예제 #1
0
파일: client.py 프로젝트: gazzman/ib
class Client(CallbackBase, EWrapper):
    cached_cds = dict()
    id_to_cd = dict()
    stk_base = {'m_secType': 'STK', 'm_exchange': 'SMART', 'm_currency': 'USD'}
    opt_base = {'m_secType': 'OPT', 'm_exchange': 'SMART', 'm_currency': 'USD'}
    ind_base = {'m_secType': 'IND', 'm_currency': 'USD'}
    fx_base = {'m_secType': 'CASH'}

    def __init__(self, client_id=9):
        self.client_id = client_id
        self.init_logger()
        self.req_id = 0
        self.m_client = EClientSocket(self)
        self.tt = TickType()

    def init_logger(self):
        cid = '%2i' % self.client_id
        logger_fmt = ' '.join(['%(levelno)s, [%(asctime)s #%(process)5i]',
                               'client', cid, '%(levelname)8s: %(message)s'])
        self.logger = logging.getLogger(__name__)
        hdlr = TimedRotatingFileHandler('ib_client.log', when='midnight')
        fmt = logging.Formatter(fmt=logger_fmt)
        hdlr.setFormatter(fmt)
        self.logger.addHandler(hdlr)
        self.logger.setLevel(LOGLEVEL)

    def connect(self, host='', port=7496):
        self.m_client.eConnect(host, port, self.client_id)

    def disconnect(self):
        self.m_client.eDisconnect()
        self.logger.info('Client disconnected')
        id_to_localSymbol = dict()        
        for cid in self.id_to_cd:
            id_to_localSymbol[cid] = self.id_to_cd[cid].m_summary.m_localSymbol
        fnm = 'id_to_localSymbol_%s.pkl' % datetime.now().isoformat()
        pickle.dump(id_to_localSymbol, open(fnm, 'w'))

    def request_contract_details(self, key):
        if key not in self.cached_cds: 
            args = key._asdict()
            if type(key) == ContractId:
                if key[0] in self.id_to_cd: return [self.id_to_cd[key[0]]]
            elif type(key) in (Currency, CurrencyLocal):
                args.update(self.fx_base)
            elif type(key) == Index: 
                args.update(self.ind_base)
            elif type(key) in (Option, OptionLocal): 
                args.update(self.opt_base)
            elif type(key) == Stock: 
                args.update(self.stk_base)
            else:
                errmsg = 'Valid arg types are %s; not %s'
                raise TypeError(errmsg % (', '.join(CONKEYTYPES), str(type(key)))) 
            args = dict([(k, v) for (k, v) in args.items() if v])
            contract = Contract(**args)
            self.req_id += 1
            self.m_client.reqContractDetails(self.req_id, contract)
            while self.req_id not in (self.failed_contracts.keys() + 
                                      self.fulfilled_contracts.keys()): sleep(.5)
            if self.req_id in self.failed_contracts: return None
            self.cached_cds[key] = self.req_cds[self.req_id]
            for cd in self.req_cds[self.req_id]: 
                self.id_to_cd[cd.m_summary.m_conId] = cd
        return self.cached_cds[key]

    # Request data methods
    def request_mkt_data(self, contract, gtick_list='', snapshot=True,
                         fname=None):
        self.req_id += 1
        self.data_requests[self.req_id] = datetime.now()
        if not fname: fname = 'MKT_%i_%s.txt' % (contract.m_conId, gtick_list)
        self.data_req_fnames[self.req_id] = fname
        self.mkt_data[self.req_id] = (contract.m_conId, gtick_list)
        self.m_client.reqMktData(self.req_id, contract, gtick_list, snapshot)
        return self.req_id

    def start_realtime_bars(self, contract, show='TRADES', fname=None):
        if self.too_many_requests():
            self.logger.error('Too many requests.')
            return None
        self.req_id += 1
        self.data_requests[self.req_id] = datetime.now()
        self.realtime_bars[self.req_id] = (contract.m_conId, show)
        if not fname: fname = 'RTBARS_%i_%s.txt' % (contract.m_conId, show)
        self.data_req_fnames[self.req_id] = fname
        self.m_client.reqRealTimeBars(self.req_id, contract, 5, show, 0)
        self.logger.info('Realtime bars started for req_id %i', self.req_id)
        return self.req_id

    def request_historical_data(self, contract, end_time=None, duration='1 D',
                                bar_size='1 min', show='TRADES', fname=None):
        if self.too_many_requests(): return None
        if not end_time: end_time = datetime.now().strftime('%Y%m%d %H:%M:%S')
        self.req_id += 1
        self.data_requests[self.req_id] = datetime.now()
        self.historical_data[self.req_id] = (contract.m_conId, show)
        if not fname: fname = 'HSTBARS_%i_%s.txt' % (contract.m_conId, show)
        self.data_req_fnames[self.req_id] = fname
        self.m_client.reqHistoricalData(self.req_id, contract, end_time,
                                        duration, bar_size, show, 1, 1)
        return self.req_id

    def request_fundamentals(self, contract, report_type, fname=None):
        if self.too_many_requests(): return None
        self.req_id += 1
        self.data_requests[self.req_id] = datetime.now()
        self.fundamentals[self.req_id] = (contract.m_conId, report_type)
        if not fname: fname = 'FND_%i_%s.txt' % (contract.m_conId, report_type)
        self.data_req_fnames[req_id] = fname
        self.m_client.reqFundamentalData(self.req_id, contract, report_type)
        return self.req_id

    # Cancel data methods
    def cancel_mkt_data(self, req_id):
        self.m_client.cancelMktData(req_id)
        del self.mkt_data[req_id]
        self.logger.info('Market data canceled for req_id %i', req_id)
        return True

    def cancel_realtime_bars(self, req_id):
        self.m_client.cancelRealTimeBars(req_id)
        del self.realtime_bars[req_id]
        self.logger.info('Realtime bars canceled for req_id %i', req_id)
        return True

    def cancel_historical_data(self, req_id):
        self.m_client.cancelHistoricalData(req_id)
        del self.historical_data[req_id]
        self.logger.info('Historical data canceled for req_id %i', req_id)
        return True

    def cancel_fundamentals(self, req_id):
        self.m_client.cancelFundamentalData(req_id)
        del self.fundamentals[req_id]
        self.logger.info('Fundamentals canceled for req_id %i', req_id)
        return True

    # Cancel all data methods
    def cancel_all_mkt_data(self):
        bar_ids = self.mkt_data.keys()
        [self.cancel_mkt_data(x) for x in bar_ids]

    def cancel_all_realtime_bars(self):
        bar_ids = self.realtime_bars.keys()
        [self.cancel_realtime_bars(x) for x in bar_ids]

    def cancel_all_historical_data(self):
        historical_ids = self.historical_data.keys()
        [self.cancel_historical_data(x) for x in historical_ids]

    def cancel_all_fundamentals(self):
        fundamental_ids = self.fundamentals.keys()
        [self.cancel_fundamentals(x) for x in fundamental_ids]

    # Orders and Executions methods
    def place_order(self, contract, order):
        order_id = self.nextId
        self.m_client.placeOrder(self.nextId, contract, order)
        self.m_client.reqIds(1)
        while order_id == self.nextId: 
            self.logger.debug('Waiting for next order id')
            sleep(.1)
        return order_id

    def request_open_orders(self):
        self.m_client.reqOpenOrders()        

    def request_all_orders(self):
        self.m_client.reqAllOpenOrders()

    def cancel_order(self, order_id):
        self.m_client.cancelOrder(order_id)
        del self.orders[self.client_id][order_id]

    def cancel_open_orders(self):
        self.request_open_orders()
        if self.client_id not in self.orders:
            self.logger.error('Client has no open orders')
        else:
            order_ids = self.orders[self.client_id].keys()
            [self.cancel_order(x) for x in order_ids
            if self.orders[self.client_id][x]['status'].lower() != 'cancelled']

    def request_executions(self, client_id=None, time=None, symbol=None,
                           sec_type=None, side=None, exchange=None):
        args = {'m_clientId': client_id, 'm_time': time, 'm_symbol': symbol,
                'm_secType': sec_type, 'm_side': side, 'm_exchange': exchange}
        args = dict([(k, v) for (k, v) in args.items() if v])
        self.req_id += 1
        self.m_client.reqExecutions(self.req_id, ExecutionFilter(**args))

    # Helper methods
    def too_many_requests(self):
        since = datetime.now() - timedelta(seconds=600)
        count =len([x for x in self.data_requests.values() if x > since])
        if count >= 60: return True
        else: return False
예제 #2
0
class ClientManager:
    def __init__(self, host="localhost", port=7496, id=1):
        self.host = host
        self.port = port
        self.id = id
        self.subscriptions = {}
        self.subscriptionCounter = 1

        wrapper = Wrapper()
        self.client = EClientSocket(wrapper)
        self.client.eConnect(host, port, id)

        time.sleep(5)

    def subscribeStock(self, symbol):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_exchange = "SMART"
        contract.m_currency = "USD"
        contract.m_secType = "STK"

        self.subscriptions[symbol] = self.subscriptionCounter
        self.client.reqMktData(self.subscriptionCounter, contract, "", False,
                               [])
        self.subscriptionCounter += 1

    def subscribeFX(self, base, priceCur):
        """
        base = base of the currency pair
        priceCur = currency for pricing
        
        ex. USD, JPY means buy/sell USD with price of JPY
        """
        contract = Contract()
        contract.m_symbol = base
        contract.m_exchange = "IDEALPRO"
        contract.m_currency = priceCur
        contract.m_secType = "CASH"

        symbol = ".".join([base, priceCur])

        self.subscriptions[symbol] = self.subscriptionCounter
        self.client.reqMktData(self.subscriptionCounter, contract, "", False,
                               [])
        self.subscriptionCounter += 1

    def unsubscribeStock(self, symbol):

        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.subscriptions.pop(symbol)

    def unsubscribeFX(self, base, priceCur):

        symbol = ".".join([base, priceCur])

        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.subscriptions.pop(symbol)

    def reqCurrentTime(self):

        print self.client.reqCurrentTime()

    def connected(self):

        return self.client.connected
예제 #3
0
class ClientManager:
    """
    object that connects to the TWS gateway --> use an external program to drive this component
    """
    def __init__(self, host="localhost", port=7496, id=1):
        self.host = host
        self.port = port
        self.id = id
        self.subscriptions = {}
        self.tickerMap = {}
        self.funcMap = self._defineFuncMap()
        self.subscriptionCounter = 1

        self.wrapper = Wrapper()
        self.client = EClientSocket(self.wrapper)
        self.client.eConnect(host, port, id)

        time.sleep(5)

    def _defineFuncMap(self):

        funcMap = {
            "reqMktData": self.reqMktData,
            "cancelHistoricalData": self.cancelHistoricalData,
            "cancelRealTimeBars": self.cancelRealTimeBars,
            "reqHistoricalData": self.reqHistoricalData,
            "reqRealTimeBars": self.reqRealTimeBars,
            "reqContractDetails": self.reqContractDetails,
            "reqMktDepth": self.reqMktDepth,
            "cancelMktData": self.cancelMktData,
            "cancelMktDepth": self.cancelMktDepth,
            "exerciseOptions": self.exerciseOptions,
            "placeOrder": self.placeOrder,
            "reqAccountUpdates": self.reqAccountUpdates,
            "reqExecutions": self.reqExecutions,
            "cancelOrder": self.cancelOrder,
            "reqOpenOrders": self.reqOpenOrders,
            "reqIds": self.reqIds,
            "reqNewsBulletins": self.reqNewsBulletins,
            "cancelNewsBulletins": self.cancelNewsBulletins,
            "setServerLogLevel": self.setServerLogLevel,
            "reqAutoOpenOrders": self.reqAutoOpenOrders,
            "reqAllOpenOrders": self.reqAllOpenOrders,
            "reqManagedAccts": self.reqManagedAccts,
            "requestFA": self.requestFA,
            "replaceFA": self.replaceFA,
            "reqFundamentalData": self.reqFundamentalData,
            "cancelFundamentalData": self.cancelFundamentalData,
            "calculateImpliedVolatility": self.calculateImpliedVolatility,
            "cancelCalculateImpliedVolatility":
            self.cancelCalculateImpliedVolatility,
            "calculateOptionPrice": self.calculateOptionPrice,
            "cancelCalculateOptionPrice": self.cancelCalculateOptionPrice,
            "reqGlobalCancel": self.reqGlobalCancel,
            "reqMarketDataType": self.reqMarketDataType,
            "reqPositions": self.reqPositions,
            "cancelPositions": self.cancelPositions,
            "reqAccountSummary": self.reqAccountSummary,
            "cancelAccountSummary": self.cancelAccountSummary,
            "queryDisplayGroups": self.queryDisplayGroups,
            "subscribeToGroupEvents": self.subscribeToGroupEvents,
            "updateDisplayGroup": self.updateDisplayGroup,
            "unsubscribeFromGroupEvents": self.unsubscribeFromGroupEvents,
        }

        return funcMap

    def runCommand(self, **kwargs):
        """
        takes in the commands from the run command function and then calls the appropriate command
        """

        cmd = kwargs["cmd"]
        self.funcMap[cmd](**kwargs)

    def subscribeStock(self, **kwargs):

        symbol = kwargs["symbol"]
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_exchange = "SMART"
        contract.m_currency = "USD"
        contract.m_secType = "STK"

        self.subscriptions[symbol] = self.subscriptionCounter
        self.tickerMap[self.subscriptionCounter] = symbol
        self.client.reqMktData(self.subscriptionCounter, contract, "", False,
                               [])
        self.subscriptionCounter += 1

    def subscribeFX(self, **kwargs):
        """
        base = base of the currency pair
        priceCur = currency for pricing
        
        ex. USD, JPY means buy/sell USD with price of JPY
        """

        base = kwargs["base"]
        priceCur = kwargs["priceCur"]

        contract = Contract()
        contract.m_symbol = base
        contract.m_exchange = "IDEALPRO"
        contract.m_currency = priceCur
        contract.m_secType = "CASH"

        symbol = ".".join([base, priceCur])

        self.subscriptions[symbol] = self.subscriptionCounter
        self.tickerMap[self.subscriptionCounter] = symbol
        self.client.reqMktData(self.subscriptionCounter, contract, "", False,
                               [])
        self.subscriptionCounter += 1

    def unsubscribeStock(self, **kwargs):

        symbol = kwargs["symbol"]

        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.tickerMap.pop(self.subscriptions.pop(symbol))

    def unsubscribeFX(self, **kwargs):

        base = kwargs["base"]
        priceCur = kwargs["priceCur"]
        symbol = ".".join([base, priceCur])

        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.tickerMap.pop(self.subscriptions.pop(symbol))

    ###Helper functions
    def _createContract(self, **kwargs):

        contract = Contract()
        if "contract_conId" in kwargs:
            contract.m_conId = kwargs["contract_conId"]
        if "contract_symbol" in kwargs:
            contract.m_symbol = kwargs["contract_symbol"]
        if "contract_secType" in kwargs:
            contract.m_secType = kwargs["contract_secType"]
        if "contract_expiry" in kwargs:
            contract.m_expiry = kwargs["contract_expiry"]
        if "contract_strike" in kwargs:
            contract.m_strike = kwargs["contract_strike"]
        if "contract_right" in kwargs:
            contract.m_right = kwargs["contract_right"]
        if "contract_multiplier" in kwargs:
            contract.m_multiplier = kwargs["contract_multiplier"]
        if "contract_exchange" in kwargs:
            contract.m_exchange = kwargs["contract_exchange"]

        if "contract_currency" in kwargs:
            contract.m_currency = kwargs["contract_currency"]
        if "contract_localSymbol" in kwargs:
            contract.m_localSymbol = kwargs["contract_localSymbol"]
        if "contract_tradingClass" in kwargs:
            contract.m_tradingClass = kwargs["contract_tradingClass"]
        if "contract_primaryExch" in kwargs:
            contract.m_primaryExch = kwargs[
                "contract_primaryExch"]  # pick a non-aggregate (ie not the SMART exchange) exchange that the contract trades on.  DO NOT SET TO SMART.
        if "contract_includeExpired" in kwargs:
            contract.m_includeExpired = kwargs[
                "contract_includeExpired"]  # can not be set to true for contracts.

        if "contract_secIdType" in kwargs:
            contract.m_secIdType = kwargs[
                "contract_secIdType"]  # CUSIP;SEDOL;ISIN;RIC
        if "contract_secId" in kwargs:
            contract.m_secId = kwargs["contract_secId"]

        return contract

    def _createOrder(self, **kwargs):

        order = Order()

        # main order fields
        if "order_orderId" in kwargs: order.m_orderId = kwargs["order_orderId"]
        order.m_clientId = self.id
        if "order_permId" in kwargs: order.m_permId = kwargs["order_permId"]
        if "order_action" in kwargs:
            order.m_action = kwargs[
                "order_action"]  #values are BUY, SELL, SSHORT
        if "order_totalQuantity" in kwargs:
            order.m_totalQuantity = kwargs["order_totalQuantity"]
        if "order_orderType" in kwargs:
            order.m_orderType = kwargs["order_orderType"]
        if "order_lmtPrice" in kwargs:
            order.m_lmtPrice = kwargs["order_lmtPrice"]
        if "order_auxPrice" in kwargs:
            order.m_auxPrice = kwargs["order_auxPrice"]

        # extended order fields
        if "order_tif" in kwargs:
            order.m_tif = kwargs[
                "order_tif"]  # "Time in Force" - DAY, GTC, etc.
        if "order_activeStartTime" in kwargs:
            order.m_activeStartTime = kwargs[
                "order_activeStartTime"]  # GTC orders
        if "order_activeStopTime" in kwargs:
            order.m_activeStopTime = kwargs[
                "order_activeStopTime"]  # GTC orders YYYYMMDD hh:mm:ss (optional time zone)
        if "order_ocaGroup" in kwargs:
            order.m_ocaGroup = kwargs[
                "order_ocaGroup"]  # one cancels all group name
        if "order_ocaType" in kwargs:
            order.m_ocaType = kwargs[
                "order_ocaType"]  # 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK
        if "order_orderRef" in kwargs:
            order.m_orderRef = kwargs["order_orderRef"]
        if "order_transmit" in kwargs:
            order.m_transmit = kwargs[
                "order_transmit"]  # if false, order will be created but not transmited
        if "order_parentId" in kwargs:
            order.m_parentId = kwargs[
                "order_parentId"]  # Parent order Id, to associate Auto STP or TRAIL orders with the original order.
        if "order_blockOrder" in kwargs:
            order.m_blockOrder = kwargs["order_blockOrder"]
        if "order_sweepToFill" in kwargs:
            order.m_sweepToFill = kwargs["order_sweepToFill"]
        if "order_displaySize" in kwargs:
            order.m_displaySize = kwargs["order_displaySize"]
        if "order_triggerMethod" in kwargs:
            order.m_triggerMethod = kwargs[
                "order_triggerMethod"]  # 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-point
        if "order_outsideRth" in kwargs:
            order.m_outsideRth = kwargs["order_outsideRth"]
        if "order_hidden" in kwargs: order.m_hidden = kwargs["order_hidden"]
        if "order_goodAfterTime" in kwargs:
            order.m_goodAfterTime = kwargs[
                "order_goodAfterTime"]  # FORMAT: 20060505 08:00:00 {time zone}
        if "order_goodTillDate" in kwargs:
            order.m_goodTillDate = kwargs[
                "order_goodTillDate"]  # FORMAT: 20060505 08:00:00 {time zone} order must be GTD
        if "order_overridePercentageConstraints" in kwargs:
            order.m_overridePercentageConstraints = kwargs[
                "order_overridePercentageConstraints"]
        if "order_rule80A" in kwargs:
            order.m_rule80A = kwargs[
                "order_rule80A"]  # Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
        if "order_allOrNone" in kwargs:
            order.m_allOrNone = kwargs["order_allOrNone"]
        if "order_minQty" in kwargs: order.m_minQty = kwargs["order_minQty"]
        if "order_percentOffset" in kwargs:
            order.m_percentOffset = kwargs[
                "order_percentOffset"]  # REL orders only specify the decimal, e.g. .04 not 4
        if "order_trailStopPrice" in kwargs:
            order.m_trailStopPrice = kwargs[
                "order_trailStopPrice"]  # for TRAILLIMIT orders only
        if "order_trailingPercent" in kwargs:
            order.m_trailingPercent = kwargs[
                "order_trailingPercent"]  # specify the percentage, e.g. 3, not .03

        # Financial advisors only
        if "order_faGroup" in kwargs: order.m_faGroup = kwargs["order_faGroup"]
        if "order_faProfile" in kwargs:
            order.m_faProfile = kwargs["order_faProfile"]
        if "order_faMethod" in kwargs:
            order.m_faMethod = kwargs["order_faMethod"]
        if "order_faPercentage" in kwargs:
            order.m_faPercentage = kwargs["order_faPercentage"]

        # Institutional orders only
        if "order_openClose" in kwargs:
            order.m_openClose = kwargs["order_openClose"]  # O=Open, C=Close
        if "order_origin" in kwargs:
            order.m_origin = kwargs["order_origin"]  # 0=Customer, 1=Firm
        if "order_shortSaleSlot" in kwargs:
            order.m_shortSaleSlot = kwargs[
                "order_shortSaleSlot"]  # 1 if you hold the shares, 2 if they will be delivered from elsewhere.  Only for Action="SSHORT
        if "order_designatedLocation" in kwargs:
            order.m_designatedLocation = kwargs[
                "order_designatedLocation"]  # set when slot=2 only.
        if "order_exemptCode" in kwargs:
            order.m_exemptCode = kwargs["order_exemptCode"]

        # SMART routing only
        if "order_discretionaryAmt" in kwargs:
            order.m_discretionaryAmt = kwargs["order_discretionaryAmt"]
        if "order_eTradeOnly" in kwargs:
            order.m_eTradeOnly = kwargs["order_eTradeOnly"]
        if "order_firmQuoteOnly" in kwargs:
            order.m_firmQuoteOnly = kwargs["order_firmQuoteOnly"]
        if "order_nbboPriceCap" in kwargs:
            order.m_nbboPriceCap = kwargs["order_nbboPriceCap"]
        if "order_optOutSmartRouting" in kwargs:
            order.m_optOutSmartRouting = kwargs["order_optOutSmartRouting"]

        # BOX or VOL ORDERS ONLY
        if "order_auctionStrategy" in kwargs:
            order.m_auctionStrategy = kwargs[
                "order_auctionStrategy"]  # 1=AUCTION_MATCH, 2=AUCTION_IMPROVEMENT, 3=AUCTION_TRANSPARENT

        # BOX ORDERS ONLY
        if "order_startingPrice" in kwargs:
            order.m_startingPrice = kwargs["order_startingPrice"]
        if "order_stockRefPrice" in kwargs:
            order.m_stockRefPrice = kwargs["order_stockRefPrice"]
        if "order_delta" in kwargs: order.m_delta = kwargs["order_delta"]

        # pegged to stock or VOL orders
        if "order_stockRangeLower" in kwargs:
            order.m_stockRangeLower = kwargs["order_stockRangeLower"]
        if "order_stockRangeUpper" in kwargs:
            order.m_stockRangeUpper = kwargs["order_stockRangeUpper"]

        # VOLATILITY ORDERS ONLY
        if "order_volatility" in kwargs:
            order.m_volatility = kwargs[
                "order_volatility"]  # enter percentage not decimal, e.g. 2 not .02
        if "order_volatilityType" in kwargs:
            order.m_volatilityType = kwargs[
                "order_volatilityType"]  # 1=daily, 2=annual
        if "order_continuousUpdate" in kwargs:
            order.m_continuousUpdate = kwargs["order_continuousUpdate"]
        if "order_referencePriceType" in kwargs:
            order.m_referencePriceType = kwargs[
                "order_referencePriceType"]  # 1=Bid/Ask midpoint, 2 = BidOrAsk
        if "order_deltaNeutralOrderType" in kwargs:
            order.m_deltaNeutralOrderType = kwargs[
                "order_deltaNeutralOrderType"]
        if "order_deltaNeutralAuxPrice" in kwargs:
            order.m_deltaNeutralAuxPrice = kwargs["order_deltaNeutralAuxPrice"]
        if "order_deltaNeutralConId" in kwargs:
            order.m_deltaNeutralConId = kwargs["order_deltaNeutralConId"]
        if "order_deltaNeutralSettlingFirm" in kwargs:
            order.m_deltaNeutralSettlingFirm = kwargs[
                "order_deltaNeutralSettlingFirm"]
        if "order_deltaNeutralClearingAccount" in kwargs:
            order.m_deltaNeutralClearingAccount = kwargs[
                "order_deltaNeutralClearingAccount"]
        if "order_deltaNeutralClearingIntent" in kwargs:
            order.m_deltaNeutralClearingIntent = kwargs[
                "order_deltaNeutralClearingIntent"]
        if "order_deltaNeutralOpenClose" in kwargs:
            order.m_deltaNeutralOpenClose = kwargs[
                "order_deltaNeutralOpenClose"]
        if "order_deltaNeutralShortSale" in kwargs:
            order.m_deltaNeutralShortSale = kwargs[
                "order_deltaNeutralShortSale"]
        if "order_deltaNeutralShortSaleSlot" in kwargs:
            order.m_deltaNeutralShortSaleSlot = kwargs[
                "order_deltaNeutralShortSaleSlot"]
        if "order_deltaNeutralDesignatedLocation" in kwargs:
            order.m_deltaNeutralDesignatedLocation = kwargs[
                "order_deltaNeutralDesignatedLocation"]

        # COMBO ORDERS ONLY
        if "order_basisPoints" in kwargs:
            order.m_basisPoints = kwargs[
                "order_basisPoints"]  # EFP orders only, download only
        if "order_basisPointsType" in kwargs:
            order.m_basisPointsType = kwargs[
                "order_basisPointsType"]  # EFP orders only, download only

        # SCALE ORDERS ONLY
        if "order_scaleInitLevelSize" in kwargs:
            order.m_scaleInitLevelSize = kwargs["order_scaleInitLevelSize"]
        if "order_scaleSubsLevelSize" in kwargs:
            order.m_scaleSubsLevelSize = kwargs["order_scaleSubsLevelSize"]
        if "order_scalePriceIncrement" in kwargs:
            order.m_scalePriceIncrement = kwargs["order_scalePriceIncrement"]
        if "order_scalePriceAdjustValue" in kwargs:
            order.m_scalePriceAdjustValue = kwargs[
                "order_scalePriceAdjustValue"]
        if "order_scalePriceAdjustInterval" in kwargs:
            order.m_scalePriceAdjustInterval = kwargs[
                "order_scalePriceAdjustInterval"]
        if "order_scaleProfitOffset" in kwargs:
            order.m_scaleProfitOffset = kwargs["order_scaleProfitOffset"]
        if "order_scaleAutoReset" in kwargs:
            order.m_scaleAutoReset = kwargs["order_scaleAutoReset"]
        if "order_scaleInitPosition" in kwargs:
            order.m_scaleInitPosition = kwargs["order_scaleInitPosition"]
        if "order_scaleInitFillQty" in kwargs:
            order.m_scaleInitFillQty = kwargs["order_scaleInitFillQty"]
        if "order_scaleRandomPercent" in kwargs:
            order.m_scaleRandomPercent = kwargs["order_scaleRandomPercent"]
        if "order_scaleTable" in kwargs:
            order.m_scaleTable = kwargs["order_scaleTable"]

        # HEDGE ORDERS ONLY
        if "order_hedgeType" in kwargs:
            order.m_hedgeType = kwargs[
                "order_hedgeType"]  # 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair
        if "order_hedgeParam" in kwargs:
            order.m_hedgeParam = kwargs[
                "order_hedgeParam"]  # beta value for beta hedge (in range 0-1), ratio for pair hedge

        # Clearing info
        if "order_account" in kwargs:
            order.m_account = kwargs["order_account"]  # IB account
        if "order_settlingFirm" in kwargs:
            order.m_settlingFirm = kwargs["order_settlingFirm"]
        if "order_clearingAccount" in kwargs:
            order.m_clearingAccount = kwargs[
                "order_clearingAccount"]  # True beneficiary of the order
        if "order_clearingIntent" in kwargs:
            order.m_clearingIntent = kwargs[
                "order_clearingIntent"]  # "" (Default), "IB", "Away", "PTA" (PostTrade)

        # ALGO ORDERS ONLY
        if "order_algoStrategy" in kwargs:
            order.m_algoStrategy = kwargs["order_algoStrategy"]
        if "order_algoParams" in kwargs:
            order.m_algoParams = kwargs["order_algoParams"]

        # What-if
        if "order_whatIf" in kwargs: order.m_whatIf = kwargs["order_whatIf"]

        # Not Held
        if "order_notHeld" in kwargs: order.m_notHeld = kwargs["order_notHeld"]

        # Smart combo routing params
        if "order_smartComboRoutingParams" in kwargs:
            order.m_smartComboRoutingParams = kwargs[
                "order_smartComboRoutingParams"]

        # order combo legs
        #if "order_orderComboLegs" in kwargs: order.m_orderComboLegs = kwargs["order_orderComboLegs"] = new Vector<OrderComboLeg>()

        # order misc options
        if "order_orderMiscOptions" in kwargs:
            order.m_orderMiscOptions = kwargs["order_orderMiscOptions"]

        return order

    def connected(self, **kwargs):
        return self.client.connected

    def reqCurrentTime(self, **kwargs):
        return self.client.reqCurrentTime()

    def faMsgTypeName(self, **kwargs):
        return self.client.faMsgTypeName(int)

    def serverVersion(self, **kwargs):
        return self.client.serverVersion()

    def TwsConnectionTime(self, **kwargs):
        return self.client.TwsConnectionTime()

    def wrapper(self, **kwargs):
        return self.client.wrapper()

    def reader(self, **kwargs):
        return self.client.reader()

    def isConnected(self, **kwargs):
        return self.client.isConnected()

    def eConnect(self, **kwargs):

        host = kwargs["host"]
        port = kwargs["port"]
        id = kwargs["id"]
        self.client.eConnect(host, port, id)

#     def EClientSocket(self, **kwargs):
#         self.client.EClientSocket(AnyWrapper)
#
#
#     def eConnect(self, **kwargs):
#         self.client.eConnect(String, int, int, boolean)
#
#     def createReader(self, **kwargs):
#         self.client.createReader(EClientSocket, DataInputStream)
#
#     def eConnect(self, **kwargs):
#         self.client.eConnect(Socket, int)
#
#     def eConnect(self, **kwargs):
#         self.client.eConnect(Socket)
#

    def eDisconnect(self, **kwargs):
        self.client.eDisconnect()

###client functions for call backs

#Not using scanners at the moment
#     def cancelScannerSubscription(self, **kwargs):
#         subscriptionId = kwargs["id"]
#         self.client.cancelScannerSubscription(int)
#
#     def reqScannerParameters(self, **kwargs):
#         self.client.reqScannerParameters()
#
#     def reqScannerSubscription(self, **kwargs):
#         self.client.reqScannerSubscription(int, ScannerSubscription, Vector<TagValue>)

    def reqMktData(self, **kwargs):
        """
        function to request market data
        """
        #contract information:

        requestId = kwargs["tickerId"]
        contract = self._createContract(**kwargs)

        tickList = kwargs.get("tickList", "")
        snapshot = kwargs.get("snapshot", False)

        self.client.reqMktData(requestId, contract, tickList, snapshot, [])

    def cancelHistoricalData(self, **kwargs):
        requestId = kwargs["tickerId"]
        self.client.cancelHistoricalData(requestId)

    def cancelRealTimeBars(self, **kwargs):
        requestId = kwargs["tickerId"]
        self.client.cancelRealTimeBars(requestId)

    def reqHistoricalData(self, **kwargs):
        requestId = kwargs["tickerId"]
        contract = self._createContratct()
        endDateTime = kwargs["endDateTime"]  #format of yyyymmdd HH:mm:ss ttt
        durationStr = kwargs[
            "durationStr"]  #can look like 1000 S (int [S D W])
        barSizeSetting = kwargs[
            "barSizeSetting"]  #valid values are: 1 sec|5 secs|15 secs|30 secs|1 min|2 mins|3 mins|5 mins|15 mins|30 mins|1 hour|1 day
        whatToShow = kwargs[
            "whatToShow"]  #valid values are: TRADES|MIDPOINT|BID|ASK|BID_ASK|HISTORICAL_VOLATILITY|OPTION_IMPLIED_VOLATILITY
        useRTH = bool(
            kwargs["useRTH"])  #0 for all data, 1 for market hours only
        formatDate = kwargs[
            "formatDate"]  #1 for yyyymmdd{space}{space}hh:mm:dd, 2 for timestamp value
        self.client.reqHistoricalData(requestId, contract, endDateTime,
                                      durationStr, barSizeSetting, whatToShow,
                                      useRTH, formatDate, [])

    def reqRealTimeBars(self, **kwargs):
        requestId = kwargs["tickerId"]
        contract = self._createContratct()
        barSize = 5
        whatToShow = kwargs[
            "whatToShow"]  #valid values are: TRADES|MIDPOINT|BID|ASK|BID_ASK|HISTORICAL_VOLATILITY|OPTION_IMPLIED_VOLATILITY
        useRTH = bool(
            kwargs["useRTH"])  #0 for all data, 1 for market hours only
        self.client.reqRealTimeBars(requestId, contract, barSize, whatToShow,
                                    useRTH, [])

    def reqContractDetails(self, **kwargs):

        requestId = kwargs["reqId"]
        contract = self._createContract(**kwargs)

        self.client.reqContractDetails(requestId, contract)

    def reqMktDepth(self, **kwargs):

        requestId = kwargs["tickerId"]
        contract = self._createContract(**kwargs)

        depthRows = kwargs.get("depthRows", 1)

        self.client.reqMktDepth(requestId, contract, depthRows, [])

    def cancelMktData(self, **kwargs):
        """
        cancels the market data request
        """

        requestId = kwargs["tickerId"]
        self.client.cancelMktData(requestId)

    def cancelMktDepth(self, **kwargs):
        requestId = kwargs["tickerId"]
        self.client.cancelMktDepth(requestId)

    def exerciseOptions(self, **kwargs):

        requestId = kwargs["tickerId"]
        contract = self._createContract(**kwargs)
        exerciseAction = kwargs["exercise_action"]
        exerciseQty = kwargs["exercise_qty"]
        account = ""
        override = 0
        #wonder what exchange this should be though
        if contract.m_exchange == "SMART":
            raise ("Exchange cannot be smart")
        self.client.exerciseOptions(requestId, contract, exerciseAction,
                                    exerciseQty, account, override)

    def placeOrder(self, **kwargs):
        requestId = kwargs["id"]
        contract = self._createContract(**kwargs)
        order = self._createOrder(**kwargs)

        self.client.placeOrder(requestId, contract, order)

    def reqAccountUpdates(self, **kwargs):

        subscribe = bool(kwargs["subscribe"])
        acctCode = kwargs["acctCode"]
        self.client.reqAccountUpdates(subscribe, acctCode)

    def reqExecutions(self, **kwargs):

        requestId = kwargs["reqId"]
        executionFilter = ExecutionFilter()
        self.client.reqExecutions(requestId, executionFilter)

    def cancelOrder(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelOrder(requestId)

    def reqOpenOrders(self, **kwargs):
        self.client.reqOpenOrders()

    def reqIds(self, **kwargs):
        numIds = kwargs["numIds"]
        self.client.reqIds(numIds)

    def reqNewsBulletins(self, **kwargs):
        news = kwargs["news"]
        self.client.reqNewsBulletins(news)

    def cancelNewsBulletins(self, **kwargs):
        self.client.cancelNewsBulletins()

    def setServerLogLevel(self, **kwargs):
        #     1 = SYSTEM
        #     2 = ERROR
        #     3 = WARNING
        #     4 = INFORMATION
        #     5 = DETAIL

        logLevel = kwargs["logLevel"]
        self.client.setServerLogLevel(logLevel)

    def reqAutoOpenOrders(self, **kwargs):
        #If set to TRUE, newly created TWS orders will be implicitly associated with the client. If set to FALSE, no association will be made.
        bAutoBind = kwargs["bAutoBind"]
        self.client.reqAutoOpenOrders(bAutoBind)

    def reqAllOpenOrders(self, **kwargs):
        self.client.reqAllOpenOrders()

    def reqManagedAccts(self, **kwargs):
        self.client.reqManagedAccts()

    def requestFA(self, **kwargs):

        #     1 = GROUPS
        #     2 = PROFILE
        #     3 = ACCOUNT ALIASES
        faDataType = kwargs["faDataType"]
        self.client.requestFA(faDataType)

    def replaceFA(self, **kwargs):
        #Call this function to modify FA configuration information from the API. Note that this can also be done manually in TWS itself.
        faDataType = kwargs["faDataType"]
        cxml = kwargs["cxml"]
        self.client.replaceFA(faDataType, cxml)

    def reqFundamentalData(self, **kwargs):

        #    report types
        #     ReportSnapshot (company overview)
        #     ReportsFinSummary (financial summary)
        #     ReportRatios (financial ratios)
        #     ReportsFinStatements (financial statements)
        #     RESC (analyst estimates)
        #     CalendarReport (company calendar)

        requestId = kwargs["reqId"]
        contract = self._createContract(**kwargs)
        reportType = kwargs["reportType"]
        self.client.reqFundamentalData(requestId, contract, reportType)

    def cancelFundamentalData(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelFundamentalData(requestId)

    def calculateImpliedVolatility(self, **kwargs):
        requestId = kwargs["reqId"]
        contract = self._createContract(**kwargs)
        optionPrice = kwargs["optionPrice"]
        underPrice = kwargs["underPrice"]

        self.client.calculateImpliedVolatility(requestId, contract,
                                               optionPrice, underPrice)

    def cancelCalculateImpliedVolatility(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelCalculateImpliedVolatility(requestId)

    def calculateOptionPrice(self, **kwargs):
        requestId = kwargs["requestId"]
        contract = self._createContract(**kwargs)
        volatility = kwargs["volatility"]
        underPrice = kwargs["underPrice"]

        self.client.calculateOptionPrice(requestId, contract, volatility,
                                         underPrice)

    def cancelCalculateOptionPrice(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelCalculateOptionPrice(requestId)

    def reqGlobalCancel(self, **kwargs):
        self.client.reqGlobalCancel()

    def reqMarketDataType(self, **kwargs):
        #1 for real-time streaming market data or 2 for frozen market data.
        marketDataType = kwargs["marketDataType"]
        self.client.reqMarketDataType(marketDataType)

    def reqPositions(self, **kwargs):
        self.client.reqPositions()

    def cancelPositions(self, **kwargs):
        self.client.cancelPositions()

    def reqAccountSummary(self, **kwargs):
        #This request can only be made when connected to a Financial Advisor (FA) account.
        requestId = kwargs["reqId"]
        group = kwargs["group"]
        tags = kwargs["tags"]
        self.client.reqAccountSummary(requestId, group, tags)

    def cancelAccountSummary(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelAccountSummary(requestId)


#     def verifyRequest(self, **kwargs):
#         self.client.verifyRequest(String, String)
#
#     def verifyMessage(self, **kwargs):
#         self.client.verifyMessage(String)

    def queryDisplayGroups(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.queryDisplayGroups(requestId)

    def subscribeToGroupEvents(self, **kwargs):
        #groupId =      The ID of the group, currently it is a number from 1 to 7. This is the display group subscription request sent by the API to TWS.
        requestId = kwargs["reqId"]
        groupId = kwargs["groupId"]
        self.client.subscribeToGroupEvents(requestId, groupId)

    def updateDisplayGroup(self, **kwargs):
        #     contractInfo:
        #     none = empty selection
        #     contractID@exchange – any non-combination contract. Examples: 8314@SMART for IBM SMART; 8314@ARCA for IBM @ARCA.
        #     combo = if any combo is selected.
        requestId = kwargs["reqId"]
        contractInfo = kwargs["contractInfo"]
        self.client.updateDisplayGroup(requestId, contractInfo)

    def unsubscribeFromGroupEvents(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.unsubscribeFromGroupEvents(requestId)

    def getData(self):
        """
        called to get information out of the queue in the wrapper for information passing
        """
        data = self.wrapper.queue.get()

        #this is specialized code to deal with mapping of ids to symbol information
        #work to create something more natural that is layer or at a different level?
        data["tickerId"] = self.tickerMap[data["tickerId"]]
        return data
예제 #4
0
class ClientManager:
    
    def __init__(self, host="localhost", port=7496, id=1):
        self.host=host
        self.port=port
        self.id=id
        self.subscriptions = {}
        self.tickerMap = {}
        self.subscriptionCounter = 1
        
        self.wrapper = Wrapper()
        self.client=EClientSocket(self.wrapper)
        self.client.eConnect(host, port, id)
        
        time.sleep(5)
        
    def subscribeStock(self, symbol):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_exchange = "SMART"
        contract.m_currency = "USD"
        contract.m_secType = "STK"

        self.subscriptions[symbol] = self.subscriptionCounter
        self.tickerMap[self.subscriptionCounter] = symbol
        self.client.reqMktData(self.subscriptionCounter, contract, "", False, [])
        self.subscriptionCounter+=1

    def subscribeFX(self, base, priceCur):
        """
        base = base of the currency pair
        priceCur = currency for pricing
        
        ex. USD, JPY means buy/sell USD with price of JPY
        """
        contract = Contract()
        contract.m_symbol = base
        contract.m_exchange = "IDEALPRO"
        contract.m_currency = priceCur
        contract.m_secType = "CASH"
        
        symbol = ".".join([base, priceCur])

        self.subscriptions[symbol] = self.subscriptionCounter
        self.tickerMap[self.subscriptionCounter] = symbol
        self.client.reqMktData(self.subscriptionCounter, contract, "", False, [])
        self.subscriptionCounter+=1        
        
    def unsubscribeStock(self, symbol):
        
        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.tickerMap.pop(self.subscriptions.pop(symbol))
        
    def unsubscribeFX(self, base, priceCur):
        
        symbol = ".".join([base, priceCur])
        
        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.tickerMap.pop(self.subscriptions.pop(symbol))
            
    def reqCurrentTime(self):
        
        print self.client.reqCurrentTime()
        
    def connected(self):
        
        return self.client.connected
    
    def getData(self):
        
        data = self.wrapper.queue.get()
        data["tickerId"] = self.tickerMap[data["tickerId"]]
        return data
예제 #5
0
class TWSEngine(stomp.ConnectionListener):
    """handle the trading related requests"""
    def __init__(self, host='127.0.0.1', port=7496, client_id=0):
        self.mgw = None
        self.host = host
        self.port = port
        self.client_id = client_id
        self.response_wrapper = ResponseWrapper()
        self.connection = EClientSocket(self.response_wrapper)
        self.response_wrapper.handler = self
        self.requested_market_data = {} # memory in case of connection loss
        
    def start(self):
        self.mgw.start() # start the messaging gateway
        
    def exit(self):
        if self.connection.connected: self.disconnect()
        self.mgw.unsubscribe('/queue/request')
        self.mgw.disconnect()
    
    def connect(self):
        log.info("connecting to TWS...")
        self.connection.eConnect(self.host, self.port, self.client_id)
        
    def disconnect(self):
        log.info("disconnecting IB gateway...")
        self.connection.eDisconnect()
        
    # stomp connection listener methods
    def on_connected(self, headers, body):
        self.mgw.subscribe('/queue/request')
        # connect and request the account, order, and portfolio updates
        self.connect()
        tries = 10
        while not self.connection.connected:
            time.sleep(5)
            if not self.connection.connected:
                if tries == 0:
                    log.error("trading gateway connection failed")
                    return
                log.error("tws connection trying again...")
                self.connect()
                tries -= 1
            else:
                break
        log.info("connection to TWS established")
        self.account_data_request()
        
    def on_message(self, headers, body):
        try:
            message = message_decode(body)
        except:
            log.error("unable to decode message body: %s" % body)
        else:
            self.handle_incoming(message)
        
    # message handler methods
    def handle_outgoing(self, obj, topic_or_queue='/topic/account'):
        message = message_encode(obj)
        log.debug("send: %r to '%s'" % (obj, topic_or_queue))
        self.mgw.send(topic_or_queue, message)
        
    def handle_incoming(self, message):
        log.debug("recv: %r" % message)
        mtype = message['type']
        method = getattr(self, "process_%s" % mtype, None)
        if not method: 
            log.error("no processor found for message type: %s" % mtype)
        else:
            method(message)
        
    def handle_tick(self, tick):
        queue = '/queue/ticks/%s' % tick['id']
        self.handle_outgoing(tick, queue)
        
    def handle_message_code(self, id, code, m):
        critical = [1100, 1300]
        error = [1101, 2100, 2101, 2103]
        warning = [2102, 2105]
        if id != -1:
            message = "id: %s, code: %s, message: %s" % (id, code, m)
        else:
            message = "code: %s, message: %s" % (code, m)
        if code in critical: log.critical(message)
        elif code <= 1000 or code in error:
            if code in [165, 202]: log.info(message)
            else: log.error(message)
        elif code in warning: log.warning(message)
        else: log.info(message)
        # code 1101: Connectivity between IB and TWS has been restored- data lost.*
        # *Market and account data subscription requests must be resubmitted
        # code 2100: New account data requested from TWS.  
        # API client has been unsubscribed from account data. **
        # **Account data subscription requests must be resubmitted
        if code in [1101, 2100]:
            self.account_data_request()
            if code == 1101:
                # TODO: PM: let client handle this (also with historical gap fill)
                # e.g. send a message with type 'error' to the /topic/account with the code 1101
                for id, contract in self.requested_market_data.items():
                    self.tick_request(id, contract)
            
    # incoming message processors   
    def process_place_order(self, message): 
        message_contract = message['contract']
        message_order = message['order']
        order_id = message_order['order_id']
        contract = self.create_contract(message_contract)
        order = self.create_order(message_order)
        self.place_order(order_id, contract, order)
        
    def process_cancel_order(self, message): 
        order_id = message['order_id']
        self.cancel_order(order_id)
        
    def process_historical_data_request(self, message):
        ticker_id = message['ticker_id']
        message_contract = message['contract']
        self.historical_data_request(ticker_id, message_contract)
        
    def process_tick_request(self, message):
        ticker_id = message['ticker_id']
        message_contract = message['contract']
        self.tick_request(ticker_id, message_contract)
        
    def process_cancel_market_data(self, message):
        ticker_id = message['ticker_id']
        self.cancel_market_data(ticker_id)
        
    # order methods
    def create_contract(self, c):
        contract = Contract()
        contract.m_symbol = c['symbol']
        contract.m_secType = c['secType']
        contract.m_expiry = c['expiry']
        contract.m_exchange = c['exchange']
        contract.m_currency = c['currency']
        return contract    
    
    def create_order(self, o):
        order = Order()
        order.m_orderId = o['order_id']
        order.m_clientId = self.client_id
        order.m_action = o['action']
        order.m_totalQuantity = o['quantity']
        if o['type'] == 'MKT':
            order.m_orderType = o['type'] # guaranteed execution
            order.m_lmtPrice = 0
            order.m_auxPrice = 0
        elif o['type'] == 'LMT_entry':
            order.m_orderType = o['type'][:3]
            order.m_lmtPrice = o['limit']
            order.m_auxPrice = 0
            order.m_tif = 'GTD' # TWS timeout
            gtt = o['trigger_timestamp'] + 300 # valid for 5 minutes
            enddate = datetime.fromtimestamp(gtt)
            # TWS expects date format: YYYYMMDD hh:mm:ss in the current
            # system's timezone
            gtd = datetime.strftime(enddate, "%Y%m%d %H:%M:%S")
            order.m_goodTillDate = gtd
        elif o['type'] == 'LMT_exit':
            # set group
            order.m_orderType = o['type'][:3]
            order.m_lmtPrice = o['limit']
            order.m_auxPrice = 0
            order.m_ocaGroup = o['ocagroup']
        elif o['type'] == 'STP':
            order.m_orderType = o['type']
            order.m_lmtPrice = 0
            order.m_auxPrice = o['stop']
            order.m_ocaGroup = o['ocagroup']
        else:
            log.error("invalid order type: %s" % o['type'])
        return order
        
    def place_order(self, order_id, contract, order):
        self.connection.placeOrder(order_id, contract, order)
        
    def cancel_order(self, order_id):
        self.connection.cancelOrder(order_id)
    
    # TWS request methods
    def account_data_request(self):
        self.connection.reqAccountUpdates(True, "")
        self.connection.reqOpenOrders()
    
    def historical_data_request(self, ticker_id, ticker_contract, 
            duration="2 D", bar_size="1 min"):
        contract = self.create_contract(ticker_contract)
        now = datetime.now()
        enddate = now + timedelta(hours=1)
        enddatestr = enddate.strftime("%Y%m%d %H:%M:%S")
        self.connection.reqHistoricalData(ticker_id, contract, enddatestr, 
            duration, bar_size, "TRADES", 0, 2)
        
    def tick_request(self, ticker_id, ticker_contract):
        contract = self.create_contract(ticker_contract)
        self.connection.reqMktData(ticker_id, contract, None)
        self.requested_market_data[ticker_id] = ticker_contract
        
    def cancel_market_data(self, ticker_id):
        if self.requested_market_data.get(ticker_id, None):
            self.connection.cancelMktData(ticker_id)
            del self.requested_market_data[ticker_id]
예제 #6
0
class ClientManager:
    """
    object that connects to the TWS gateway --> use an external program to drive this component
    """
    
    def __init__(self, host="localhost", port=7496, id=1):
        self.host=host
        self.port=port
        self.id=id
        self.subscriptions = {}
        self.tickerMap = {}
        self.funcMap = self._defineFuncMap()
        self.subscriptionCounter = 1
        
        self.wrapper = Wrapper()
        self.client=EClientSocket(self.wrapper)
        self.client.eConnect(host, port, id)
        
        time.sleep(5)
    
    def _defineFuncMap(self):
        
        funcMap = {
                    "reqMktData": self.reqMktData,
                    "cancelHistoricalData": self.cancelHistoricalData,
                    "cancelRealTimeBars": self.cancelRealTimeBars,
                    "reqHistoricalData": self.reqHistoricalData,
                    "reqRealTimeBars": self.reqRealTimeBars,
                    "reqContractDetails": self.reqContractDetails,
                    "reqMktDepth": self.reqMktDepth,
                    "cancelMktData": self.cancelMktData,
                    "cancelMktDepth": self.cancelMktDepth,
                    "exerciseOptions": self.exerciseOptions,
                    "placeOrder": self.placeOrder,
                    "reqAccountUpdates": self.reqAccountUpdates,
                    "reqExecutions": self.reqExecutions,
                    "cancelOrder": self.cancelOrder,
                    "reqOpenOrders": self.reqOpenOrders,
                    "reqIds": self.reqIds,
                    "reqNewsBulletins": self.reqNewsBulletins,
                    "cancelNewsBulletins": self.cancelNewsBulletins,
                    "setServerLogLevel": self.setServerLogLevel,
                    "reqAutoOpenOrders": self.reqAutoOpenOrders,
                    "reqAllOpenOrders": self.reqAllOpenOrders,
                    "reqManagedAccts": self.reqManagedAccts,
                    "requestFA": self.requestFA,
                    "replaceFA": self.replaceFA,
                    "reqFundamentalData": self.reqFundamentalData,
                    "cancelFundamentalData": self.cancelFundamentalData,
                    "calculateImpliedVolatility": self.calculateImpliedVolatility,
                    "cancelCalculateImpliedVolatility": self.cancelCalculateImpliedVolatility,
                    "calculateOptionPrice": self.calculateOptionPrice,
                    "cancelCalculateOptionPrice": self.cancelCalculateOptionPrice,
                    "reqGlobalCancel": self.reqGlobalCancel,
                    "reqMarketDataType": self.reqMarketDataType,
                    "reqPositions": self.reqPositions,
                    "cancelPositions": self.cancelPositions,
                    "reqAccountSummary": self.reqAccountSummary,
                    "cancelAccountSummary": self.cancelAccountSummary,
                    "queryDisplayGroups": self.queryDisplayGroups,
                    "subscribeToGroupEvents": self.subscribeToGroupEvents,
                    "updateDisplayGroup": self.updateDisplayGroup,
                    "unsubscribeFromGroupEvents": self.unsubscribeFromGroupEvents,
                    }
        
        return funcMap
    
    def runCommand(self, **kwargs):
        """
        takes in the commands from the run command function and then calls the appropriate command
        """
        
        cmd = kwargs["cmd"]
        self.funcMap[cmd](**kwargs)
        
        
    def subscribeStock(self, **kwargs):
        
        symbol = kwargs["symbol"]
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_exchange = "SMART"
        contract.m_currency = "USD"
        contract.m_secType = "STK"

        self.subscriptions[symbol] = self.subscriptionCounter
        self.tickerMap[self.subscriptionCounter] = symbol
        self.client.reqMktData(self.subscriptionCounter, contract, "", False, [])
        self.subscriptionCounter+=1

    def subscribeFX(self, **kwargs):
        """
        base = base of the currency pair
        priceCur = currency for pricing
        
        ex. USD, JPY means buy/sell USD with price of JPY
        """
        
        base = kwargs["base"]
        priceCur = kwargs["priceCur"]
        
        contract = Contract()
        contract.m_symbol = base
        contract.m_exchange = "IDEALPRO"
        contract.m_currency = priceCur
        contract.m_secType = "CASH"
        
        symbol = ".".join([base, priceCur])

        self.subscriptions[symbol] = self.subscriptionCounter
        self.tickerMap[self.subscriptionCounter] = symbol
        self.client.reqMktData(self.subscriptionCounter, contract, "", False, [])
        self.subscriptionCounter+=1        
    
    def unsubscribeStock(self, **kwargs):
        
        symbol = kwargs["symbol"]
        
        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.tickerMap.pop(self.subscriptions.pop(symbol))
        
    def unsubscribeFX(self, **kwargs):
        
        base = kwargs["base"]
        priceCur = kwargs["priceCur"]
        symbol = ".".join([base, priceCur])
        
        if symbol in self.subscription:
            self.client.cancelMktData(self.subscriptions[symbol])
            self.tickerMap.pop(self.subscriptions.pop(symbol))
        
        
        
    ###Helper functions
    def _createContract(self, **kwargs):
        
        contract = Contract()
        if "contract_conId" in kwargs: contract.m_conId = kwargs["contract_conId"]
        if "contract_symbol" in kwargs: contract.m_symbol = kwargs["contract_symbol"]
        if "contract_secType" in kwargs: contract.m_secType = kwargs["contract_secType"]
        if "contract_expiry" in kwargs: contract.m_expiry = kwargs["contract_expiry"]
        if "contract_strike" in kwargs: contract.m_strike = kwargs["contract_strike"]
        if "contract_right" in kwargs: contract.m_right = kwargs["contract_right"]
        if "contract_multiplier" in kwargs: contract.m_multiplier = kwargs["contract_multiplier"]
        if "contract_exchange" in kwargs: contract.m_exchange = kwargs["contract_exchange"]

        if "contract_currency" in kwargs: contract.m_currency = kwargs["contract_currency"]
        if "contract_localSymbol" in kwargs: contract.m_localSymbol = kwargs["contract_localSymbol"]
        if "contract_tradingClass" in kwargs: contract.m_tradingClass = kwargs["contract_tradingClass"]
        if "contract_primaryExch" in kwargs: contract.m_primaryExch = kwargs["contract_primaryExch"]      # pick a non-aggregate (ie not the SMART exchange) exchange that the contract trades on.  DO NOT SET TO SMART.
        if "contract_includeExpired" in kwargs: contract.m_includeExpired = kwargs["contract_includeExpired"]  # can not be set to true for contracts.

        if "contract_secIdType" in kwargs: contract.m_secIdType = kwargs["contract_secIdType"]        # CUSIP;SEDOL;ISIN;RIC
        if "contract_secId" in kwargs: contract.m_secId = kwargs["contract_secId"]
        
        return contract
    
    def _createOrder(self, **kwargs):
        
        order = Order()
        
        # main order fields
        if "order_orderId" in kwargs: order.m_orderId = kwargs["order_orderId"]
        order.m_clientId = self.id
        if "order_permId" in kwargs: order.m_permId = kwargs["order_permId"]
        if "order_action" in kwargs: order.m_action = kwargs["order_action"] #values are BUY, SELL, SSHORT
        if "order_totalQuantity" in kwargs: order.m_totalQuantity = kwargs["order_totalQuantity"]
        if "order_orderType" in kwargs: order.m_orderType = kwargs["order_orderType"]
        if "order_lmtPrice" in kwargs: order.m_lmtPrice = kwargs["order_lmtPrice"]
        if "order_auxPrice" in kwargs: order.m_auxPrice = kwargs["order_auxPrice"]

        # extended order fields
        if "order_tif" in kwargs: order.m_tif = kwargs["order_tif"]  # "Time in Force" - DAY, GTC, etc.
        if "order_activeStartTime" in kwargs: order.m_activeStartTime = kwargs["order_activeStartTime"] # GTC orders
        if "order_activeStopTime" in kwargs: order.m_activeStopTime = kwargs["order_activeStopTime"] # GTC orders YYYYMMDD hh:mm:ss (optional time zone)
        if "order_ocaGroup" in kwargs: order.m_ocaGroup = kwargs["order_ocaGroup"] # one cancels all group name
        if "order_ocaType" in kwargs: order.m_ocaType = kwargs["order_ocaType"]  # 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK
        if "order_orderRef" in kwargs: order.m_orderRef = kwargs["order_orderRef"]
        if "order_transmit" in kwargs: order.m_transmit = kwargs["order_transmit"]    # if false, order will be created but not transmited
        if "order_parentId" in kwargs: order.m_parentId = kwargs["order_parentId"]    # Parent order Id, to associate Auto STP or TRAIL orders with the original order.
        if "order_blockOrder" in kwargs: order.m_blockOrder = kwargs["order_blockOrder"]
        if "order_sweepToFill" in kwargs: order.m_sweepToFill = kwargs["order_sweepToFill"]
        if "order_displaySize" in kwargs: order.m_displaySize = kwargs["order_displaySize"]
        if "order_triggerMethod" in kwargs: order.m_triggerMethod = kwargs["order_triggerMethod"] # 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-point
        if "order_outsideRth" in kwargs: order.m_outsideRth = kwargs["order_outsideRth"]
        if "order_hidden" in kwargs: order.m_hidden = kwargs["order_hidden"]
        if "order_goodAfterTime" in kwargs: order.m_goodAfterTime = kwargs["order_goodAfterTime"] # FORMAT: 20060505 08:00:00 {time zone}
        if "order_goodTillDate" in kwargs: order.m_goodTillDate = kwargs["order_goodTillDate"]  # FORMAT: 20060505 08:00:00 {time zone} order must be GTD
        if "order_overridePercentageConstraints" in kwargs: order.m_overridePercentageConstraints = kwargs["order_overridePercentageConstraints"]
        if "order_rule80A" in kwargs: order.m_rule80A = kwargs["order_rule80A"]  # Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
        if "order_allOrNone" in kwargs: order.m_allOrNone = kwargs["order_allOrNone"]
        if "order_minQty" in kwargs: order.m_minQty = kwargs["order_minQty"]
        if "order_percentOffset" in kwargs: order.m_percentOffset = kwargs["order_percentOffset"]    # REL orders only specify the decimal, e.g. .04 not 4
        if "order_trailStopPrice" in kwargs: order.m_trailStopPrice = kwargs["order_trailStopPrice"]   # for TRAILLIMIT orders only
        if "order_trailingPercent" in kwargs: order.m_trailingPercent = kwargs["order_trailingPercent"]  # specify the percentage, e.g. 3, not .03

        # Financial advisors only
        if "order_faGroup" in kwargs: order.m_faGroup = kwargs["order_faGroup"]
        if "order_faProfile" in kwargs: order.m_faProfile = kwargs["order_faProfile"]
        if "order_faMethod" in kwargs: order.m_faMethod = kwargs["order_faMethod"]
        if "order_faPercentage" in kwargs: order.m_faPercentage = kwargs["order_faPercentage"]

        # Institutional orders only
        if "order_openClose" in kwargs: order.m_openClose = kwargs["order_openClose"]          # O=Open, C=Close
        if "order_origin" in kwargs: order.m_origin = kwargs["order_origin"]             # 0=Customer, 1=Firm
        if "order_shortSaleSlot" in kwargs: order.m_shortSaleSlot = kwargs["order_shortSaleSlot"]      # 1 if you hold the shares, 2 if they will be delivered from elsewhere.  Only for Action="SSHORT
        if "order_designatedLocation" in kwargs: order.m_designatedLocation = kwargs["order_designatedLocation"] # set when slot=2 only.
        if "order_exemptCode" in kwargs: order.m_exemptCode = kwargs["order_exemptCode"]

        # SMART routing only
        if "order_discretionaryAmt" in kwargs: order.m_discretionaryAmt = kwargs["order_discretionaryAmt"]
        if "order_eTradeOnly" in kwargs: order.m_eTradeOnly = kwargs["order_eTradeOnly"]
        if "order_firmQuoteOnly" in kwargs: order.m_firmQuoteOnly = kwargs["order_firmQuoteOnly"]
        if "order_nbboPriceCap" in kwargs: order.m_nbboPriceCap = kwargs["order_nbboPriceCap"]
        if "order_optOutSmartRouting" in kwargs: order.m_optOutSmartRouting = kwargs["order_optOutSmartRouting"]

        # BOX or VOL ORDERS ONLY
        if "order_auctionStrategy" in kwargs: order.m_auctionStrategy = kwargs["order_auctionStrategy"] # 1=AUCTION_MATCH, 2=AUCTION_IMPROVEMENT, 3=AUCTION_TRANSPARENT

        # BOX ORDERS ONLY
        if "order_startingPrice" in kwargs: order.m_startingPrice = kwargs["order_startingPrice"]
        if "order_stockRefPrice" in kwargs: order.m_stockRefPrice = kwargs["order_stockRefPrice"]
        if "order_delta" in kwargs: order.m_delta = kwargs["order_delta"]

        # pegged to stock or VOL orders
        if "order_stockRangeLower" in kwargs: order.m_stockRangeLower = kwargs["order_stockRangeLower"]
        if "order_stockRangeUpper" in kwargs: order.m_stockRangeUpper = kwargs["order_stockRangeUpper"]

        # VOLATILITY ORDERS ONLY
        if "order_volatility" in kwargs: order.m_volatility = kwargs["order_volatility"]  # enter percentage not decimal, e.g. 2 not .02
        if "order_volatilityType" in kwargs: order.m_volatilityType = kwargs["order_volatilityType"]     # 1=daily, 2=annual
        if "order_continuousUpdate" in kwargs: order.m_continuousUpdate = kwargs["order_continuousUpdate"]
        if "order_referencePriceType" in kwargs: order.m_referencePriceType = kwargs["order_referencePriceType"] # 1=Bid/Ask midpoint, 2 = BidOrAsk
        if "order_deltaNeutralOrderType" in kwargs: order.m_deltaNeutralOrderType = kwargs["order_deltaNeutralOrderType"]
        if "order_deltaNeutralAuxPrice" in kwargs: order.m_deltaNeutralAuxPrice = kwargs["order_deltaNeutralAuxPrice"]
        if "order_deltaNeutralConId" in kwargs: order.m_deltaNeutralConId = kwargs["order_deltaNeutralConId"]
        if "order_deltaNeutralSettlingFirm" in kwargs: order.m_deltaNeutralSettlingFirm = kwargs["order_deltaNeutralSettlingFirm"]
        if "order_deltaNeutralClearingAccount" in kwargs: order.m_deltaNeutralClearingAccount = kwargs["order_deltaNeutralClearingAccount"]
        if "order_deltaNeutralClearingIntent" in kwargs: order.m_deltaNeutralClearingIntent = kwargs["order_deltaNeutralClearingIntent"]
        if "order_deltaNeutralOpenClose" in kwargs: order.m_deltaNeutralOpenClose = kwargs["order_deltaNeutralOpenClose"]
        if "order_deltaNeutralShortSale" in kwargs: order.m_deltaNeutralShortSale = kwargs["order_deltaNeutralShortSale"]
        if "order_deltaNeutralShortSaleSlot" in kwargs: order.m_deltaNeutralShortSaleSlot = kwargs["order_deltaNeutralShortSaleSlot"]
        if "order_deltaNeutralDesignatedLocation" in kwargs: order.m_deltaNeutralDesignatedLocation = kwargs["order_deltaNeutralDesignatedLocation"]

        # COMBO ORDERS ONLY
        if "order_basisPoints" in kwargs: order.m_basisPoints = kwargs["order_basisPoints"]      # EFP orders only, download only
        if "order_basisPointsType" in kwargs: order.m_basisPointsType = kwargs["order_basisPointsType"]  # EFP orders only, download only

        # SCALE ORDERS ONLY
        if "order_scaleInitLevelSize" in kwargs: order.m_scaleInitLevelSize = kwargs["order_scaleInitLevelSize"]
        if "order_scaleSubsLevelSize" in kwargs: order.m_scaleSubsLevelSize = kwargs["order_scaleSubsLevelSize"]
        if "order_scalePriceIncrement" in kwargs: order.m_scalePriceIncrement = kwargs["order_scalePriceIncrement"]
        if "order_scalePriceAdjustValue" in kwargs: order.m_scalePriceAdjustValue = kwargs["order_scalePriceAdjustValue"]
        if "order_scalePriceAdjustInterval" in kwargs: order.m_scalePriceAdjustInterval = kwargs["order_scalePriceAdjustInterval"]
        if "order_scaleProfitOffset" in kwargs: order.m_scaleProfitOffset = kwargs["order_scaleProfitOffset"]
        if "order_scaleAutoReset" in kwargs: order.m_scaleAutoReset = kwargs["order_scaleAutoReset"]
        if "order_scaleInitPosition" in kwargs: order.m_scaleInitPosition = kwargs["order_scaleInitPosition"]
        if "order_scaleInitFillQty" in kwargs: order.m_scaleInitFillQty = kwargs["order_scaleInitFillQty"]
        if "order_scaleRandomPercent" in kwargs: order.m_scaleRandomPercent = kwargs["order_scaleRandomPercent"]
        if "order_scaleTable" in kwargs: order.m_scaleTable = kwargs["order_scaleTable"]

        # HEDGE ORDERS ONLY
        if "order_hedgeType" in kwargs: order.m_hedgeType = kwargs["order_hedgeType"] # 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair
        if "order_hedgeParam" in kwargs: order.m_hedgeParam = kwargs["order_hedgeParam"] # beta value for beta hedge (in range 0-1), ratio for pair hedge

        # Clearing info
        if "order_account" in kwargs: order.m_account = kwargs["order_account"] # IB account
        if "order_settlingFirm" in kwargs: order.m_settlingFirm = kwargs["order_settlingFirm"]
        if "order_clearingAccount" in kwargs: order.m_clearingAccount = kwargs["order_clearingAccount"] # True beneficiary of the order
        if "order_clearingIntent" in kwargs: order.m_clearingIntent = kwargs["order_clearingIntent"] # "" (Default), "IB", "Away", "PTA" (PostTrade)

        # ALGO ORDERS ONLY
        if "order_algoStrategy" in kwargs: order.m_algoStrategy = kwargs["order_algoStrategy"]
        if "order_algoParams" in kwargs: order.m_algoParams = kwargs["order_algoParams"]

        # What-if
        if "order_whatIf" in kwargs: order.m_whatIf = kwargs["order_whatIf"]

        # Not Held
        if "order_notHeld" in kwargs: order.m_notHeld = kwargs["order_notHeld"]

        # Smart combo routing params
        if "order_smartComboRoutingParams" in kwargs: order.m_smartComboRoutingParams = kwargs["order_smartComboRoutingParams"]

        # order combo legs
        #if "order_orderComboLegs" in kwargs: order.m_orderComboLegs = kwargs["order_orderComboLegs"] = new Vector<OrderComboLeg>()

        # order misc options
        if "order_orderMiscOptions" in kwargs: order.m_orderMiscOptions = kwargs["order_orderMiscOptions"]

        return order

    def connected(self, **kwargs):
        return self.client.connected

    def reqCurrentTime(self, **kwargs):
        return self.client.reqCurrentTime()    
   
    def faMsgTypeName(self, **kwargs):
        return self.client.faMsgTypeName(int)

    def serverVersion(self, **kwargs):
        return self.client.serverVersion()

    def TwsConnectionTime(self, **kwargs):
        return self.client.TwsConnectionTime()

    def wrapper(self, **kwargs):
        return self.client.wrapper()

    def reader(self, **kwargs):
        return self.client.reader()

    def isConnected(self, **kwargs):
        return self.client.isConnected()
            
    def eConnect(self, **kwargs):
        
        host = kwargs["host"]
        port = kwargs["port"]
        id = kwargs["id"]
        self.client.eConnect(host, port, id)
                            
    
#     def EClientSocket(self, **kwargs):
#         self.client.EClientSocket(AnyWrapper)
#   
# 
#     def eConnect(self, **kwargs):
#         self.client.eConnect(String, int, int, boolean)
# 
#     def createReader(self, **kwargs):
#         self.client.createReader(EClientSocket, DataInputStream)
# 
#     def eConnect(self, **kwargs):
#         self.client.eConnect(Socket, int)
# 
#     def eConnect(self, **kwargs):
#         self.client.eConnect(Socket)
# 
    def eDisconnect(self, **kwargs):
        self.client.eDisconnect()

###client functions for call backs

#Not using scanners at the moment
#     def cancelScannerSubscription(self, **kwargs):
#         subscriptionId = kwargs["id"]
#         self.client.cancelScannerSubscription(int)
# 
#     def reqScannerParameters(self, **kwargs):
#         self.client.reqScannerParameters()
# 
#     def reqScannerSubscription(self, **kwargs):
#         self.client.reqScannerSubscription(int, ScannerSubscription, Vector<TagValue>)

    def reqMktData(self, **kwargs):
        """
        function to request market data
        """
        #contract information:
        
        requestId = kwargs["tickerId"]
        contract = self._createContract(**kwargs)
         
        tickList = kwargs.get("tickList", "")
        snapshot = kwargs.get("snapshot", False)
        
        self.client.reqMktData(requestId, contract, tickList, snapshot, [])

    def cancelHistoricalData(self, **kwargs):
        requestId = kwargs["tickerId"]
        self.client.cancelHistoricalData(requestId)

    def cancelRealTimeBars(self, **kwargs):
        requestId = kwargs["tickerId"]
        self.client.cancelRealTimeBars(requestId)

    def reqHistoricalData(self, **kwargs):
        requestId = kwargs["tickerId"]
        contract = self._createContratct()
        endDateTime = kwargs["endDateTime"] #format of yyyymmdd HH:mm:ss ttt
        durationStr = kwargs["durationStr"] #can look like 1000 S (int [S D W])
        barSizeSetting = kwargs["barSizeSetting"] #valid values are: 1 sec|5 secs|15 secs|30 secs|1 min|2 mins|3 mins|5 mins|15 mins|30 mins|1 hour|1 day
        whatToShow = kwargs["whatToShow"] #valid values are: TRADES|MIDPOINT|BID|ASK|BID_ASK|HISTORICAL_VOLATILITY|OPTION_IMPLIED_VOLATILITY
        useRTH = bool(kwargs["useRTH"]) #0 for all data, 1 for market hours only
        formatDate = kwargs["formatDate"] #1 for yyyymmdd{space}{space}hh:mm:dd, 2 for timestamp value
        self.client.reqHistoricalData(requestId, contract, endDateTime, durationStr, barSizeSetting, whatToShow, useRTH, formatDate, [])

    def reqRealTimeBars(self, **kwargs):
        requestId = kwargs["tickerId"]
        contract = self._createContratct()
        barSize = 5 
        whatToShow = kwargs["whatToShow"] #valid values are: TRADES|MIDPOINT|BID|ASK|BID_ASK|HISTORICAL_VOLATILITY|OPTION_IMPLIED_VOLATILITY
        useRTH = bool(kwargs["useRTH"]) #0 for all data, 1 for market hours only
        self.client.reqRealTimeBars(requestId, contract, barSize, whatToShow, useRTH, [])

    def reqContractDetails(self, **kwargs):
        
        requestId = kwargs["reqId"]
        contract = self._createContract(**kwargs)
        
        self.client.reqContractDetails(requestId, contract)

    def reqMktDepth(self, **kwargs):
        
        requestId = kwargs["tickerId"]
        contract = self._createContract(**kwargs)
        
        depthRows = kwargs.get("depthRows", 1)
        
        self.client.reqMktDepth(requestId, contract, depthRows, [])

    def cancelMktData(self, **kwargs):
        """
        cancels the market data request
        """
        
        requestId = kwargs["tickerId"]
        self.client.cancelMktData(requestId)

    def cancelMktDepth(self, **kwargs):
        requestId = kwargs["tickerId"]
        self.client.cancelMktDepth(requestId)

    def exerciseOptions(self, **kwargs):
        
        requestId = kwargs["tickerId"]
        contract = self._createContract(**kwargs)
        exerciseAction = kwargs["exercise_action"]
        exerciseQty = kwargs["exercise_qty"]
        account = ""
        override = 0
        #wonder what exchange this should be though
        if contract.m_exchange == "SMART":
            raise("Exchange cannot be smart")
        self.client.exerciseOptions(requestId, contract, exerciseAction, exerciseQty, account, override)

    def placeOrder(self, **kwargs):
        requestId = kwargs["id"]
        contract = self._createContract(**kwargs)
        order = self._createOrder(**kwargs)
        
        self.client.placeOrder(requestId, contract, order)

    def reqAccountUpdates(self, **kwargs):
        
        subscribe = bool(kwargs["subscribe"])
        acctCode = kwargs["acctCode"]
        self.client.reqAccountUpdates(subscribe, acctCode)

    def reqExecutions(self, **kwargs):
        
        requestId = kwargs["reqId"]
        executionFilter = ExecutionFilter()
        self.client.reqExecutions(requestId, executionFilter)

    def cancelOrder(self, **kwargs):
        requestId = kwargs["reqId"] 
        self.client.cancelOrder(requestId)

    def reqOpenOrders(self, **kwargs):
        self.client.reqOpenOrders()

    def reqIds(self, **kwargs):
        numIds = kwargs["numIds"]
        self.client.reqIds(numIds)

    def reqNewsBulletins(self, **kwargs):
        news = kwargs["news"]
        self.client.reqNewsBulletins(news)

    def cancelNewsBulletins(self, **kwargs):
        self.client.cancelNewsBulletins()

    def setServerLogLevel(self, **kwargs):
#     1 = SYSTEM
#     2 = ERROR
#     3 = WARNING
#     4 = INFORMATION
#     5 = DETAIL

        logLevel = kwargs["logLevel"]
        self.client.setServerLogLevel(logLevel)

    def reqAutoOpenOrders(self, **kwargs):
        #If set to TRUE, newly created TWS orders will be implicitly associated with the client. If set to FALSE, no association will be made.
        bAutoBind = kwargs["bAutoBind"]
        self.client.reqAutoOpenOrders(bAutoBind)

    def reqAllOpenOrders(self, **kwargs):
        self.client.reqAllOpenOrders()

    def reqManagedAccts(self, **kwargs):
        self.client.reqManagedAccts()

    def requestFA(self, **kwargs):
        
#     1 = GROUPS
#     2 = PROFILE
#     3 = ACCOUNT ALIASES
        faDataType = kwargs["faDataType"]
        self.client.requestFA(faDataType)

    def replaceFA(self, **kwargs):
        #Call this function to modify FA configuration information from the API. Note that this can also be done manually in TWS itself.
        faDataType = kwargs["faDataType"]
        cxml = kwargs["cxml"]
        self.client.replaceFA(faDataType, cxml)

    def reqFundamentalData(self, **kwargs):


#    report types
#     ReportSnapshot (company overview)
#     ReportsFinSummary (financial summary)
#     ReportRatios (financial ratios)
#     ReportsFinStatements (financial statements)
#     RESC (analyst estimates)
#     CalendarReport (company calendar)

        requestId = kwargs["reqId"]
        contract = self._createContract(**kwargs)
        reportType =kwargs["reportType"]  
        self.client.reqFundamentalData(requestId, contract, reportType)

    def cancelFundamentalData(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelFundamentalData(requestId)

    def calculateImpliedVolatility(self, **kwargs):
        requestId = kwargs["reqId"]
        contract = self._createContract(**kwargs)
        optionPrice = kwargs["optionPrice"]
        underPrice = kwargs["underPrice"]
        
        self.client.calculateImpliedVolatility(requestId, contract, optionPrice, underPrice)

    def cancelCalculateImpliedVolatility(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelCalculateImpliedVolatility(requestId)

    def calculateOptionPrice(self, **kwargs):
        requestId = kwargs["requestId"]
        contract = self._createContract(**kwargs)
        volatility = kwargs["volatility"]
        underPrice = kwargs["underPrice"]
        
        self.client.calculateOptionPrice(requestId, contract, volatility, underPrice)

    def cancelCalculateOptionPrice(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelCalculateOptionPrice(requestId)

    def reqGlobalCancel(self, **kwargs):
        self.client.reqGlobalCancel()

    def reqMarketDataType(self, **kwargs):
        #1 for real-time streaming market data or 2 for frozen market data.
        marketDataType = kwargs["marketDataType"]
        self.client.reqMarketDataType(marketDataType)

    def reqPositions(self, **kwargs):
        self.client.reqPositions()

    def cancelPositions(self, **kwargs):
        self.client.cancelPositions()

    def reqAccountSummary(self, **kwargs):
        #This request can only be made when connected to a Financial Advisor (FA) account.
        requestId = kwargs["reqId"]
        group = kwargs["group"]
        tags = kwargs["tags"]
        self.client.reqAccountSummary(requestId, group, tags)

    def cancelAccountSummary(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.cancelAccountSummary(requestId)

#     def verifyRequest(self, **kwargs):
#         self.client.verifyRequest(String, String)
# 
#     def verifyMessage(self, **kwargs):
#         self.client.verifyMessage(String)

    def queryDisplayGroups(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.queryDisplayGroups(requestId)

    def subscribeToGroupEvents(self, **kwargs):
        #groupId =      The ID of the group, currently it is a number from 1 to 7. This is the display group subscription request sent by the API to TWS. 
        requestId = kwargs["reqId"]
        groupId = kwargs["groupId"]
        self.client.subscribeToGroupEvents(requestId, groupId)

    def updateDisplayGroup(self, **kwargs):
#     contractInfo:
#     none = empty selection
#     contractID@exchange – any non-combination contract. Examples: 8314@SMART for IBM SMART; 8314@ARCA for IBM @ARCA.
#     combo = if any combo is selected.
        requestId = kwargs["reqId"]
        contractInfo = kwargs["contractInfo"]
        self.client.updateDisplayGroup(requestId, contractInfo)

    def unsubscribeFromGroupEvents(self, **kwargs):
        requestId = kwargs["reqId"]
        self.client.unsubscribeFromGroupEvents(requestId)    
    
    def getData(self):
        """
        called to get information out of the queue in the wrapper for information passing
        """
        data = self.wrapper.queue.get()
        
        #this is specialized code to deal with mapping of ids to symbol information
        #work to create something more natural that is layer or at a different level?
        data["tickerId"] = self.tickerMap[data["tickerId"]]
        return data