def __str__(self): if self.requestedOrder is not None: # IBridgePy created orders ans = '{ibpyOrderId=%s status=%s order=%s contract=%s}' % ( self._ibpyOrderId, self.status, print_IBCpp_order(self.requestedOrder), print_IBCpp_contract(self.requestedContract)) else: # orders are called-back from IB server if self.get_value_by_tag('whyHeld') == '': if self.openOrderRecord.order.orderId not in [0, -1]: ans = '{ibpyOrderId=%s status=%s order=%s contract=%s}' % ( self.getIbpyOrderId(), self.status, print_IBCpp_order(self.openOrderRecord.order), print_IBCpp_contract(self.openOrderRecord.contract)) else: ans = '{permId=%s status=%s order=%s contract=%s}' % ( self.getIbpyOrderId(), self.status, print_IBCpp_order(self.openOrderRecord.order), print_IBCpp_contract(self.openOrderRecord.contract)) else: if self.openOrderRecord.order.orderId not in [0, -1]: ans = '{ibpyOrderId=%s status=%s order=%s contract=%s whyHeld=%s}' % ( self.getIbpyOrderId(), self.status, print_IBCpp_order(self.openOrderRecord.order), print_IBCpp_contract(self.openOrderRecord.contract), self.get_value_by_tag('whyHeld')) else: ans = '{permId=%s status=%s order=%s contract=%s whyHeld=%s}' % ( self.getIbpyOrderId(), self.status, print_IBCpp_order(self.openOrderRecord.order), print_IBCpp_contract(self.openOrderRecord.contract), self.get_value_by_tag('whyHeld')) return ans
def _placeOrderHelper(self, int_orderId, ibpyRequest, contract, ibcppOrder): ibpyOrderId = self._idConverter.fromIBtoBroker(int_orderId) # Set for ending flat. # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId) ibpyRequest.param['int_orderId'] = int_orderId # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId self._singleTrader.set_from_send_req_to_server(self.name, ibcppOrder.account, ibpyOrderId) # IBCpp function self.placeOrder(int_orderId, contract, ibcppOrder) self._log.debug( __name__ + '::placeOrderWrapper: int_orderId=%s contract=%s ibcppOrder=%s' % (int_orderId, print_IBCpp_contract(contract), print_IBCpp_order(ibcppOrder))) # Only IB order may not follow up. # If do not follow up on order, just set ending flag and assign ibpyOrderId here. if not ibpyRequest.followUp: ibpyRequest.returnedResult = ibpyOrderId ibpyRequest.status = ReqAttr.Status.COMPLETED
def placeOrderWrapper(self, contract, order, ibpyRequest): self._log.debug( __name__ + '::placeOrderWrapper: contract=%s order=%s' % (print_IBCpp_contract(contract), print_IBCpp_order(order))) if isinstance(order.orderId, int): int_orderId = order.orderId else: int_orderId = self.use_next_id() order.orderId = int_orderId # Set for ending flat. # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId) ibpyRequest.param['int_orderId'] = int_orderId ibpyOrderId = self._idConverter.fromIBtoBroker(int_orderId) # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId self._singleTrader.set_from_send_req_to_server(self.name, order.account, ibpyOrderId) self.orderToBeProcessed[int_orderId] = (contract, order) self.simulateOpenOrder( int_orderId, contract, order, IBCpp.OrderState(), from_contract_to_security(contract).full_print()) # IBCpp function self.simulateOrderStatus(int_orderId, 'Submitted', 0, order.totalQuantity, 0.0, 0, 0, 0, 0, '') # IBCpp function self.simulate_process_order(self.get_datetime())
def __str__(self): ans = '{reqId=%s;status=%s;reqType=%s;followUp=%s;' % ( self.reqId, self.status, self.reqType, self.followUp) tmp = '{' for key in self.param: if key == 'order': tmp += 'order:%s,' % (print_IBCpp_order(self.param[key])) elif key == 'contract': tmp += 'contract:%s,' % (print_IBCpp_contract(self.param[key])) elif key == 'security': tmp += 'security:%s,' % (self.param[key].full_print()) else: tmp += '%s:%s,' % (key, self.param[key]) tmp += '}' ans += 'param=%s}' % (tmp, ) return ans
def placeOrderWrapper(self, contract, order, ibpyRequest): self._validate_contract(contract, 'placeOrderWrapper') self._log.info('Place Order to %s security=%s order=%s' % (self.name, print_IBCpp_contract(contract), print_IBCpp_order(order))) tdOrder = OrderConverter().fromIBtoTD(contract, order) try: ibpyOrderId = self._tdClient.place_orders(order.account, tdOrder) except RuntimeError as e: if 'buying power' in e.message: raise NotEnoughFund() else: raise RuntimeError(e) if ibpyOrderId is None: raise RuntimeError( 'Place order to TD failed but there is not RuntimeError.') self._log.info('Order was placed to %s successfully. ibpyOrderId=%s' % (self.name, ibpyOrderId)) # Register int_orderId in _idConverter so that brokerClient::CallBack::orderStatus knows how to handle int_orderId int_orderId = self._idConverter.fromBrokerToIB(ibpyOrderId) self._idConverter.setRelationship(int_orderId, ibpyOrderId) # Set for ending flat. # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId) ibpyRequest.param['int_orderId'] = int_orderId # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId self._singleTrader.set_from_send_req_to_server(self.name, order.account, ibpyOrderId) # IBCpp function order.orderId = int_orderId self.simulateOpenOrder( int_orderId, contract, order, IBCpp.OrderState(), from_contract_to_security(contract).full_print()) # IBCpp function # IBCpp function, this is the ending flag for PlaceOrder self.simulateOrderStatus(int_orderId, 'Submitted', 0, order.totalQuantity, 0.0, 0, 0, 0, 0, '')
def placeOrderWrapper(self, contract, ibcppOrder, ibpyRequest): self._check_connectivity_reconn_if_needed() orderId = ibcppOrder.orderId if isinstance(orderId, int) and orderId != 0: self._log.debug(__name__ + '::placeOrderWrapper: orderId=%s' % (ibcppOrder.orderId, )) int_orderId = ibcppOrder.orderId else: self.request_data( ReqIds() ) # For IBinsync, nextId needs updates every time when self._nextId is needed. int_orderId = self._nextId.useOne() ibcppOrder.orderId = int_orderId self._log.debug(__name__ + '::placeOrderWrapper: reqIds and then orderId=%s' % (int_orderId, )) ibpyOrderId = self._idConverter.fromIBtoBroker(int_orderId) # Set for ending flat. # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId) ibpyRequest.param['int_orderId'] = int_orderId # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId self._singleTrader.set_from_send_req_to_server(self.name, ibcppOrder.account, ibpyOrderId) # IBCpp function self.placeOrder(int_orderId, contract, ibcppOrder) self._log.debug( __name__ + '::placeOrderWrapper: int_orderId=%s contract=%s ibcppOrder=%s' % (int_orderId, print_IBCpp_contract(contract), print_IBCpp_order(ibcppOrder))) # Only IB order may not follow up. # If do not follow up on order, just set ending flag and assign ibpyOrderId here. if not ibpyRequest.followUp: ibpyRequest.returnedResult = ibpyOrderId ibpyRequest.status = ReqAttr.Status.COMPLETED
def openOrder(self, int_ibOrderId, contract, order, orderState): """ call back function of IB C++ API which updates the open orders """ self._log.debug( __name__ + '::openOrder: ibOrderId=%i contract=%s order=%s orderState=%s' % (int_ibOrderId, print_IBCpp_contract(contract), print_IBCpp_order(order), print_IBCpp_orderState(orderState))) # For IB only: # The int_ibOrderId is 0 or -1 if the order is not placed by IB clients # Then, create a string value for it using permId # IBridgePy will not touch these orders and the created value is not registered in idConverter if int_ibOrderId in [-1]: str_ibpyOrderId = 'permIDatIB%s' % (order.permId, ) else: str_ibpyOrderId = self._idConverter.fromIBtoBroker(int_ibOrderId) self._singleTrader.set_openOrder( self.brokerName, order.account, OpenOrderRecord(str_ibpyOrderId, contract, order, orderState))
def _send_req_to_server(self, activeRequests): """ pandas dataFrame: reqData All requests are defined in broker_client_factory::BrokerClientDefs """ self._log.debug(__name__ + '::_send_req_to_server: brokerClient=%s' % (self, )) for reqId in activeRequests.get_request_ids(): aRequest = activeRequests.get_by_reqId_otherwise_exit(reqId) self._allRequests[ reqId] = aRequest # move to allRequest which stores all requests aRequest.status = ReqAttr.Status.SUBMITTED reqType = aRequest.reqType param = aRequest.param self._log.debug('%s' % (aRequest, )) if reqType == 'reqPositions': self.reqPositionsWrapper() elif reqType == 'reqConnect': ans = self.isConnectedWrapper() if ans: aRequest.status = ReqAttr.Status.COMPLETED else: ans = self.connectWrapper() if ans: aRequest.status = ReqAttr.Status.COMPLETED elif reqType == 'reqCurrentTime': self.reqCurrentTimeWrapper() elif reqType == 'reqAllOpenOrders': self.reqAllOpenOrdersWrapper() elif reqType == 'reqOneOrder': ibpyOrderId = param['orderId'] self.reqOneOrderWrapper(ibpyOrderId) elif reqType == 'reqAccountUpdates': accountCode = param['accountCode'] subscribe = param['subscribe'] self.reqAccountUpdatesWrapper( subscribe, accountCode) # Request to update account info elif reqType == 'reqAccountSummary': group = param['group'] tag = param['tag'] self.reqAccountSummaryWrapper(reqId, group, tag) elif reqType == 'reqIds': self.reqIdsWrapper() elif reqType == 'reqHeartBeats': self.reqHeartBeatsWrapper() elif reqType == 'reqHistoricalData': security = param['security'] endTime = param['endTime'] goBack = param['goBack'] barSize = param['barSize'] whatToShow = param['whatToShow'] useRTH = param['useRTH'] formatDate = 2 # param['formatDate'] Send epoch to IB server all the time. It is easier to handle self.reqHistoricalDataWrapper( reqId, from_security_to_contract(security), endTime, goBack, barSize, whatToShow, useRTH, formatDate) elif reqType == 'reqMktData': security = param['security'] genericTickList = param['genericTickList'] snapshot = param['snapshot'] # put security and reqID in dictionary for fast access # it is keyed by both security and reqId self._realTimePriceRequestedList.addReqIdAndStrSecurity( reqId, security.full_print()) self.reqMktDataWrapper( reqId, from_security_to_contract(security), genericTickList, snapshot) # Send market data request to IB server elif reqType == 'cancelMktData': security = param['security'] reqId = self._realTimePriceRequestedList.findByStrSecurity( security.full_print()) self.cancelMktDataWrapper(reqId) self._realTimePriceRequestedList.deleteReqIdAndStrSecurity( reqId, security.full_print()) elif reqType == 'reqRealTimeBars': security = param['security'] barSize = param['barSize'] whatToShow = param['whatToShow'] useRTH = param['useRTH'] self._realTimePriceRequestedList.addReqIdAndStrSecurity( reqId, security.full_print()) self.reqRealTimeBarsWrapper( reqId, from_security_to_contract(security), barSize, whatToShow, useRTH) # Send market dataFromServer request to IB server elif reqType == 'placeOrder': """ Ending label is IBCpp::callBacks::orderStatus """ contract = param['contract'] order = param['order'] self.placeOrderWrapper(contract, order, aRequest) # When the order is placed, IB will callback orderStatus # In broker_client_factory::CallBack::orderStatus, IBridgePy, set ending flag for this request and assign ibpyOrderId # self.activeRequests.get_by_reqId_otherwise_exit(reqId).returnedResult = str_ibpyOrderId # self.activeRequests.get_by_reqId_otherwise_exit(reqId).status = ReqAttr.Status.COMPLETED elif reqType == 'modifyOrder': """ Ending label is IBCpp::callBacks::orderStatus """ ibpyOrderId = param['ibpyOrderId'] contract = param['contract'] order = param['order'] int_orderId = order.orderId self._idConverter.verifyRelationship(int_orderId, ibpyOrderId) self._log.info( 'ModifyOrder ibpyOrderId=%s security=%s order=%s' % (ibpyOrderId, print_IBCpp_contract(contract), print_IBCpp_order(order))) self.modifyOrderWrapper(contract, order, aRequest) elif reqType == 'reqContractDetails': security = param['security'] self.reqContractDetailsWrapper( reqId, from_security_to_contract(security)) elif reqType == 'calculateImpliedVolatility': security = param['security'] optionPrice = float(param['optionPrice']) underPrice = float(param['underPrice']) # put security and reqID in dictionary for fast access # it is keyed by both security and reqId self._realTimePriceRequestedList.addReqIdAndStrSecurity( reqId, security.full_print()) self.calculateImpliedVolatilityWrapper( reqId, from_security_to_contract(security), optionPrice, underPrice) elif reqType == 'reqScannerSubscription': subscription = param['subscription'] self.reqScannerSubscriptionWrapper(reqId, subscription) # Need to upgrade IBCpp # tagValueList = self.end_check_list.loc[idx, 'reqData'].param['tagValueList'] # self.reqScannerSubscription(reqId, subscription, tagValueList) # self._log.debug(__name__ + '::_send_req_to_server:reqScannerSubscription:' # + ' subscription=' + subscription.full_print() + ' tagValueList=' + str(tagValueList)) elif reqType == 'cancelScannerSubscription': tickerId = param['tickerId'] self.cancelScannerSubscriptionWrapper(tickerId) elif reqType == 'cancelOrder': """ Ending label is IBCpp::callBacks::error: errorCode = 10148 Do not use orderStatus callback to follow up on cancelOrder request because the status can be either Canceled Or PendingCancel """ ibpyOrderId = param['ibpyOrderId'] int_orderId = self._idConverter.fromBrokerToIB(ibpyOrderId) param['int_orderId'] = int_orderId self.cancelOrderWrapper(ibpyOrderId) elif reqType == 'reqScannerParameters': self.reqScannerParametersWrapper() else: self._log.error( __name__ + '::_send_req_to_server: EXIT, cannot handle reqType=%s' % (reqType, )) self.end()