Пример #1
0
    def __init__(self, tws_uri):
        EWrapper.__init__(self)
        EClientSocket.__init__(self, anyWrapper=self)

        self.tws_uri = tws_uri
        host, port, client_id = self.tws_uri.split(':')
        self._host = host
        self._port = int(port)
        self.client_id = int(client_id)

        self._next_ticker_id = 0
        self._next_request_id = 0
        self._next_order_id = None
        self.managed_accounts = None
        self.symbol_to_ticker_id = {}
        self.ticker_id_to_symbol = {}
        self.last_tick = defaultdict(dict)
        self.bars = {}
        # accounts structure: accounts[account_id][currency][value]
        self.accounts = defaultdict(
            lambda: defaultdict(lambda: defaultdict(lambda: np.NaN)))
        self.accounts_download_complete = False
        self.positions = {}
        self.portfolio = {}
        self.open_orders = {}
        self.order_statuses = {}
        self.executions = defaultdict(OrderedDict)
        self.commissions = defaultdict(OrderedDict)
        self._execution_to_order_id = {}
        self.time_skew = None
        self.unrecoverable_error = False

        self.connect()
Пример #2
0
    def __init__(self, name=None, call_msg=True, host=None, port=None, client_id=None):
        self.name = name
        self.host = host
        self.port = port
        self.client_id = client_id
        self.ref_nums = [0]
        self.wrapper = SyncWrapper()
        self.connection = EClientSocket(self.wrapper)
        self.account = self.wrapper.account
        self.contracts = self.wrapper.contracts
        self.executions_ = self.wrapper.executions
        self.order_messages = self.wrapper.order_messages

        if self.host is None:
            self.host = 'localhost'
        if self.port is None:
            self.port = 7496
        if call_msg is False:
            self.wrapper.suppress = True
        if self.client_id is None:
            self.client_id = 0

        # listen to execution
        #self.wrapper.register(self.method, events='execution')
        self.__connect__ = self.connection.eConnect(self.host, self.port, self.client_id)
        self.__gen_order_id__(1)
        sleep(.2)
Пример #3
0
 def __init__(self, eventEngine, gatewayName='IB'):
     """Constructor"""
     super(IbGateway, self).__init__(eventEngine, gatewayName)
     
     self.host = EMPTY_STRING        # 连接地址
     self.port = EMPTY_INT           # 连接端口
     self.clientId = EMPTY_INT       # 用户编号
     
     self.tickerId = 0               # 订阅行情时的代码编号    
     self.tickDict = {}              # tick快照字典,key为tickerId,value为VtTickData对象
     self.tickProductDict = {}       # tick对应的产品类型字典,key为tickerId,value为产品类型
     
     self.orderId  = 0               # 订单编号
     self.orderDict = {}             # 报单字典,key为orderId,value为VtOrderData对象
     
     self.accountDict = {}           # 账户字典
     
     self.contractDict = {}          # 合约字典
     
     self.subscribeReqDict = {}      # 用来保存订阅请求的字典 
     
     self.connected = False          # 连接状态
     
     self.wrapper = IbWrapper(self)                  # 回调接口
     self.connection = EClientSocket(self.wrapper)   # 主动接口
Пример #4
0
 def __init__(self, parameters):
     # Variable initialization
     #self.orders = orders.OrderBook()
     #self.price_log = data.PriceLog()
     #self.parameters = parameters
     
     self.connection = EClientSocket(self)
     self.connection.eConnect('localhost', 7496, 0) # host, port, clientId
     
     tick_id = 1
     symbol = "SLV"
     contract = self.makeContract(symbol)
     self.connection.reqMktData(tick_id, contract, [], False)
Пример #5
0
    def __init__(self, tws_uri, order_update_callback):
        EWrapper.__init__(self)
        EClientSocket.__init__(self, anyWrapper=self)

        self.tws_uri = tws_uri
        host, port, client_id = self.tws_uri.split(':')
        self._order_update_callback = order_update_callback

        self._next_ticker_id = 0
        self._next_order_id = None
        self.managed_accounts = None
        self.ticker_id_to_symbol = {}
        self.last_tick = defaultdict(dict)
        self.realtime_bars = {}
        self.accounts = {}
        self.accounts_download_complete = False
        self.positions = {}
        self.portfolio = {}
        self.orders = {}
        self.time_skew = None

        log.info("Connecting: {}:{}:{}".format(host, int(port),
                                               int(client_id)))
        self.eConnect(host, int(port), int(client_id))
        while self.notConnected():
            sleep(0.1)

        self._download_account_details()
        log.info("Managed accounts: {}".format(self.managed_accounts))

        self.reqCurrentTime()
        self.reqIds(1)

        while self.time_skew is None or self._next_order_id is None:
            sleep(0.1)

        log.info("Local-Broker Time Skew: {}".format(self.time_skew))
Пример #6
0
    def __init__(self, host, port, strategies, instruments, logger):

        self.msgs = queue.Queue()
        self.book_builder = BookBuilder()

        # strategies
        self.instruments = instruments
        self.contracts = dict()
        self.strategies = []
        for strategy in strategies:
            strat = Recoil2(strategy['watch_threshold'],
                            strategy['watch_duration'],
                            strategy['slowdown_threshold'],
                            strategy['slowdown_duration'])
            self.strategies.append(strat)

        # operations
        self.host = host
        self.port = port
        self.connection = EClientSocket(Connector(self.instruments, self.msgs))
        self.next_id = None
        self.log = logger
Пример #7
0
class IBProvider(BaseProvider):
    def __init__(self):
        basicConfig()
        # These two variables are initialized in Connect method
        self._connection = None
        self._wrapper = None
        self._request_id = 0

    def connect(self):
        self._wrapper = ReferenceWrapper()
        self._connection = EClientSocket(self._wrapper)
        self._connection.eConnect(IB_HOST, IB_PORT, IB_PROVIDER_CLIENT_ID)

    def disconnect(self):
        if self._connection.isConnected():
            self._connection.eDisconnect()

    def _make_contract(self, symbol):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART'
        contract.m_primaryExch = 'SMART'
        contract.m_currency = 'USD'
        contract.m_localSymbol = symbol
        return contract

    def _get_next_request_id(self):
        self._request_id += 1
        return self._request_id

    def get_market_depth_L1(self, symbol):
        contract = self._make_contract(symbol)
        request_id = self._get_next_request_id()
        self._connection.reqMktData(request_id, contract, '', True)
        while not self._wrapper.isExecutionRequestFinished(request_id):
            err = self._wrapper.getError(request_id)
            if err is not None:
                raise Exception(err)
            very_short_sleep()
        return self._wrapper.getMarketDepthL1(request_id)
Пример #8
0
import time
from datetime import datetime
from IBWrapper import IBWrapper, contract
from ib.ext.EClientSocket import EClientSocket
from ib.ext.ScannerSubscription import ScannerSubscription


if __name__=="__main__":
    callback = IBWrapper()          # Instantiate IBWrapper 
    tws = EClientSocket(callback)   # Instantiate EClientSocket
    host = ""
    port = 7496
    clientId = 5000
    tws.eConnect(host, port, clientId)     # Connect to TWS
    tws.setServerLogLevel(5)
    accountName = "DU123456"        # Change to your own account
    create = contract()             # Instantiate contract class
    
    # Initiate attributes to receive data. At some point we need a separate class for this
    callback.initiate_variables()
    
    # Account and Portfolio ##############################################################
    # reqAccountUpdates   --->   updateAccountTime      self.update_AccountTime
    #                            updateAccountValue     self.update_AccountValue
    #                            updatePortfolio        self.update_Portfolio
    # accountDownloadEnd                                self.accountDownloadEnd_flag
    # reqAccountSummary   --->   accountSummary         self.account_Summary
    # cancelAccountSummary
    # accountSummaryEnd                                 self.account_SummaryEnd_flag
    # reqPositions        --->   position               self.update_Position
    # cancelPositions
Пример #9
0
import csv
import timeit
import random
import pandas as pd
from datetime import datetime, timedelta
import threading
from threading import Thread
import multiprocessing
from multiprocessing import Process
# from flask import Flask, url_for, request, render_template, redirect
from apscheduler.schedulers.background import BackgroundScheduler

###############################################

callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7496
clientId = 100
create = contract()
callback.initiate_variables()


def conn():
    status = tws.isConnected()
    if status == False:
        print(
            "######### $$$$$$$$$$$$$$$$$$ RECONNECTING TWS SESSION   $$$$$$$$$$$$$$$$$$############"
        )
        tws.eConnect(host, port, clientId)
        # print("######### $$$$$$$$$$$$$$$$$$$ TWS CONNECTED   $$$$$$$$$$$$$$$$$$############")
Пример #10
0
import pandas as pd
from datetime import datetime, timedelta
import threading
from threading import Thread
import multiprocessing
from multiprocessing import Process
# from flask import Flask, url_for, request, render_template, redirect
from apscheduler.schedulers.background import BackgroundScheduler

sched = BackgroundScheduler()
import openpyxl

###############################################

callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7496
clientId = 100
create = contract()
callback.initiate_variables()

acc = "DU228380"

# hl_curr_ny = 'YES'

df_common_inputs = pd.read_excel('C:/database/FX_DAILY/FOREX_settings.xlsx',
                                 'common_inputs')
df_london = pd.read_excel('C:/database/FX_DAILY/FOREX_settings.xlsx',
                          'LONDON_TRADES')
df_o_val = pd.read_excel('C:/database/FX_DAILY/FOREX_settings.xlsx',
Пример #11
0
import pandas as pd
import time
from IBWrapper import IBWrapper, contract
from ib.ext.EClientSocket import EClientSocket

from ib.ext.ScannerSubscription import ScannerSubscription
import re


stocks=[
'700'
]
if __name__ == '__main__':
    for x in stocks:
        callback = IBWrapper()
        tws = EClientSocket(callback)
        host = "127.0.0.1"
        port = 7496
        clientId = 999
        tws.eConnect(host, port, clientId)
        create = contract()
        callback.initiate_variables()
        contract_Details = create.create_contract(x, 'STK', 'SEHK', 'HKD')
        tickerId = 8001

        tws.reqFundamentalData(tickerId,
                          contract_Details,
                          "RESC"
                          )
        time.sleep(5)
Пример #12
0
 def __init__(self, wrapper):
     EClientSocket.__init__(self, wrapper)
Пример #13
0
class ReferenceApp:
    def __init__(self, host='localhost', port=7496, clientId=0):
        self.host = host
        self.port = port
        self.clientId = clientId
        self.wrapper = ReferenceWrapper()
        self.connection = EClientSocket(self.wrapper)

    @ref
    def eConnect(self):
        self.connection.eConnect(self.host, self.port, self.clientId)

    @ref
    def reqAccountUpdates(self):
        self.connection.reqAccountUpdates(1, '')

    @ref
    def reqOpenOrders(self):
        self.connection.reqOpenOrders()

    @ref
    def reqExecutions(self):
        filt = ExecutionFilter()
        self.connection.reqExecutions(0, filt)

    @ref
    def reqIds(self):
        self.connection.reqIds(10)

    @ref
    def reqNewsBulletins(self):
        self.connection.reqNewsBulletins(1)

    @ref
    def cancelNewsBulletins(self):
        self.connection.cancelNewsBulletins()

    @ref
    def setServerLogLevel(self):
        self.connection.setServerLogLevel(3)

    @ref
    def reqAutoOpenOrders(self):
        self.connection.reqAutoOpenOrders(1)

    @ref
    def reqAllOpenOrders(self):
        self.connection.reqAllOpenOrders()

    @ref
    def reqManagedAccts(self):
        self.connection.reqManagedAccts()

    @ref
    def requestFA(self):
        self.connection.requestFA(1)

    @ref
    def reqMktData(self):
        contract = Contract() #
        contract.m_symbol = 'AUD'
        contract.m_currency = 'USD'
        contract.m_secType = 'CASH'
        contract.m_exchange = 'IDEALPRO'
        self.connection.reqMktData(1, contract, '', False)

    @ref
    def reqHistoricalData(self):
        contract = Contract()
        contract.m_symbol = 'QQQQ'
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART'
        endtime = strftime('%Y%m%d %H:%M:%S')
        self.connection.reqHistoricalData(
            tickerId=1,
            contract=contract,
            endDateTime=endtime,
            durationStr='1 D',
            barSizeSetting='1 min',
            whatToShow='TRADES',
            useRTH=0,
            formatDate=1)

    @ref
    def eDisconnect(self):
        sleep(5)
        self.connection.eDisconnect()
Пример #14
0
 def receiveFA(cls, faDataType, xml):
     """ generated source for method receiveFA """
     return cls.FINANCIAL_ADVISOR + " " + EClientSocket.faMsgTypeName(
         faDataType) + " " + xml
Пример #15
0
	long_SMA = data['close'].rolling(long_length).mean()

	return short_SMA.iloc[-1], long_SMA.iloc[-1]

def check_existing_pos():
	# 0 is no position, 1 means we have existing position
	# we need to write an algo to send request to IB to check
	# whether we have existing position
	# you will need a proper identifier for your position.
	pos = 1 
	return pos

# connect
accountName = "DU000000"
callback = IBWrapper()             # Instantiate IBWrapper. callback 
tws = EClientSocket(callback)      # Instantiate EClientSocket and return data to callback
host = ""
port = 4002
clientId = 4002
order_id = 1001

tws.eConnect(host, port, clientId) # Connect to TWS

# Let's work with APPLE stock.
create = contract()
callback.initiate_variables()
contract_Details = create.create_contract('AAPL', 'STK', 'SMART', 'USD')

'''
This should be the beginning of the while loop
This is an infinite loop.
Пример #16
0
import csv
import timeit
import random
import pandas as pd
from datetime import datetime, timedelta
import threading
from threading import Thread
import multiprocessing
from multiprocessing import Process
# from flask import Flask, url_for, request, render_template, redirect
from apscheduler.schedulers.background import BackgroundScheduler
sched = BackgroundScheduler()
import openpyxl
###############################################
callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7496
clientId = 100
create = contract()
callback.initiate_variables()
acc = "DU228380"
commonwealth_curr = ['GBP', 'AUD', 'NZD', 'EUR']


def conn():
    status = tws.isConnected()
    if status == False:
        # print("######### $$$$$$$$$$$$$$$$$$ RECONNECTING TWS SESSION   $$$$$$$$$$$$$$$$$$############")
        tws.eConnect(host, port, clientId)
        # print("######### $$$$$$$$$$$$$$$$$$$ TWS CONNECTED   $$$$$$$$$$$$$$$$$$############")
Пример #17
0
class IBMarketData(object):
    def __init__(self, host='127.0.0.1', port=7496, clientId=0):
        self.host = host
        self.port = port
        self.clientId = clientId
        self.wrapper = ReferenceWrapper()
        self.connection = EClientSocket(self.wrapper)
        self.logger = make_logger(self)
        if not self.logger.handlers:
            self.logger.addHandler(logging.StreamHandler())

    def market_data_get(self, symbol, data_type):
        self.connection.reqMktData(1, )
        contract = Contract()
        contract.m_symbol = 'QQQ'
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART'
        self.connection.reqMktData(1, contract, '', False)

    def market_data_register(self, symbol, data_type, handler, handler_ctx):
        pass

    def market_data_unregister(self, symbol, data_type):
        pass

    def _make_stock_contract(self, symbol):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART/ISLAND'
        return contract

    def _generate_ticker_id(self):
        global DataRequests

        while True:
            id = random.randint(1, 9999)

            if id not in DataRequests.keys():
                return id

    def historical_bars_get(self, symbol, bar_type, start, end=None):
        self.logger.error('symbol={}, bar_type={}, start={}, end={}'.format(
            symbol, bar_type, start, end))

        id = self._generate_ticker_id()

        global DataRequests
        data_request = DataRequest(BAR_TYPE_TO_REQ[bar_type])
        DataRequests[id] = data_request

        if end is None:
            end = start

        if bar_type == BAR_MIN:
            end += timedelta(minutes=1)
        elif bar_type == BAR_DAY:
            start = datetime(year=start.year, month=start.month, day=start.day)
            end = datetime(year=end.year, month=end.month, day=end.day)
            end += timedelta(days=1)
        else:
            raise ValueError()

        if start.tzname() == None:
            start = TZ_NY.localize(start)
            end = TZ_NY.localize(end)

        start = start.astimezone(TZ_LOCAL)
        end = end.astimezone(TZ_LOCAL)

        assert end >= start

        end_start_delta = end - start

        duration = '{days} D'.format(days=end_start_delta.days + 1)
        if bar_type == BAR_DAY and end_start_delta.days + 1 > 365:
            duration = '{years} Y'.format(years=(end_start_delta.days / 365) +
                                          1)

        endtime = end.strftime('%Y%m%d %H:%M:%S')

        args = dict(
            tickerId=id,
            contract=self._make_stock_contract(symbol),
            endDateTime=endtime,
            durationStr=duration,
            barSizeSetting=bar_type,
            whatToShow='TRADES',
            useRTH=0,
            formatDate=2  #linux time
        )

        self.logger.error(
            'reqHistoricalData(id:{} | type:"{}" | duration:"{}" | end:"{}"'.
            format(id, bar_type, duration, endtime))

        self.connection.reqHistoricalData(**args)

        data_request.wait()
        start = start.astimezone(TZ_NY)
        end = end.astimezone(TZ_NY)
        bars = [b for b in data_request.bars if start <= b.get_time() <= end]

        DataRequests.pop(id)

        return bars

    def bars_register(self, symbol, handler, handler_ctx):
        pass

    def bars_unregister(self, symbol):
        pass

    def connect(self):
        self.connection.eConnect(self.host, self.port, self.clientId)

    def disconnect(self):
        self.connection.eDisconnect()
        time.sleep(0.15)
Пример #18
0
class IBClient(object):
    fields = {'trades': 'TRADES',
              'midpoint': 'MIDPOINT',
              'bid': 'BID',
              'ask': 'ASK',
              'bid_ask': 'BID_ASK',
              'hist_vol': 'HISTORICAL_VOLATILITY',
              'imp_vol': 'OPTION_IMPLIED_VOLATILITY'}

    def __init__(self, name=None, call_msg=True, host=None, port=None, client_id=None):
        self.name = name
        self.host = host
        self.port = port
        self.client_id = client_id
        self.ref_nums = [0]
        self.wrapper = SyncWrapper()
        self.connection = EClientSocket(self.wrapper)
        self.account = self.wrapper.account
        self.contracts = self.wrapper.contracts
        self.executions_ = self.wrapper.executions
        self.order_messages = self.wrapper.order_messages

        if self.host is None:
            self.host = 'localhost'
        if self.port is None:
            self.port = 7496
        if call_msg is False:
            self.wrapper.suppress = True
        if self.client_id is None:
            self.client_id = 0

        # listen to execution
        #self.wrapper.register(self.method, events='execution')
        self.__connect__ = self.connection.eConnect(self.host, self.port, self.client_id)
        self.__gen_order_id__(1)
        sleep(.2)


    def request_reference_id(self, integer=False):
        if not integer:
            ref_id = uuid.uuid4().hex
            if ref_id in self.ref_nums:
                return self.request_reference()
            else:
                self.ref_nums.append(ref_id)
                return ref_id
        else:
            ref_id = '{0:09d}'.format(np.random.randint(0, 999999999))
            if ref_id > max([x for x in self.ref_nums if type(x) is int]):
                return int(ref_id)
            else:
                return self.request_reference(integer=True)

    def __gen_order_id__(self, num):
        self.connection.reqIds(num)
        return self.wrapper.order_id


    def method(self, sender, event, msg=None):
        print "[{0}] got event {1} with message {2}".format(self.name, event, msg)

    def __track_orders__(self):
        self.connection.reqAutoOpenOrders(1)

    def managed_accounts(self):
        if self.account.child_accounts:
            return self.account.child_accounts
        else:
            self.connection.reqManagedAccts()
            sleep(1)
            if self.account.child_accounts:
                return self.account.child_accounts
            return ['REQUEST FAILED']

    def account_updates(self, acct):
        #get a unique id
        reference = self.request_reference_id()

        #append a new packet container to account
        self.account.append_request(reference, AccountPacket(acct), PortfolioPacket(acct))
        self.wrapper.ref_id = reference
        self.connection.reqAccountUpdates(1, acct)
        sleep(1)
        return reference

    def place_order(self, contract, order):
        self.wrapper.order_id += 100
        ref = self.wrapper.order_id
        self.connection.placeOrder(ref, contract, order)
        sleep(.2)
        return ref

    def cancel_order(self, id):
        self.connection.cancelOrder(id)

    def get_executions(self, efilter=None):
        if not efilter:
            efilter = ExecutionFilter()
        ref = self.request_reference_id(integer=True)
        self.connection.reqExecutions(reqId=ref, filter=efilter)
        sleep(3)  # Todo: This is a ridiculous bottleneck
        return ref

    def get_contract(self, contract):
        ref = self.request_reference_id(integer=True)
        self.connection.reqContractDetails(ref, contract)
        sleep(1)
        return ref

    def portfolio(self, account):
        ref = self.account_updates(account)
        return self.account[ref]['portfolio'].messages

    def account_details(self, account):
        ref = self.account_updates(account)
        return self.account[ref]['account'].messages

    def executions(self, efilter=None):
        ref = self.get_executions(efilter)
        return self.executions_[ref]

    def order_status(self, order_id):
        sleep(.2)
        return [msg for msg in self.order_messages if msg['orderId'] == order_id]

    def disconnect(self):
        self.connection.eDisconnect()
Пример #19
0
# TODO: Error handling for connecting, see https://bit.ly/3dkTqj5
# TODO: get fundamental data, see https://bit.ly/3nH5rUF
# import pandas as pd
import time

from ib.ext.EClientSocket import EClientSocket
from IBWrapper import IBWrapper, contract

# from ib.ext.ScannerSubscription import ScannerSubscription
# import re

stocks = ['5']

for x in stocks:
    callback = IBWrapper()
    tws = EClientSocket(callback)
    host = "127.0.0.1"
    port = 7496
    clientId = 25
    tws.eConnect(host, port, clientId)
    create = contract()
    callback.initiate_variables()
    contract_Details = create.create_contract(x, 'STK', 'SEHK', 'HKD')
    tickerId = 8001

    tws.reqFundamentalData(tickerId, contract_Details, "ReportSnapshot")
    time.sleep(5)

    print(callback.fundamental_Data_data)
    print(callback.fundamental_Data_data.find("AATCA"))
    print(callback.fundamental_Data_data.find("ACFSHR"))
Пример #20
0
import pandas as pd
import numpy as np
import time
from datetime import datetime
from ib.ext.EWrapperMsgGenerator import updateAccountTime
from ib.ext.Contract import Contract
from ib.ext.EClientSocket import EClientSocket
from ib.ext.ScannerSubscription import ScannerSubscription
from ib.opt import Connection, message

accountName = 'DU958186'
callback = EWrapperMsgGenerator
tws=EClientSocket(callback)
host=''
port=7497
clientId=100

tws.eConnect(host,port,clientId)

Пример #21
0
numId = 0

if __name__ == '__main__':
    cid = 10        # clientId: can be any number. It will show on IBGateway as folder/different user 
    orderId = 1     # orderId
    accountId = 'DU594416'
    symbolId = '???'       # contract identifier id or asset id?
    port = 4002
    
    # =============================================================================
    # ESTABLISH CONNECTION
    # =============================================================================
    # instantiate data in IBWrapper, still need to use this as EWrapper 
    # is an abstract object
    data = IBWrapper()
    tws = EClientSocket(data)
    tws.eConnect('localhost' , port, cid) 
    
    # Initiate attributes to receive data (REQUIRED) 
    data.initiate_variables()
    # =============================================================================
    # =============================================================================
    
    '''
    # =============================================================================     
    # UPDATE YOUR PORTFOLIO WITH 2 ALTERNATIVES FUNCTION
    # =============================================================================
    # 1. update account:    reqAccountUpdates(subscribe, accountId)
    #     subscribe:    0 - update Acc Time, 1 - update Acc Val, 2 - update Portfolio
    tws.reqAccountUpdates(2, accountId)
    # time (1 sec) is REQUIRED to get data, otherwise empty list
Пример #22
0
 def __init__(self, wrapper):
     ## Set up with a wrapper inside
     EClientSocket.__init__(self, wrapper)
Пример #23
0
from IBWrapper import IBWrapper, contract
from ib.ext.EClientSocket import EClientSocket
import time
callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7497
clientId = 100
tws.eConnect(host, port, clientId)

time.sleep(3)
#request ID 1
tws.reqIds(1)
order_id = callback.next_ValidId + 1

create = contract()
callback.initiate_variables()
time.sleep(3)
df = [
    "AAPL", "STK", "SMART", "USD", '', '', '20170616', '50', "DU228380", "LMT",
    "1", "SELL", "142.26"
]
contract_info = create.create_contract(df[0], df[1], df[2],
                                       df[3])  #,df[4],df[5],df[6],df[7])
order_info = create.create_order(df[8], df[9], df[10], df[11], df[12], True)

order_info2 = create.create_order(df[8], df[9], df[10], df[11], df[12],
                                  "143.26", True)

tws.placeOrder(order_id, contract_info, order_info)
Пример #24
0
 def __init__(self, host='localhost', port=7496, clientId=0):
     self.host = host
     self.port = port
     self.clientId = clientId
     self.wrapper = ReferenceWrapper()
     self.connection = EClientSocket(self.wrapper)
Пример #25
0
class Bot(object):

    def __init__(self, host, port, strategies, instruments, logger):

        self.msgs = queue.Queue()
        self.book_builder = BookBuilder()

        # strategies
        self.instruments = instruments
        self.contracts = dict()
        self.strategies = []
        for strategy in strategies:
            strat = Recoil2(strategy['watch_threshold'],
                            strategy['watch_duration'],
                            strategy['slowdown_threshold'],
                            strategy['slowdown_duration'])
            self.strategies.append(strat)

        # operations
        self.host = host
        self.port = port
        self.connection = EClientSocket(Connector(self.instruments, self.msgs))
        self.next_id = None
        self.log = logger

    def connect(self):
        template = 'Attempting to connect host: {} port: {}...'
        self.log.operation(template.format(self.host, self.port))
        self.connection.eConnect(self.host, self.port, 0)
        self.log.operation('Connected.')

    def disconnect(self):
        self.log.operation('Disconnecting...')
        self.connection.eDisconnect()
        self.log.operation('Disconnected.')

    def request_data(self):
        for ticker_id, instrument in self.instruments.items():
            contract = Contract()
            contract.m_symbol = instrument['symbol']
            contract.m_currency = instrument['currency']
            contract.m_secType = instrument['secType']
            contract.m_exchange = instrument['exchange']
            self.contracts[instrument['symbol']] = contract
            self.connection.reqMktData(ticker_id, contract, '', False)

    def run(self):
        while True:
            msg = self.msgs.get()
            self.log.raw(msg)

            if msg['type'] == 'nextValidId':
                self.log.order({'msg': 'new order ID', 'orderId': msg['orderId']})
                self.next_id = msg['orderId']
                continue

            tick = self.book_builder.process_raw_tick(msg)

            if not tick:
                continue

            self.log.data(tick)

            for strategy in self.strategies:
                signal = strategy.handle_tick(tick)

                if not signal:
                    continue

                self.log.order(signal)
                order = strategy.place_order(signal)

                if not order:
                    continue

                c = self.contracts[signal['symbol']]
                self.log.order({'symbol': signal['symbol'],
                                'qty': order.m_totalQuantity,
                                'type': order.m_orderType,
                                'goodTill': order.m_goodTillDate,
                                'px': order.m_lmtPrice,
                                'action': order.m_action})
                self.connection.placeOrder(id=self.next_id, contract=c,
                                           order=order)
                self.next_id += 1
Пример #26
0
import time
from datetime import datetime
from IBWrapper import IBWrapper, contract
from ib.ext.EClientSocket import EClientSocket
from ib.ext.ScannerSubscription import ScannerSubscription
from __future__ import print_function

if __name__ == "__main__":
    callback = IBWrapper()  # Instantiate IBWrapper
    tws = EClientSocket(callback)  # Instantiate EClientSocket
    host = ""
    port = 7496
    clientId = 5000
    tws.eConnect(host, port, clientId)  # Connect to TWS
    tws.setServerLogLevel(5)
    accountName = "DU123456"  # Change to your own account
    create = contract()  # Instantiate contract class

    # Initiate attributes to receive data. At some point we need a separate class for this
    callback.initiate_variables()

    # Account and Portfolio ##############################################################
    # reqAccountUpdates   --->   updateAccountTime      self.update_AccountTime
    #                            updateAccountValue     self.update_AccountValue
    #                            updatePortfolio        self.update_Portfolio
    # accountDownloadEnd                                self.accountDownloadEnd_flag
    # reqAccountSummary   --->   accountSummary         self.account_Summary
    # cancelAccountSummary
    # accountSummaryEnd                                 self.account_SummaryEnd_flag
    # reqPositions        --->   position               self.update_Position
    # cancelPositions
Пример #27
0
class IB:
    """
    Interface to Interactive Brokers.
    """

    # Definition of the tick data "field" value.
    tick_type = {
        0: "BID_SIZE",
        1: "BID_PRICE",
        2: "ASK_PRICE",
        3: "ASK_SIZE",
        4: "LAST_PRICE",
        5: "LAST_SIZE",
        6: "HIGH",
        7: "LOW",
        8: "VOLUME",
        9: "CLOSE_PRICE",
        10: "BID_OPTION_COMPUTATION",
        11: "ASK_OPTION_COMPUTATION",
        12: "LAST_OPTION_COMPUTATION",
        13: "MODEL_OPTION_COMPUTATION",
        14: "OPEN_PRICE",
        15: "LOW_13_WEEK",
        16: "HIGH_13_WEEK",
        17: "LOW_26_WEEK",
        18: "HIGH_26_WEEK",
        19: "LOW_52_WEEK",
        20: "HIGH_52_WEEK",
        21: "AVG_VOLUME",
        22: "OPEN_INTEREST",
        23: "OPTION_HISTORICAL_VOL",
        24: "OPTION_IMPLIED_VOL",
        27: "OPTION_CALL_OPEN_INTEREST",
        28: "OPTION_PUT_OPEN_INTEREST",
        29: "OPTION_CALL_VOLUME"
    }

    def __init__(self, account_name: str, host: str, port: int,
                 client_id: int):
        self.account_name = account_name
        # Instantiate IBWrapper callback.
        self.callback = IBWrapper()
        # Instantiate EClientSocket and return data to callback
        self.tws = EClientSocket(self.callback)
        # Connect to TWS.
        self.tws.eConnect(host, port, client_id)

        # Instantiate contract class.
        self.create = contract()
        self.callback.initiate_variables()

    def request_account_data(self):
        """
        Requests the relevant account data.
        http://interactivebrokers.github.io/tws-api/account_updates.html
        http://interactivebrokers.github.io/tws-api/classIBApi_1_1EClient.html#aea1b0d9b6b85a4e0b18caf13a51f837f
        """
        self.callback.update_AccountValue = []
        self.callback.update_Portfolio = []
        self.callback.update_AccountTime = None
        print(f'Requesting account data.')
        self.tws.reqAccountUpdates(subscribe=True, acctCode=self.account_name)
        # Retrieve the data from the callback when it arrives.
        while True:
            # Don't check for portfolio, as it may be empty to begin with.
            if all([
                    len(self.callback.update_AccountValue) > 0,
                    self.callback.update_AccountTime
            ]):
                account_data = pd.DataFrame(
                    self.callback.update_AccountValue,
                    columns=['key', 'value', 'currency', 'accountName'])
                portfolio = pd.DataFrame(
                    self.callback.update_Portfolio,
                    columns=[
                        'Contract ID', 'Currency', 'Expiry', 'Include Expired',
                        'Local Symbol', 'Multiplier', 'Primary Exchange',
                        'Right', 'Security Type', 'Strike', 'Symbol',
                        'Trading Class', 'Position', 'Market Price',
                        'Market Value', 'Average Cost', 'Unrealised PnL',
                        'Realised PnL', 'Account Name'
                    ])
                account_time = self.callback.update_AccountTime
                break
            print(f'Waiting for account data. ')
            time.sleep(2)
        # Unsubscribe.
        self.tws.reqAccountUpdates(subscribe=False, acctCode=self.account_name)
        self.callback.update_AccountValue = []
        self.callback.update_Portfolio = []
        self.callback.update_AccountTime = None
        return account_data, portfolio, account_time

    def request_portfolio(self):
        """
        Requests the portfolio.
        http://interactivebrokers.github.io/tws-api/account_updates.html
        http://interactivebrokers.github.io/tws-api/interfaceIBApi_1_1EWrapper.html#a790ccbe25033df73996f36a79ce2ce5a
        """
        self.callback.update_AccountValue = []
        print(f'Requesting portfolio data.')
        self.tws.reqAccountUpdates(subscribe=True, acctCode=self.account_name)
        # Retrieve the data from the callback when it arrives.
        while True:
            if len(self.callback.update_AccountValue) > 0:
                data = pd.DataFrame(
                    self.callback.update_AccountValue,
                    columns=['key', 'value', 'currency', 'accountName'])
                break
            print(f'Waiting for portfolio data.')
            time.sleep(2)
        # Unsubscribe.
        self.tws.reqAccountUpdates(subscribe=False, acctCode=self.account_name)
        self.callback.update_AccountValue = []
        return data

    def request_tick_data(self, ticker, max_num_tries=10):
        """
        Requests current tick data for the given ticker.
        """
        # Create the contract to request tick data for.
        contract_info = self.create.create_contract(ticker, 'STK', 'SMART',
                                                    'USD')
        tickerId = 1004
        self.callback.tick_Price = []

        # Request the data.
        # Take a snapshot, so we don't continue to get data.
        self.tws.reqMktData(tickerId=tickerId,
                            contract=contract_info,
                            genericTickList="",
                            snapshot=True)

        # Retrieve the data from the callback when it arrives.
        received_data = False
        num_tries = 0
        while num_tries < max_num_tries:
            if len(self.callback.tick_Price) > 0:
                data = pd.DataFrame(
                    self.callback.tick_Price,
                    columns=['tickerId', 'field', 'price', 'canAutoExecute'])
                data["Type"] = data["field"].map(IB.tick_type)
                print(data)
                if 'LAST_PRICE' in data['Type'].values:
                    # We have the information we need.
                    break
                if 'CLOSE_PRICE' in data['Type'].values:
                    if not received_data:
                        # We have the close price. Wait a little longer to see if we get the last price.
                        received_data = True
                        time.sleep(2)
                        continue
                    break
            print(
                f'Waiting for tick data for ticker {ticker}, with ID {tickerId}, after try {num_tries} of {max_num_tries}.'
            )
            num_tries += 1
            time.sleep(2)

        self.tws.cancelMktData(tickerId)

        # Attach the type of each row, based on the field.
        # data["Type"] = data["field"].map(IB.tick_type)

        # Reset the tick_Price data.
        self.callback.tick_Price = []

        if not received_data:
            data = None

        return data

    def request_tick_data_repeat(self, ticker, max_num_tries):
        """
        Wrapper around request_tick_data, that makes a given number of attempts.
        On each attempt, a new connection is established.
        """
        num_tries = 0
        while num_tries < max_num_tries:
            data = self.request_tick_data(ticker)
            if data is not None:
                break
            num_tries += 1
        return data

    def request_historical_data(self,
                                ticker: str,
                                num_days: int,
                                last_date: datetime = None):
        """
        https://interactivebrokers.github.io/tws-api/historical_bars.html
        http://interactivebrokers.github.io/tws-api/classIBApi_1_1EClient.html#aad87a15294377608e59aec1d87420594
        """
        # Create the contract to request tick data for.
        contract_info = self.create.create_contract(ticker, 'STK', 'SMART',
                                                    'USD')
        tickerId = 1004
        self.callback.historical_Data = []

        # Example: To get 3 days ending on 1/7/2013, use the last second of 1/7/2013 as the endDateTime,
        # and 3D as the durationStr.

        data_endtime = '' if last_date is None else last_date.strftime(
            "%Y%m%d %H:%M:%S")

        # Request the data.
        # reqHistoricalData(self, tickerId, contract, endDateTime, durationStr, barSizeSetting, whatToShow, useRTH, formatDate):
        self.tws.reqHistoricalData(
            tickerId=tickerId,
            contract=contract_info,
            endDateTime=
            data_endtime,  # The request's end date and time (the empty string indicates current present moment).
            durationStr=f"{num_days} D",
            barSizeSetting="1 day",
            whatToShow=
            "TRADES",  # Hopefully this will be a bar summarising the trades...
            useRTH=
            1,  # "Regular trading hours". For some reason, 1 chops of the most recent day.
            formatDate=
            1,  # dates applying to bars returned in the format: yyyymmdd{space}{space}hh:mm:dd
            #keepUpToDate=False
        )

        # Retrieve the data from the callback when it arrives.
        while True:
            # I think the last row has "finished" in the "date" column, to indicate all data is retrieved.
            if len(
                    self.callback.historical_Data
            ) > 0 and 'finished' in self.callback.historical_Data[-1][1]:
                print(self.callback.historical_Data)
                data = pd.DataFrame(
                    self.callback.
                    historical_Data[:-1],  # Removed "finished" row. 
                    columns=[
                        "reqId", "date", "open", "high", "low", "close",
                        "volume", "count", "WAP", "hasGaps"
                    ])
                break
            print(f'Waiting for historical data with ID {tickerId}.')
            time.sleep(2)

        # Reset the historical_Data data.
        self.callback.historical_Data = []

        data['date'] = pd.to_datetime(data['date'])
        data.set_index('date')
        # print(data.to_string())

        return data[[
            'date', 'open', 'high', 'low', 'close', 'volume', 'count'
        ]]

    def close(self):
        self.tws.eDisconnect()
Пример #28
0
 def receiveFA(cls, faDataType, xml):
     return cls.FINANCIAL_ADVISOR + " " + EClientSocket.faMsgTypeName(faDataType) + " " + xml
Пример #29
0
 def receiveFA(cls, faDataType, xml):
     """ generated source for method receiveFA """
     return cls.FINANCIAL_ADVISOR + " " + EClientSocket.faMsgTypeName(faDataType) + " " + xml
Пример #30
0
class Wrapper(EWrapper):
    orders = None
    order_ids = [0]
    parameters = None
    connection = None

    _storage = None

    def __init__(self, storage):
        # Variable initialization
        #self.orders = orders.OrderBook()
        #self.price_log = data.PriceLog()
        #self.parameters = parameters

        self._storage = storage
        
        self.connection = EClientSocket(self)
        self.connection.eConnect('localhost', 7496, 0) # host, port, clientId
        
        tick_id = 1
        symbol = "SLV"
        contract = self.makeContract(symbol)
        self.connection.reqMktData(tick_id, contract, [], False)

    def makeContract(self, symbol):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART'
        contract.m_primaryExch = 'SMART'
        contract.m_currency = 'USD'
        contract.m_localSymbol = symbol
        return contract

    def tickPrice(self, tickerId, field, price, canAutoExecute):
        # 1 = bid
        # 2 = ask
        # 4 = last
        # 6 = high
        # 7 = low
        # 9 = close

        priceLog = {}

        side = ""
        if field == 2:
            self._storage.log_price("ask", price)
        elif field == 1:
            self._storage.log_price("bid", price)
        if side != "":
            print(side, price)

    def openOrder(self, orderId, contract, order, state):
        orderId = order.m_orderId
        symbol = contract.m_symbol
        qty = order.m_totalQuantity
        price = order.m_lmtPrice
        action = order.m_action
        self.orders.add(orderId, symbol, qty, price, action)
        
        order = [orderId, symbol, qty, price, action]
        print("--> Open order:{} Status:{} Warning:{}".format(order, state.m_status, state.m_warningText))
    
    def error(self, id=None, errorCode=None, errorMsg=None):
        if errorCode == 2104:
            print("--> {}".format(errorMsg))
        elif errorCode == 502:
            raise Exception(errorMsg)
        else:
            showmessage('error', vars())
    
    def nextValidId(self, orderId):
        self.order_ids.append(orderId)

    def connectionClosed(self):
        """ Something broke, connection lost. """
        print("--> Connection closed, exiting...")
        sys.exit(0)

    def connected(self):
        """ Returns True of connected to TraderWorkstation, otherwise False. """
        return self.connection.m_connected

    def tickSize(self, tickerId, field, size): pass #showmessage('tickSize', vars())
    def tickGeneric(self, tickerId, tickType, value): pass #showmessage('tickGeneric', vars()) 
    def tickString(self, tickerId, tickType, value): pass #showmessage('tickString', vars()) 
    def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, impliedFuture, holdDays, futureExpiry, dividendImpact, dividendsToExpiry): showmessage('tickEFP', vars()) 
    def tickOptionComputation(self, tickerId, field, impliedVolatility, delta): showmessage('tickOptionComputation', vars()) 
    def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeId): pass #showmessage('orderStatus', vars()) 
    def openOrderEnd(self): showmessage('openOrderEnd', vars())
    def updateAccountValue(self, key, value, currency, accountName): showmessage('updateAccountValue', vars()) 
    def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName): showmessage('updatePortfolio', vars()) 
    def updateAccountTime(self, timeStamp): showmessage('updateAccountTime', vars()) 
    def accountDownloadEnd(self, accountName): showmessage('accountDownloadEnd', vars()) 
    def contractDetails(self, contractDetails): showmessage('contractDetails', vars()) 
    def bondContractDetails(self, contractDetails): showmessage('bondContractDetails', vars()) 
    def contractDetailsEnd(self, reqId): showmessage('contractDetailsEnd', vars()) 
    def execDetails(self, orderId, contract, execution): showmessage('execDetails', vars()) 
    def execDetailsEnd(self, reqId): showmessage('execDetailsEnd', vars()) 
    def error_0(self, strval): showmessage('error_0', vars()) 
    def error_1(self, strval): showmessage('error_1', vars()) 
    def updateMktDepth(self, tickerId, position, operation, side, price, size): showmessage('updateMktDepth', vars()) 
    def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size): showmessage('updateMktDepthL2', vars()) 
    def updateNewsBulletin(self, msgId, msgType, message, origExchange): showmessage('updateNewsBulletin', vars()) 
    def managedAccounts(self, accountsList): pass #showmessage('managedAccounts', vars()) 
    def receiveFA(self, faDataType, xml): showmessage('receiveFA', vars()) 
    def historicalData(self, reqId, date, open, high, low, close, volume, count, WAP, hasGaps): showmessage('historicalData', vars()) 
    def scannerParameters(self, xml): showmessage('scannerParameters', vars()) 
    def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection): showmessage('scannerData', vars()) 
    def scannerDataEnd(self, reqId): showmessage('scannerDataEnd', vars()) 
    def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count): showmessage('realtimeBar', vars()) 
    def currentTime(self, time): showmessage('currentTime', vars()) 
    def fundamentalData(self, reqId, data): showmessage('fundamentalData', vars()) 
    def deltaNeutralValidation(self, reqId, underComp): showmessage('deltaNeutralValidation', vars()) 
    def tickSnapshotEnd(self, reqId): showmessage('tickSnapshotEnd', vars()) 
    def marketDataType(self, reqId, marketDataType): showmessage('marketDataType', vars()) 
    def commissionReport(self, commissionReport): showmessage('commissionReport', vars()) 
Пример #31
0
class IBBroker(BaseBroker):
    def __init__(self):
        basicConfig()
        # These two variables are initialized in Connect method
        self._connection = None
        self._wrapper = None
        self._request_id = 0

    def _get_next_request_id(self):
        self._request_id += 1
        return self._request_id

    def get_security(self, symbol):
        contract = IBSecurity()
        contract.Symbol = symbol
        contract.symbol_id = 0
        contract.Currency = 'USD'
        return contract

    def _get_next_valid_order_id(self):
        """
        You must assign a unique order ID to each order you place. IB's servers
        keep track of the next available order ID you can use; this function
        requests that value from IB's servers, waits until IB sends a response,
        then returns the ID.
        """
        last_time = self._wrapper._time_received_next_valid_order_id
        self._connection.reqIds(1)
        # Wait until IB sends the next valid ID
        while last_time == self._wrapper._time_received_next_valid_order_id:
            very_short_sleep()
        return self._wrapper._next_valid_order_id

    def _request_current_time(self):
        self._connection.reqCurrentTime()

    def connect(self):
        self._wrapper = ReferenceWrapper()
        self._connection = EClientSocket(self._wrapper)
        self._connection.eConnect(IB_HOST, IB_PORT, IB_CLIENT_ID)

    def disconnect(self):
        if self._connection.isConnected():
            self._connection.eDisconnect()

    def send_pre_trade(self, trade_info): # trade info is fa profile

        self._connection.requestFA(self._connection.PROFILES)
        self._connection.replaceFA(self._connection.PROFILES, trade_info)

    def send_order(self, order):
        order.__class__ = IBOrder # casting to IBOrder
        order.prepare_IB_order()
        order_id = self._get_next_valid_order_id()
        contract = self.get_security(order.Symbol)
        #order.m_transmit = True # forces IB to transmit order straight away
        self._connection.placeOrder(order_id, contract, order) # places order
        order.Status = Order.StatusChoice.Sent.value # order status is set to SENT
        order.Order_Id = order_id # sets broker specific ID
        while not self._wrapper.isOpeningOfOrdersFinished(order_id):
            err = self._wrapper.getError(order_id)
            if err is not None:
                raise Exception(err)
            very_short_sleep()
            #if(self._wrapper.isError(id)):
            #   raise Exception(self.wrapper.isError(id))

    def update_orders(self, orders):
        requestId = self._get_next_request_id()
        exf = ExecutionFilter()
        distribution = {}
        self._connection.reqExecutions(requestId, exf)  #
        while not self._wrapper.isExecutionRequestFinished(requestId):
            err = self._wrapper.getError(requestId)
            if err is not None:
                raise Exception(err)
            very_short_sleep()
        executions = self._wrapper.getExecutions(requestId)
        for order in orders:
            price = 0
            shares = 0
            if executions is not None:
                for execution in executions:
                    if execution.m_shares > 0 and execution.m_orderId == order.Order_Id and not execution.m_acctNumber.startswith('DF'):
                        price = execution.m_price
                        if order.Symbol not in distribution:
                            distribution[order.Symbol] = {}
                        if execution.m_acctNumber not in distribution[order.Symbol]:
                            distribution[order.Symbol][execution.m_acctNumber] = 0
                        distribution[order.Symbol][execution.m_acctNumber] += execution.m_shares
                        shares += execution.m_shares
                if price != 0:
                    order.setFills(price, shares)
        return distribution

    def get_account_info(self, broker_account):
        requestId = self._get_next_request_id()
        self._connection.reqAccountSummary(requestId, 'All', 'AccountType,TotalCashValue')
        while not self._wrapper.isExecutionRequestFinished(requestId):
            err = self._wrapper.getError(requestId)
            max_resp = self._wrapper.getMaxRequestFailureError()
            if err is not None:
                raise Exception(err)
            if max_resp:
                raise Exception("Maximum number of account summary requests exceeded")
            very_short_sleep()
        return self._wrapper.getAccountInfo(broker_account.ib_account)
Пример #32
0
class Wrapper(EWrapper):
    orders = None
    order_ids = [0]
    parameters = None
    connection = None

    def __init__(self, parameters):
        # Variable initialization
        #self.orders = orders.OrderBook()
        #self.price_log = data.PriceLog()
        #self.parameters = parameters
        
        self.connection = EClientSocket(self)
        self.connection.eConnect('localhost', 7496, 0) # host, port, clientId
        
        tick_id = 1
        symbol = "SLV"
        contract = self.makeContract(symbol)
        self.connection.reqMktData(tick_id, contract, [], False)

    def makeContract(self, symbol):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART'
        contract.m_primaryExch = 'SMART'
        contract.m_currency = 'USD'
        contract.m_localSymbol = symbol
        return contract

    def tickPrice(self, tickerId, field, price, canAutoExecute):
        #showmessage('tickPrice', vars())
        
        # 1 = bid
        # 2 = ask
        # 4 = last
        # 6 = high
        # 7 = low
        # 9 = close

        priceLog = {}

        side = ""
        if field == 2:
            print "a%0.2f " % price
        elif field == 1:
            print "b%0.2f " % price
        if side != "":
            print side, price

    def openOrder(self, orderId, contract, order, state):
        orderId = order.m_orderId
        symbol = contract.m_symbol
        qty = order.m_totalQuantity
        price = order.m_lmtPrice
        action = order.m_action
        self.orders.add(orderId, symbol, qty, price, action)
        
        order = [orderId, symbol, qty, price, action]
        print "--> Open order:%s Status:%s Warning:%s" % (order, state.m_status, state.m_warningText)
    
    def error(self, id=None, errorCode=None, errorMsg=None):
        if errorCode == 2104:
            print "--> %s" % errorMsg
        else:
            showmessage('error', vars())
    
    def nextValidId(self, orderId):
        self.order_ids.append(orderId)

    def connectionClosed(self):
        print "--> Connection closed, exiting..."
        sys.exit(0)

    def tickSize(self, tickerId, field, size): pass #showmessage('tickSize', vars())
    def tickGeneric(self, tickerId, tickType, value): pass #showmessage('tickGeneric', vars()) 
    def tickString(self, tickerId, tickType, value): pass #showmessage('tickString', vars()) 
    def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, impliedFuture, holdDays, futureExpiry, dividendImpact, dividendsToExpiry): showmessage('tickEFP', vars()) 
    def tickOptionComputation(self, tickerId, field, impliedVolatility, delta): showmessage('tickOptionComputation', vars()) 
    def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeId): pass #showmessage('orderStatus', vars()) 
    def openOrderEnd(self): showmessage('openOrderEnd', vars())
    def updateAccountValue(self, key, value, currency, accountName): showmessage('updateAccountValue', vars()) 
    def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName): showmessage('updatePortfolio', vars()) 
    def updateAccountTime(self, timeStamp): showmessage('updateAccountTime', vars()) 
    def accountDownloadEnd(self, accountName): showmessage('accountDownloadEnd', vars()) 
    def contractDetails(self, contractDetails): showmessage('contractDetails', vars()) 
    def bondContractDetails(self, contractDetails): showmessage('bondContractDetails', vars()) 
    def contractDetailsEnd(self, reqId): showmessage('contractDetailsEnd', vars()) 
    def execDetails(self, orderId, contract, execution): showmessage('execDetails', vars()) 
    def execDetailsEnd(self, reqId): showmessage('execDetailsEnd', vars()) 
    def error_0(self, strval): showmessage('error_0', vars()) 
    def error_1(self, strval): showmessage('error_1', vars()) 
    def updateMktDepth(self, tickerId, position, operation, side, price, size): showmessage('updateMktDepth', vars()) 
    def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size): showmessage('updateMktDepthL2', vars()) 
    def updateNewsBulletin(self, msgId, msgType, message, origExchange): showmessage('updateNewsBulletin', vars()) 
    def managedAccounts(self, accountsList): pass #showmessage('managedAccounts', vars()) 
    def receiveFA(self, faDataType, xml): showmessage('receiveFA', vars()) 
    def historicalData(self, reqId, date, open, high, low, close, volume, count, WAP, hasGaps): showmessage('historicalData', vars()) 
    def scannerParameters(self, xml): showmessage('scannerParameters', vars()) 
    def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection): showmessage('scannerData', vars()) 
    def scannerDataEnd(self, reqId): showmessage('scannerDataEnd', vars()) 
    def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count): showmessage('realtimeBar', vars()) 
    def currentTime(self, time): showmessage('currentTime', vars()) 
    def fundamentalData(self, reqId, data): showmessage('fundamentalData', vars()) 
    def deltaNeutralValidation(self, reqId, underComp): showmessage('deltaNeutralValidation', vars()) 
    def tickSnapshotEnd(self, reqId): showmessage('tickSnapshotEnd', vars()) 
    def marketDataType(self, reqId, marketDataType): showmessage('marketDataType', vars()) 
    def commissionReport(self, commissionReport): showmessage('commissionReport', vars()) 
Пример #33
0
# -*- coding: utf-8 -*-
"""
Interaction Brokers Connection

Connection Demo
"""

from IBWrapper import IBWrapper
from ib.ext.EClientSocket import EClientSocket

accountName = "DU230008"
callback = IBWrapper()        # Instantiate IBWrapper. callback 
tws = EClientSocket(callback) # Instantiate EClientSocket and return data to callback
host = "localhost"                     # For local host
port = 7497
clientId = 5

tws.eConnect(host, port, clientId) # Connect to TWS

tws.eDisconnect()
Пример #34
0
from IBWrapper import IBWrapper, contract
from ib.ext.EClientSocket import EClientSocket
import pandas as pd
from datetime import datetime
import os
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from pandas.lib import Timestamp
import pytz
#import datetime
import dateutil.relativedelta
import random

callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7497
clientId = 100

#connect
tws.eConnect(host, port, clientId)
print("connected")

time.sleep(2)
#read function from package into a variable
create = contract()
#callback function to fetch data into specified similar named columns
callback.initiate_variables()

#fetch from TWS 1st ticker
Пример #35
0
class IBClient(object):
    """IB Socket client"""

    def __init__(self, client_name='IB', host='localhost', port=7496, client_id=0):
        """Constructor"""
        self.client_name = client_name
        self.host = host  # host IP address in a string; e.g. '127.0.0.1', 'localhost'
        self.port = port  # socket port; TWS default value: 7496; TWS demo account default value: 7497
        self.client_id = client_id  # socket client id

        self.connected = False  # status of the socket connection

        self.tickerId = 0  # known as ticker ID or request ID
        self.ipc_msg_dict = {}  # key: ticker ID or request ID; value: request and response objects; response objects ususally carrys data, Events, and Status
        self.order_id = 0  # current available order ID
        self.order_dict = {}  # key: ticker ID or request ID; value: request and response objects; response objects ususally carrys data, Events, and Status

        self.context = None  # key: ticker ID or request ID; value: request and response objects; response objects ususally carrys data, Events, and Status
        self.data = None

        self.wrapper = IBMsgWrapper(self)  # the instance with IB message callback methods
        self.connection = EClientSocket(self.wrapper)  # low layer socket client

        # TWS's data connection status
        self.hmdf_status_dict = {}
        for farm in IB_FARM_NAME_LS:
            self.hmdf_status_dict[farm] = 'unknown'

        # EVENTS
        self.conn_down_event = Event()  # sock connection event
        self.mdf_conn_event = Event()  # market data connection event
        self.hdf_conn_event = Event()  # hist data connection event

        self.order_event = Event()
        self.account_event = Event()
        self.get_order_event = Event()

        # LOCKER
        self.req_id_locker = threading.Lock()

        # CONSTANT VALUES
        self.PRICE_DF_HEADER1 = ['time', 'open', 'high', 'low', 'close', 'volume']
        self.PRICE_DF_HEADER2 = ['symbol', 'time', 'open', 'high', 'low', 'close', 'volume']

    def connect(self):
        """ Connect to socket host, e.g. TWS """
        self.connection.eConnect(self.host, self.port, self.client_id)

        timeout = 5.
        count = 0.
        while not self.connected and count < timeout:
            count += 0.05
            sleep(0.05)

        if self.connected:
            self.order_id = self.connection.reqIds(-1)
            if self.context is not None:
                # TODO: may need to move this to a thread or at user layer
                self.enable_account_info_update()
        else:
            print('failed to connect.')

        return self.connected

    def close(self):
        """ disconnect from IB host """
        self.disconnect()

    def disconnect(self):
        """ disconnect from IB host """
        if self.context is not None:
            self.disable_account_info_update()

        self.connection.eDisconnect()
        self.connected = False

    def register_strategy(self, context, data):
        """  TBA """
        self.context = context
        self.data = data

    def __get_new_request_id(self):
        '''' genew request ID (ticker ID) in a thread safe way '''
        self.req_id_locker.acquire()
        self.tickerId += 1
        __id = self.tickerId
        self.req_id_locker.release()
        return __id

    #
    # Tick Data Methods
    #
    def request_tick_data(self, contract):
        """ Subscribe tick data for a specified contract
        Args:
            contract: a legal IBPY Contract object or a string for U.S. stock only
        Returns:
            tickerId:  the ID of this request. this ID could be used to cancel request later.
            tick_data: a reference to the tick data dictionary which will be updated with latest quote.
        """
        if isinstance(contract, Contract):
            pass
        elif isinstance(contract, str):
            contract = new_stock_contract(contract)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        __id = self.__get_new_request_id()
        request = RequestDetails('reqMktData', 'Snapshot', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        # False - indicating request live quotes instead of a snapshot
        self.connection.reqMktData(__id, contract, '', False)

        return __id, self.ipc_msg_dict[__id][1].tick_data

    def get_tick_snapshot(self, contract, max_wait_time=5):
        """ Get a snapshot with default tick types and corresponding tick data for a given contract

        Note: 1) no generic ticks can be specified.
              2) only return data fields which have changed within an 11 second interval.
              If it is necessary for an API client to receive a certain data field, it is better
              to subscribe to market data until that field has been returned and then cancel the market data request.

        Known Issues:
              1) When called outside of market hours, get_tick_snapshot request could take more than 10 sec
                 to reach the end (tickSnapshotEnd)
              2) Need to check Issue#1 during market hours

        Args:
            contract: a legal IBPY Contract object or a string for U.S. stock only

        Returns:
            a copy of tick data dictionary
        Raises:
            None
        """
        if isinstance(contract, Contract):
            pass
        elif isinstance(contract, str):
            contract = new_stock_contract(contract)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        __id = self.__get_new_request_id()

        request = RequestDetails('reqMktData', 'Snapshot', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        # send reqMktData req
        # True - indicating request live quotes instead of a snapshot
        #
        # Important:
        # When set it to 'True', each regulatory snapshot made will incur a fee of 0.01 USD to the account.
        # This applies to both live and paper accounts.
        self.connection.reqMktData(__id, contract, '', True)

        response.event.wait(max_wait_time)
        if response.event.is_set():
            # tickPrice() and tickeSize() may write after tickSnapshotEnd() completed.
            sleep(0.5)
            snapshot = copy(response.tick_data)
            # remove the from dict and free the memory
            response.event.clear()
            self.ipc_msg_dict.pop(__id)
        else:
            response.event.clear()
            self.ipc_msg_dict.pop(__id)
            raise RuntimeError('reqMktData (get_tick_snapshot) is timeout. max_wait_time=%d' % (max_wait_time))

        return snapshot

    def cancel_tick_request(self, tickerId):
        """ Cancel tick data request for a given ticker ID (request ID)

        Args:
            tickerId: the ticker request to cancel
        Returns:
            None
        Raises:
            None
        """
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        # TODO: check if tickerID is in the list
        self.connection.cancelMktData(tickerId)
        self.ipc_msg_dict.pop(tickerId)
        return

    def request_realtime_price(self, contract, price_type='TRADES'):
        """ Get real-time price/volume for a specific contract, e.g. stocks, futures and option contracts.
            IB API support only 5 sec duration between two real-time bar (price) records.
        Args:
            contract: one IB contract instance
            price_type: 'TRADES', 'MIDPOINT', 'BID',  'ASK'
        Returns:
            tickerId: the request ID; it's also the key to get response msg from ipc_msg_dict
            realtime_price: a reference to the real-time price (OCHL) list which will be updated
                            with latest price (OCHL) record.
        Raises:
            None
        """
        if isinstance(contract, Contract):
            pass
        elif isinstance(contract, str):
            contract = new_stock_contract(contract)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if price_type not in ['TRADES', 'MIDPOINT', 'BID', 'ASK']:
            raise TypeError("Got incorrect price_type")

        __id = self.__get_new_request_id()
        request = RequestDetails('reqHistoricalData', price_type, contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)
        # only 5 sec duration supported
        # price_type: 'TRADES', 'MIDPOINT', 'BID',  'ASK'
        # useRTH - set to True
        self.connection.reqRealTimeBars(__id, contract, 5, price_type, True)

        return __id, self.ipc_msg_dict[__id][1].rt_price

    def cancel_realtime_price(self, req_id):
        """ Cancel realtime price/volumne request.
        Args:
            req_id: the ticker ID (or request ID)
        Returns:
            None
        """
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')
        self.connection.cancelRealTimeBars(req_id)

        # remove request/response data from ipc_msg_dict
        self.ipc_msg_dict.pop(req_id)
        return

    #
    # Historical Data Methods
    #
    def get_price_history(self, contract, ts_end, duration='1 M', frequency='daily', max_wait_time=30):
        """ Get price/volumne history for a specific contract, e.g. stocks, futures and option ocntract.

        Args:
            contract: one IB contract instance
            ts_end: a string in '%Y%m%d' or '%Y%m%d %H:%M:%S' format
            duration: string
                        X S	Seconds
                        X D	Day
                        X W	Week
                        X M	Month
                        X Y	Year
            frequency: {‘daily’, ‘minute’}, optional; Resolution of the data to be returned.
            max_wait_time: int; max num of sec to wait after calling reqHistoricalData
        Returns:
            pandas Panel/DataFrame/Series – The pricing data that was requested.

                            Open  High   Low  Close     Volume
                Date
                2017-12-15  6.96  6.96  6.86   6.90  366523000
                2017-12-18  6.88  7.02  6.87   6.98  303664000
                2017-12-19  7.00  7.02  6.98   7.01  299342000

        Raises:
            None

        """
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(contract, Contract):
            pass
        elif isinstance(contract, str):
            contract = new_stock_contract(contract)
        else:
            raise TypeError("contract must be a Contract object or string")

        if frequency == 'daily':
            bar_size = '1 day'
        elif frequency == 'minute':
            bar_size = '1 min'
        elif frequency == 'second':
            bar_size = '1 sec'
        elif frequency == '5 seconds':
            bar_size = '5 secs'
        else:
            raise ValueError("get_price_history: incorrect frequency value")

        if len(ts_end) == 8 or len(ts_end) == 17:
            if len(ts_end) == 8:
                ts_end = ts_end + ' 23:59:59'
        else:
            print('get_price_history: incorrect ts_end format')
            return

        __id = self.__get_new_request_id()
        request = RequestDetails('reqHistoricalData', '', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        self.connection.reqHistoricalData(tickerId=__id, contract=contract, endDateTime=ts_end, durationStr=duration,
                                          barSizeSetting=bar_size, whatToShow='TRADES', useRTH=0, formatDate=1)

        df = None
        response.event.wait(max_wait_time)
        if response.event.is_set():
            df = pd.DataFrame(response.price_hist, columns=self.PRICE_DF_HEADER1)
            # clean up the time format
            date = df['time'][0]

            if len(date) == 8:
                df['time'] = pd.to_datetime(df['time'], format='%Y%m%d')
            elif len(date) == 18:
                # len('20161020 23:46:00') --> 2 Spaces!!!!!
                # adj_date = datetime.strptime(date, "%Y%m%d  %H:%M:%S")
                df['time'] = pd.to_datetime(df['time'], format="%Y%m%d  %H:%M:%S")
            else:
                # adj_date = datetime.strptime(date, "%Y%m%d %H:%M:%S")
                df['time'] = pd.to_datetime(df['time'], format="%Y%m%d %H:%M:%S")

            # TODO: check for timezone
            # exchange = request.contract.m_exchange
            # server_timezone = pytz.timezone("Asia/Shanghai")  # timezone where the server runs
            # mkt_timezone = pytz.timezone(IBEXCHANGE.get_timezone(exchange))  # Get Exchange's timezone
            # adj_date = server_timezone.localize(adj_date).astimezone(
            #     mkt_timezone)  # covert server time to Exchange's time
            # adj_date = adj_date.strftime("%Y%m%d %H:%M:%S")  # from datetime to string

            df = df.set_index('time')
            # remove the from dict and free the memory
            response.event.clear()
            self.ipc_msg_dict.pop(__id)
        else:
            self.ipc_msg_dict.pop(__id)
            print('reqHistoricalData is timeout.')
            raise RuntimeError('reqHistoricalData is timeout.')

        return df

    def get_stock_price_history(self, security_list, ts_end, duration='1 M', frequency='daily', max_wait_time=30):
        """Get price/volumne history for a list of stocks.

        Args:
            security_list: a list of security symbols, .e.g. ['IBM', 'DATA']
            endDateTime: a string in '%Y%m%d' or '%Y%m%d %H:%M:%S' format
            durationStr: see IB API doc.
            frequency: {‘daily’, ‘minute’}, optional; Resolution of the data to be returned.
            max_wait_time: int; max num of sec to wait after calling reqHistoricalData
        Returns:
            pandas Panel/DataFrame/Series – The pricing data that was requested.
        Raises:
            None

        """
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        num_secs = len(security_list)
        if num_secs <= 0:
            return

        if frequency == 'daily':
            bar_size = '1 day'
        elif frequency == 'minute':
            bar_size = '1 min'
        elif frequency == 'second':
            bar_size = '1 sec'
        elif frequency == '5 seconds':
            bar_size = '5 secs'
        else:
            print('get_stock_price_history: incorrect frequency')
            return

        if len(ts_end) == 8 or len(ts_end) == 17:
            if len(ts_end) == 8:
                ts_end = ts_end + ' 23:59:59'
        else:
            print('get_stock_price_history: incorrect ts_end format')
            return

        # ['Symbol', 'Date', 'Open', 'High', 'Low', 'Close', 'Volume']
        df = pd.DataFrame(columns=self.PRICE_DF_HEADER2)
        for sec in security_list:

            __id = self.__get_new_request_id()

            contract = new_stock_contract(sec)
            request = RequestDetails('reqHistoricalData', '', contract)
            response = ResponseDetails()
            self.ipc_msg_dict[__id] = (request, response)

            self.connection.reqHistoricalData(tickerId=__id, contract=contract, endDateTime=ts_end,
                                              durationStr=duration, barSizeSetting=bar_size, whatToShow='TRADES',
                                              useRTH=0, formatDate=1)

            response.event.wait(max_wait_time)
            if response.event.is_set():

                df_tmp = pd.DataFrame(response.price_hist, columns=self.PRICE_DF_HEADER1)
                # clean up the time format
                date = df_tmp['time'][0]

                if len(date) == 8:
                    df_tmp['time'] = pd.to_datetime(df_tmp['time'], format='%Y%m%d')
                elif len(date) == 18:
                    # len('20161020 23:46:00') --> 2 Spaces!!!!!
                    # adj_date = datetime.strptime(date, "%Y%m%d  %H:%M:%S")
                    df_tmp['time'] = pd.to_datetime(df_tmp['time'], format="%Y%m%d  %H:%M:%S")
                else:
                    # adj_date = datetime.strptime(date, "%Y%m%d %H:%M:%S")
                    df_tmp['time'] = pd.to_datetime(df_tmp['time'], format="%Y%m%d %H:%M:%S")

                # TODO: check for timezone
                # exchange = request.contract.m_exchange
                # server_timezone = pytz.timezone("Asia/Shanghai")  # timezone where the server runs
                # mkt_timezone = pytz.timezone(IBEXCHANGE.get_timezone(exchange))  # Get Exchange's timezone
                # adj_date = server_timezone.localize(adj_date).astimezone(
                #     mkt_timezone)  # covert server time to Exchange's time
                # adj_date = adj_date.strftime("%Y%m%d %H:%M:%S")  # from datetime to string

                df_tmp['symbol'] = pd.DataFrame([sec] * len(df_tmp))
                df = df.append(df_tmp)
                # remove the from dict and free the memory
                self.ipc_msg_dict.pop(__id)
                response.event.clear()

            else:
                self.ipc_msg_dict.pop(__id)
                raise RuntimeError('reqHistoricalData is timeout.')

        return df

    def get_contract_price_history(self, contract, ts_end, duration='1 M', frequency='daily', max_wait_time=30):
        # Same function as get_price_history
        return self.get_price_history(self, contract, ts_end, duration, frequency, max_wait_time)

    #
    # Placing/Changing/Canceling Order Methods
    #
    def order_amount(self, contract, amount, style=MarketOrder()):
        ''' Place an order. Order X units of security Y.
            Warning: only mkt order and limited order work; calling stoploss/stoplimited order will result in IB disconnection.
        :param contract: A IB Contract object.
        :param amount: The integer amount of shares. Positive means buy, negative means sell.
        :param style:
        :return:
        '''
        if amount == 0:
            return -1
        elif amount > 0:
            action = 'BUY'
        else:
            action = 'SELL'

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if not isinstance(contract, Contract):
            raise TypeError("contract must be a contract object")
        # request next valid order ID from IB host; this request will update self.order_id
        self.connection.reqIds(-1)  # note: input param is always ignored;
        sleep(0.05)

        order = Order()
        order.m_orderId = self.order_id
        order.m_client_id = self.client_id
        order.m_action = action
        order.m_totalQuantity = abs(amount)
        order.m_orderType = style.order_type
        if style.limit_price is not None:
            order.m_lmtPrice = style.limit_price
        if style.stop_price is not None:
            order.m_auxPrice = style.stop_price
        order.m_overridePercentageConstraints = True  # override TWS order size constraints

        # place order
        self.connection.placeOrder(self.order_id, contract, order)
        # TODO: wait for returns from orderStatus
        return self.order_id

    def combo_order_amount(self, contract, amount, style=MarketOrder()):
        ''' Place an order

        :param contract: A security object.
        :param amount: The integer amount of shares. Positive means buy, negative means sell.
        :param style:
        :return:
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if amount == 0:
            return -1
        elif amount > 0:
            action = 'BUY'
        else:
            action = 'SELL'

        if isinstance(contract, Contract):
            if len(contract.m_comboLegs) == 0:
                raise TypeError("contract must contains combo legs")
        else:
            raise TypeError("contract must be a contract object")

        # request next valid order ID from IB host; this request will update self.order_id
        self.connection.reqIds(-1)  # note: input param is always ignored;
        sleep(0.05)

        order = Order()
        order.m_orderId = self.order_id
        order.m_client_id = self.client_id
        order.m_action = action
        order.m_totalQuantity = abs(amount)
        order.m_orderType = style.order_type
        if style.limit_price is not None:
            order.m_lmtPrice = style.limit_price
        if style.stop_price is not None:
            order.m_auxPrice = style.stop_price

        order.m_overridePercentageConstraints = True  # override TWS order size constraints
        '''
        # Advanced configuration. Not tested yet.
        if style.is_combo_order:
            if style.non_guaranteed:
                tag = TagValue()
                tag.m_tag = "NonGuaranteed"
                tag.m_value = "1"
                order.m_smartComboRoutingParams = [tag]
        '''
        self.connection.placeOrder(self.order_id, contract, order)
        return self.order_id

    def order_value(self, contract, value, style):
        ''' Reserve for future implementation

        :param contract:
        :param value:
        :param style:
        :return:
        '''
        pass

    def order_target(self, contract, amount, style):
        ''' Places an order to adjust a position to a target number of shares.

        :param contract:
        :param value:
        :param style:
        :return:
        '''
        pass

    def order_target_value(self, contract, amount, style):
        ''' Places an order to adjust a position to a target value.

        :param contract:
        :param value:
        :param style:
        :return:
        '''
        pass

    def modify_order(self, order_id, contract, amount, style=MarketOrder()):
        ''' Change amount or order type (including limited price for limtied orders)
            for a existing order specified by order_id
        
        :param order_id: a existing order's order_id
        :param contract: A IB Contract object. supposed to be the same with the order-to-be-modified.
        :param amount: The integer amount of shares. Positive means buy, negative means sell.
        :param style: market order or limited order
        :return: the existing order's order_id (same as the input)
        '''

        if amount == 0:
            return -1
        elif amount > 0:
            action = 'BUY'
        else:
            action = 'SELL'

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if not isinstance(contract, Contract):
            raise TypeError("contract must be a contract object")

        order = Order()
        order.m_orderId = order_id
        order.m_client_id = self.client_id
        order.m_action = action
        order.m_totalQuantity = abs(amount)
        order.m_orderType = style.order_type
        if style.limit_price is not None:
            order.m_lmtPrice = style.limit_price
        if style.stop_price is not None:
            order.m_auxPrice = style.stop_price
        order.m_overridePercentageConstraints = True  # override TWS order size constraints

        # place order
        self.connection.placeOrder(self.order_id, contract, order)
        # TODO: wait for returns from orderStatus
        return self.order_id

    def cancel_order(self, order):
        ''' Attempts to cancel the specified order. Cancel is attempted asynchronously.

        :param order: Can be the order_id as a string or the order object.
        :return: None
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(order, int):
            order_id = order
        elif isinstance(order, Order):
            order_id = order.m_orderId
        else:
            raise TypeError("order must be a order_id (int) or order object")
        self.connection.cancelOrder(order_id)

    def get_open_orders(self):
        ''' Attempts to get all open orders.

        :param
        :return: None
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if 'reqOpenOrders' not in self.ipc_msg_dict:
            request = RequestDetails('reqOpenOrders', '', '')
            response = ResponseDetails()
            self.ipc_msg_dict['reqOpenOrders'] = (request, response)
        else:
            response = self.ipc_msg_dict['reqOpenOrders'][1]

        # self.connection.reqOpenOrders()
        # self.reqAutoOpenOrders(True)
        self.connection.reqAllOpenOrders()

        max_wait_time = 3.
        self.get_order_event.wait(max_wait_time)
        if self.get_order_event.is_set():
            # snapshot = copy(response.tick_snapshot)
            # self.ipc_msg_dict.pop(self.tickerId)
            self.get_order_event.clear()
        else:
            # self.ipc_msg_dict.pop(self.tickerId)
            raise RuntimeError('get_open_orders is timeout.')

        return

    #
    # Account Info Methods
    #
    def enable_account_info_update(self):
        ''' Turn on auto account update, meaning IB socket host will push account info to IB socket client.
                updateAccountTime()
                updateAccountValue()
                updatePortfolio()
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        # TODO: check self.IB_acct_id before using it
        # request IB host (e.g. TWS) push account info to IB client (socket client)
        self.connection.reqAccountUpdates(True, self.context.account.account_id)
        return

    def disable_account_info_update(self):
        ''' Turn off auto account update, meaning IB socket host will stop pushing account info
         to IB socket client.
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        # TODO: check self.IB_acct_id before using it
        # stop IB host (e.g. TWS) to push account info to IB client (socket client)
        self.connection.reqAccountUpdates(False, self.context.account.account_id)
        return

    #
    # Fundamental Data Methods
    #
    def get_financial_statements(self, symbol, max_wait_time=20):
        ''' Get a company's financial statements

        :param:
            symbol: stock symbol string, e.g. 'IBM'; or a IB contract object
        :return:
            a string of financial statements
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()

        request = RequestDetails('reqFundamentalData', 'ReportsFinStatements', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        self.connection.reqFundamentalData(__id, contract, 'ReportsFinStatements')

        response.event.wait(max_wait_time)
        raw_xml = None
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # covert from xml to dest. format
                raw_xml = copy(response.fundamental_data)
            else:
                pass  # raise RuntimeError('get_financial_statements: reqFundamentalData got error. Security=%s Reason:%s' % (symbol, response.error_msg))
        else:
            # Timeout
            pass  # ('get_financial_statements: reqFundamentalData is timeout. Security=%s' % symbol)

        status = response.status
        self.ipc_msg_dict.pop(__id)
        return status, raw_xml

    def get_company_ownership(self, symbol, max_wait_time=60.0 * 5):
        ''' Get a company's ownership report

        :param:
            symbol: stock symbol string, e.g. 'IBM'
            max_wait_time: max number of seconds to wait before raise timeout
        :return:
            a string of ownership report
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            # For US stock only
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()

        request = RequestDetails('reqFundamentalData', 'ReportsOwnership', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        self.connection.reqFundamentalData(__id, contract, 'ReportsOwnership')

        response.event.wait(max_wait_time)
        report = None
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # covert from xml to dest. format
                report = parse_ownership_report(response.fundamental_data)
            else:
                pass  # ('get_company_ownership: reqFundamentalData got error. Security=%s Reason:%s' % (symbol, response.error_msg))
        else:
            pass  # ('get_company_ownership: reqFundamentalData is timeout. Security=%s' % symbol)

        status = response.status
        self.ipc_msg_dict.pop(__id)
        return status, report

    def get_analyst_estimates(self, symbol, max_wait_time=20):
        ''' Get analyst estimates report for a company

        :param:
            symbol: stock symbol string, e.g. 'IBM'; or a IB contract object
        :return:
            a string of financial statements
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()

        request = RequestDetails('reqFundamentalData', 'RESC-Analyst Estimates', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        self.connection.reqFundamentalData(__id, contract, 'RESC')

        response.event.wait(max_wait_time)
        report = None
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # covert from xml to dest. format
                report = parse_analyst_estimates(response.fundamental_data)
            else:
                pass  # ('get_analyst_estimates: reqFundamentalData got error. Security=%s Reason:%s' % (symbol, response.error_msg))
        else:
            pass  # ('get_analyst_estimates: reqFundamentalData is timeout. Security=%s' % symbol)

        status = response.status
        self.ipc_msg_dict.pop(__id)
        return status, report

    def get_company_overview(self, symbol, max_wait_time=10):
        ''' Get company overview infomration

        :param:
            symbol: stock symbol string, e.g. 'IBM'; or a IB contract object
        :return:
            a string of financial statements
        '''
        # ReportsFinSummary	Financial summary

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()

        request = RequestDetails('reqFundamentalData', 'ReportSnapshot-Company overview', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        # ReportSnapshot	Company's financial overview
        self.connection.reqFundamentalData(__id, contract, 'ReportSnapshot')

        response.event.wait(max_wait_time)
        report = None
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # TODO: covert from xml to dest. format
                report = response.fundamental_data
            else:
                pass  # ('get_analyst_estimates: reqFundamentalData got error. Security=%s Reason:%s' % (symbol, response.error_msg))
        else:
            pass  # ('get_analyst_estimates: reqFundamentalData is timeout. Security=%s' % symbol)

        status = response.status
        self.ipc_msg_dict.pop(__id)
        return status, report

    def get_financial_summary(self, symbol, max_wait_time=10):
        ''' Get company finanical summary information, such as revenue history, net profit, and dividends history.

        :param:
            symbol: stock symbol string, e.g. 'IBM'; or a IB contract object
        :return:
            a string of financial statements
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()

        request = RequestDetails('reqFundamentalData', 'ReportsFinSummary-Financial summary', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        self.connection.reqFundamentalData(__id, contract, 'ReportsFinSummary')

        response.event.wait(max_wait_time)
        report = None
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # TODO: covert from xml to dest. format
                report = response.fundamental_data
            else:
                pass
        else:
            pass

        status = response.status
        self.ipc_msg_dict.pop(__id)
        return status, report

    def get_financial_ratios(self, symbol, max_wait_time=5):
        ''' Get analyst estimates report for a company

        :param:
            symbol: stock symbol string, e.g. 'IBM'
        :return:
            a string of financial statements
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()

        request = RequestDetails('reqFundamentalData', 'RESC-Analyst Estimates', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        # 258 - financial ratios
        '''
            TTMNPMGN=16.1298;NLOW=80.6;TTMPRCFPS=6.26675;TTMGROSMGN=60.76731;TTMCFSHR=15.004
            46;QCURRATIO=1.42071;TTMREV=259842;TTMINVTURN=5.28024;TTMOPMGN=14.22711;TTMPR2RE
            V=1.39703;AEPSNORM=8.55;TTMNIPEREM=144524.1;EPSCHNGYR=8.47727;TTMPRFCFPS=62.4260
            6;TTMRECTURN=19.99938;TTMPTMGN=17.88125;QCSHPS=40.50882;TTMFCF=5815;
            LATESTADATE=2016-12-31;APTMGNPCT=17.88125;AEBTNORM=46463;TTMNIAC=33008;NetDebt_I=152080;
            PRYTDPCTR=-1.55563;TTMEBITD=53326;AFEEPSNTM=0;PR2TANBK=5.01599;EPSTRENDGR=-
            15.53209;QTOTD2EQ=72.60778;TTMFCFSHR=1.50625;QBVPS=110.0867;NPRICE=94.1;YLD5YAVG
            =3.88751;REVTRENDGR=51.11774;TTMEPSXCLX=8.54981;QTANBVPS=18.75999;PRICE2BK=0.854
            78;MKTCAP=363007.5;TTMPAYRAT=31.32574;TTMINTCOV=-99999.99;TTMDIVSHR=2.585;TTMREVCHG=55.81794;
            TTMROAPCT=4.09615;TTMROEPCT=7.73685;
            TTMREVPERE=896006.9;APENORM=11.00585;TTMROIPCT=5.51924;REVCHNGYR=-
            6.66885;CURRENCY=HKD;DIVGRPCT=-8.33887;TTMEPSCHG=-32.80548;PEEXCLXOR=11.00609;QQUICKRATI=1.30087;
            TTMREVPS=67.30638;BETA=0.90979;TTMEBT=46463;ADIV5YAVG=3.1048;ANIACNORM=33008;QLTD2EQ=55.46377;NHIG=103.9
        '''
        report = None
        self.connection.reqMktData(__id, contract, "258", False)
        response.event.wait(max_wait_time)
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # TODO: convert the format to a table alike
                report = response.tick_str

        return report

    def get_dividends_info(self, symbol, max_wait_time=5):
        ''' Get analyst estimates report for a company

        :param:
            symbol: stock symbol string, e.g. 'IBM'
        :return:
            a string of financial statements
        '''
        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        if isinstance(symbol, Contract):
            contract = symbol
        elif isinstance(symbol, str):
            contract = new_stock_contract(symbol)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        __id = self.__get_new_request_id()
        request = RequestDetails('reqFundamentalData', 'RESC-Analyst Estimates', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        # IB Dividends ("456")
        #
        # This tick type provides four different comma-separated elements:
        # The sum of dividends for the past 12 months (0.83 in the example below).
        # The sum of dividends for the next 12 months (0.92 from the example below).
        # The next dividend date (20130219 in the example below).
        # The next single dividend amount (0.23 from the example below).
        # Example: 0.83,0.92,20130219,0.23
        self.connection.reqMktData(__id, contract, "456", False)
        result = None
        response.event.wait(max_wait_time)
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                # TODO: convert the format
                result = set(response.tick_str.split(','))

        self.ipc_msg_dict.pop(__id)

        return result

    def get_contract_details(self, contract, max_wait_time=5):
        """ Get contract details for a specified contract
        Args:
            contract: a legal IBPY Contract object or a string for U.S. stock only
        Returns:
            status: a reference to the tick data dictionary which will be updated with latest quote.
            contract_details: a contractDetails instance
        """
        if isinstance(contract, Contract):
            pass
        elif isinstance(contract, str):
            contract = new_stock_contract(contract)
        else:
            raise TypeError("contract must be a contract object or string (for U.S. stocks only).")

        if not self.connected:
            raise RuntimeError('IB client is not connected to TWS')

        __id = self.__get_new_request_id()
        request = RequestDetails('reqContractDetails', '', contract)
        response = ResponseDetails()
        self.ipc_msg_dict[__id] = (request, response)

        # False - indicating request live quotes instead of a snapshot
        self.connection.reqContractDetails(__id, contract)

        response.event.wait(max_wait_time)
        contract_details = None
        if response.event.is_set():
            if response.status == ResponseDetails.STATUS_FINISHED:
                if len(response.contract_list) > 0:
                    contract_details = copy(response.contract_list[0])
            else:
                pass
        else:
            pass

        status = response.status
        self.ipc_msg_dict.pop(__id)

        return status, contract_details

    def get_full_contract(self, contract):
        """ Subscribe tick data for a specified contract
        Args:
            contract: a legal IBPY Contract object or a string for U.S. stock only
        Returns:
            tickerId:  the ID of this request. this ID could be used to cancel request later.
            tick_data: a reference to the tick data dictionary which will be updated with latest quote.
        """

        status, contract_details = self.get_contract_details(contract)
        new_contract = copy(contract_details.m_summary)

        return status, new_contract
Пример #36
0
###start of intializations
tf1 = 1
tf2 = 1
new_entry = 'T'
wdw = 25
ctime = 0
r_sflag = 0
r_qty = 0
cnt = 0
global o_type ,order_id

# end of intializations


callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7497
clientId = 100
create = contract()
callback.initiate_variables()
tws.eConnect(host, port, clientId)
print("connected")
####dummy data request
contract_Details1 = create.create_contract("ES" ,"FUT" ,"GLOBEX" ,"USD" ,'' ,'' ,'20170616' ,'50')
tickerId = random.randint(1, 1000000)
# print(datetime.now())
tws.reqRealTimeBars(tickerId,
                    contract_Details1,
                    5,
                    "TRADES",
Пример #37
0
            print(df_order_status)
            print(
                "###############################################################\n"
            )
        else:
            print(
                "\n###################### No orders to show #######################\n"
            )

        return df_order_status


# Establish connection ----------------------------------------------------------------------
#accountName = "Your Account Name Here"
callback = IBWrapper()  # Instantiate IBWrapper. callback
tws = EClientSocket(
    callback)  # Instantiate EClientSocket and return data to callback
host = ""
port = 4002
clientId = 8
tws.eConnect(host, port, clientId)  # Connect to TWS
create = contract()  # Instantiate contract class
callback.initiate_variables()
tws.reqAccountUpdates(1, accountName)

# Portfolio Query ------------------------------------------------------------

ib = IB()
df_portfolio = ib.portfolio()
count = len(df_portfolio)

# Disconnect ------------------------------------------------------------------
Пример #38
0
class IbGateway(VtGateway):
    """IB接口"""

    #----------------------------------------------------------------------
    def __init__(self, eventEngine, gatewayName='IB'):
        """Constructor"""
        super(IbGateway, self).__init__(eventEngine, gatewayName)
        
        self.host = EMPTY_STRING        # 连接地址
        self.port = EMPTY_INT           # 连接端口
        self.clientId = EMPTY_INT       # 用户编号
        
        self.tickerId = 0               # 订阅行情时的代码编号    
        self.tickDict = {}              # tick快照字典,key为tickerId,value为VtTickData对象
        
        self.orderId  = 0               # 订单编号
        self.orderDict = {}             # 报单字典,key为orderId,value为VtOrderData对象
        
        self.accountDict = {}           # 账户字典
        
        self.connected = False          # 连接状态
        
        self.wrapper = IbWrapper(self)                  # 回调接口
        self.connection = EClientSocket(self.wrapper)   # 主动接口

    #----------------------------------------------------------------------
    def connect(self):
        """连接"""
        # 载入json文件
        fileName = self.gatewayName + '_connect.json'
        fileName = os.getcwd() + '/ibGateway/' + fileName
        
        try:
            f = file(fileName)
        except IOError:
            log = VtLogData()
            log.gatewayName = self.gatewayName
            log.logContent = u'读取连接配置出错,请检查'
            self.onLog(log)
            return
        
        # 解析json文件
        setting = json.load(f)
        try:
            self.host = str(setting['host'])
            self.port = int(setting['port'])
            self.clientId = int(setting['clientId'])
        except KeyError:
            log = VtLogData()
            log.gatewayName = self.gatewayName
            log.logContent = u'连接配置缺少字段,请检查'
            self.onLog(log)
            return            
        
        # 发起连接
        self.connection.eConnect(self.host, self.port, self.clientId)
        
        # 查询服务器时间
        self.connection.reqCurrentTime()
        
        # 请求账户数据主推更新
        self.connection.reqAccountUpdates(True, '')
    
    #----------------------------------------------------------------------
    def subscribe(self, subscribeReq):
        """订阅行情"""
        # 订阅行情
        self.tickerId += 1
        
        contract = Contract()
        contract.m_symbol = str(subscribeReq.symbol)
        contract.m_exchange = exchangeMap.get(subscribeReq.exchange, '')
        contract.m_secType = productClassMap.get(subscribeReq.productClass, '')
        contract.m_currency = currencyMap.get(subscribeReq.currency, '')
        contract.m_expiry = subscribeReq.expiry
        contract.m_strike = subscribeReq.strikePrice
        contract.m_right = optionTypeMap.get(subscribeReq.optionType, '')
    
        self.connection.reqMktData(self.tickerId, contract, '', False)
        
        # 创建Tick对象并保存到字典中
        tick = VtTickData()
        tick.symbol = subscribeReq.symbol
        tick.exchange = subscribeReq.exchange
        tick.vtSymbol = '.'.join([tick.symbol, tick.exchange])
        tick.gatewayName = self.gatewayName
        self.tickDict[self.tickerId] = tick
    
    #----------------------------------------------------------------------
    def sendOrder(self, orderReq):
        """发单"""
        # 增加报单号1,最后再次进行查询
        # 这里双重设计的目的是为了防止某些情况下,连续发单时,nextOrderId的回调推送速度慢导致没有更新
        self.orderId += 1
        
        # 创建合约对象
        contract = Contract()
        contract.m_symbol = str(orderReq.symbol)
        contract.m_exchange = exchangeMap.get(orderReq.exchange, '')
        contract.m_secType = productClassMap.get(orderReq.productClass, '')
        contract.m_currency = currencyMap.get(orderReq.currency, '')
        
        contract.m_expiry = orderReq.expiry
        contract.m_strike = orderReq.strikePrice
        contract.m_right = optionTypeMap.get(orderReq.optionType, '')
        
        # 创建委托对象
        order = Order()
        order.m_orderId = self.orderId
        order.m_clientId = self.clientId
        
        order.m_action = directionMap.get(orderReq.direction, '')
        order.m_lmtPrice = orderReq.price
        order.m_totalQuantity = orderReq.volume
        order.m_orderType = priceTypeMap.get(orderReq.priceType, '')
        
        # 发送委托
        self.connection.placeOrder(self.orderId, contract, order)
        
        # 查询下一个有效编号
        self.connection.reqIds(1)
    
    #----------------------------------------------------------------------
    def cancelOrder(self, cancelOrderReq):
        """撤单"""
        self.connection.cancelOrder(cancelOrderReq.orderID)
    
    #----------------------------------------------------------------------
    def qryAccount(self):
        """查询账户资金"""
        log = VtLogData()
        log.gatewayName = self.gatewayName        
        log.logContent = u'IB接口账户信息提供主推更新,无需查询'
        self.onLog(log) 
    
    #----------------------------------------------------------------------
    def qryPosition(self):
        """查询持仓"""
        log = VtLogData()
        log.gatewayName = self.gatewayName        
        log.logContent = u'IB接口持仓信息提供主推更新,无需查询'
        self.onLog(log) 
    
    #----------------------------------------------------------------------
    def close(self):
        """关闭"""
        self.connection.eDisconnect()
Пример #39
0
import pandas as pd
from datetime import datetime, timedelta
import threading
from threading import Thread
import multiprocessing
from multiprocessing import Process
# from flask import Flask, url_for, request, render_template, redirect
from apscheduler.schedulers.background import BackgroundScheduler

sched = BackgroundScheduler()
import openpyxl

###############################################

callback = IBWrapper()
tws = EClientSocket(callback)
host = ""
port = 7496
clientId = 100
create = contract()
callback.initiate_variables()

acc = "DU228380"

commonwealth_curr = ['GBP', 'AUD', 'NZD', 'EUR']


def conn():
    status = tws.isConnected()
    if status == False:
        print(
Пример #40
0
 def connect(self):
     self._wrapper = ReferenceWrapper()
     self._connection = EClientSocket(self._wrapper)
     self._connection.eConnect(IB_HOST, IB_PORT, IB_CLIENT_ID)
Пример #41
0
import sys
import queue
from wrapper import Wrapper
from ib.ext.ScannerSubscription import ScannerSubscription
from ib.ext.EClientSocket import EClientSocket

from utils import Logger

log = Logger('scanner')

msgs = queue.Queue()
wrapper = Wrapper({}, msgs)
connection = EClientSocket(wrapper)

host = "54.197.15.42"
port = 7496

connection.eConnect(host, port, 1)
subscription = ScannerSubscription()
subscription.numberOfRows(100)
subscription.instrument('STK')
subscription.locationCode('STK.US')
subscription.scanCode('TOP_PERC_GAIN')
subscription.abovePrice(1.0)
subscription.aboveVolume(1)
subscription.marketCapBelow(1000000000.0)

ticker_id = 10

log.operation('Requesting subscription')