def _fromTDChildOrdertoIBOpenOrder(tdOrder, idConverter): originalTdOrderId = str(tdOrder['orderId']) int_orderId = idConverter.fromBrokerToIB(originalTdOrderId) security = _fromTDInstrumentToIBridgePySecurity(tdOrder['orderLegCollection'][0]['instrument']) contract = from_security_to_contract(security) orderStatus = OrderStatusConverter().fromTDtoIB(str(tdOrder['status'])) quantity = int(float(tdOrder['quantity'])) orderState = IBCpp.OrderState() orderState.status = orderStatus ibOrder = IBCpp.Order() ibOrder.orderId = int_orderId ibOrder.account = str(tdOrder['accountId']) ibOrder.action = str(tdOrder['orderLegCollection'][0]['instruction']) ibOrder.totalQuantity = quantity ibOrder.orderType = OrderTypeConverter().fromTDtoIB(str(tdOrder['orderType'])) ibOrder.tif = OrderTifConverter().fromTDtoIB(str(tdOrder['duration'])) if ibOrder.orderType == OrderType.LMT: ibOrder.lmtPrice = float(str(tdOrder['price'])) elif ibOrder.orderType == OrderType.STP: ibOrder.auxPrice = float(str(tdOrder['stopPrice'])) elif ibOrder.orderType == OrderType.STP_LMT: ibOrder.lmtPrice = float(str(tdOrder['price'])) ibOrder.auxPrice = float(str(tdOrder['stopPrice'])) elif ibOrder.orderType == OrderType.MKT: pass else: raise RuntimeError(__name__ + '::reqOneOrderWrapper: EXIT, cannot handle orderType=%s' % (ibOrder.orderType,)) ibOrder.orderRef = originalTdOrderId orderStatus, filledQuantity, remaining, price, whyHeld = OrderConverter().fromTDtoIBOrderStatus(tdOrder) return int_orderId, contract, ibOrder, orderState, security, orderStatus, filledQuantity, remaining, price, whyHeld
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 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 str(e): 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, order, ibpyRequest): instrument = self._robinhoodClient.instruments(contract.symbol)[0] action = OrderActionConverter().fromIBtoRB(order.action) tif = OrderTifConverter().fromIBtoRB(order.tif) quantity = int(order.totalQuantity) ans = None if order.orderType == OrderType.MKT: ans = self._robinhoodClient.place_market_order( action, instrument, quantity, tif) elif order.orderType == OrderType.LMT: ans = self._robinhoodClient.place_limit_order( action, instrument=instrument, limit_price=order.lmtPrice, quantity=quantity, time_in_force=tif) elif order.orderType == OrderType.STP: ans = self._robinhoodClient.place_stop_order( action, instrument=instrument, stop_price=order.auxPrice, quantity=quantity, time_in_force=tif) else: self._log.error( __name__ + '::placeOrderWrapper: EXIT, cannot handle orderType=%s' % (order.orderType, )) exit() ibpyOrderId = str(ans['id']) 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 create_contract(security): contract = IBCpp.Contract() contract.symbol = security.symbol contract.secType = security.secType contract.exchange = security.exchange contract.currency = security.currency contract.primaryExchange = security.primaryExchange contract.includeExpired=security.includeExpired contract.expiry= security.expiry contract.strike= float(security.strike) contract.right= security.right contract.multiplier= security.multiplier return contract
def fromRBtoIBOpenOrder(rbOrder, idConverter, accountCode): # IBCpp.Order().orderId must be an integer so that an integer orderId has to be created originalTdOrderId = str(rbOrder['id']) int_orderId = idConverter.fromBrokerToIB(originalTdOrderId) security = symbol(str(rbOrder['symbol'])) contract = from_security_to_contract(security) orderStatus = OrderStatusConverter().fromRBtoIB(str(rbOrder['state'])) quantity = int(float(rbOrder['quantity'])) orderState = IBCpp.OrderState() orderState.status = orderStatus ibOrder = IBCpp.Order() ibOrder.orderId = int_orderId ibOrder.account = accountCode ibOrder.action = OrderActionConverter().fromRBtoIB( str(rbOrder['side'])) # _robinhoodClient side : buy, sell ibOrder.totalQuantity = quantity ibOrder.orderType = OrderTypeConverter().fromRBtoIB( str(rbOrder['type']).lower(), str(rbOrder['trigger']).lower()) ibOrder.tif = OrderTifConverter().fromRBtoIB( str(rbOrder['time_in_force'])) if ibOrder.orderType == OrderType.LMT: ibOrder.lmtPrice = float(str(rbOrder['price'])) elif ibOrder.orderType == OrderType.STP: ibOrder.auxPrice = float(str(rbOrder['stop_price'])) elif ibOrder.orderType == OrderType.STP_LMT: ibOrder.lmtPrice = float(str(rbOrder['price'])) ibOrder.auxPrice = float(str(rbOrder['stop_price'])) elif ibOrder.orderType == OrderType.MKT: pass else: print(__name__ + '::reqOneOrderWrapper: EXIT, cannot handle orderType=%s' % (ibOrder.orderType, )) exit() return int_orderId, contract, ibOrder, orderState, security
def get_scanner_results(self, kwargs): # numberOfRows=-1, instrument='', locationCode='', scanCode='', abovePrice=0.0, # belowPrice=0.0, aboveVolume=0, marketCapAbove=0.0, marketCapBelow=0.0, moodyRatingAbove='', # moodyRatingBelow='', spRatingAbove='', spRatingBelow='', maturityDateAbove='', maturityDateBelow='', # couponRateAbove=0.0, couponRateBelow=0.0, excludeConvertible=0, averageOptionVolumeAbove=0, # scannerSettingPairs='', stockTypeFilter='' tagList = [ 'numberOfRows', 'instrument', 'locationCode', 'scanCode', 'abovePrice', 'belowPrice', 'aboveVolume', 'marketCapAbove', 'marketCapBelow', 'moodyRatingAbove', 'moodyRatingBelow', 'spRatingAbove', 'spRatingBelow', 'maturityDateAbove', 'maturityDateBelow', 'couponRateAbove', 'couponRateBelow', 'excludeConvertible', 'averageOptionVolumeAbove', 'scannerSettingPairs', 'stockTypeFilter' ] subscription = IBCpp.ScannerSubscription() for ct in kwargs: if ct in tagList: setattr(subscription, ct, kwargs[ct]) reqIdList = self.submit_requests(ReqScannerSubscription(subscription)) self.submit_requests(CancelScannerSubscription(reqIdList[0])) return self._brokerClient.get_submit_requests_result( reqIdList[0]) # return a pandas dataFrame
def get_scanner_results(self, **kwargs): # numberOfRows=-1, instrument='', locationCode='', scanCode='', abovePrice=0.0, # belowPrice=0.0, aboveVolume=0, marketCapAbove=0.0, marketCapBelow=0.0, moodyRatingAbove='', # moodyRatingBelow='', spRatingAbove='', spRatingBelow='', maturityDateAbove='', maturityDateBelow='', # couponRateAbove=0.0, couponRateBelow=0.0, excludeConvertible=0, averageOptionVolumeAbove=0, # scannerSettingPairs='', stockTypeFilter='' tagList = [ 'numberOfRows', 'instrument', 'locationCode', 'scanCode', 'abovePrice', 'belowPrice', 'aboveVolume', 'marketCapAbove', 'marketCapBelow', 'moodyRatingAbove', 'moodyRatingBelow', 'spRatingAbove', 'spRatingBelow', 'maturityDateAbove', 'maturityDateBelow', 'couponRateAbove', 'couponRateBelow', 'excludeConvertible', 'averageOptionVolumeAbove', 'scannerSettingPairs', 'stockTypeFilter' ] subscription = IBCpp.ScannerSubscription() for ct in kwargs: if ct in tagList: setattr(subscription, ct, kwargs[ct]) self.request_data(ReqData.reqScannerSubscription(subscription)) reqId = int(self.end_check_list[self.end_check_list['reqType'] == 'reqScannerSubscription']['reqId']) ans = ServerResponse(reqId, self.end_check_list_result[int(reqId)]) return ans
def create_order(orderId, accountCode, security, amount, orderDetails, createdTime, ocaGroup=None, ocaType=None, transmit=None, parentId=None, orderRef='', outsideRth=False, hidden=False): contract = from_security_to_contract(security) order = IBCpp.Order() if hidden: if contract.exchange == ExchangeName.ISLAND: order.hidden = True else: print(__name__ + '::create_order: EXIT, only ISLAND accept hidden orders') exit() if amount > 0: order.action = 'BUY' elif amount < 0: order.action = 'SELL' order.orderId = orderId order.account = accountCode order.totalQuantity = int(abs(amount)) # int only order.orderType = orderDetails.orderType # LMT, MKT, STP order.tif = orderDetails.tif order.orderRef = str(orderRef) order.outsideRth = outsideRth if ocaGroup is not None: order.ocaGroup = ocaGroup if ocaType is not None: order.ocaType = ocaType if transmit is not None: order.transmit = transmit if parentId is not None: order.parentId = parentId if orderDetails.orderType in ['MKT', 'MOC']: pass elif orderDetails.orderType == 'LMT': order.lmtPrice = orderDetails.limit_price elif orderDetails.orderType == 'STP': order.auxPrice = orderDetails.stop_price elif orderDetails.orderType == 'STP LMT': order.lmtPrice = orderDetails.limit_price order.auxPrice = orderDetails.stop_price elif orderDetails.orderType == 'TRAIL LIMIT': if orderDetails.trailing_amount is not None: order.auxPrice = orderDetails.trailing_amount # trailing amount if orderDetails.trailing_percent is not None: order.trailingPercent = orderDetails.trailing_percent order.trailStopPrice = orderDetails.stop_price if order.action == 'SELL': order.lmtPrice = orderDetails.stop_price - orderDetails.limit_offset elif order.action == 'BUY': order.lmtPrice = orderDetails.stop_price + orderDetails.limit_offset elif orderDetails.orderType == 'TRAIL': if orderDetails.trailing_amount is not None: order.auxPrice = orderDetails.trailing_amount # trailing amount if orderDetails.trailing_percent is not None: order.trailingPercent = orderDetails.trailing_percent if orderDetails.stop_price is not None: order.trailStopPrice = orderDetails.stop_price else: print(__name__ + '::create_order: EXIT,Cannot handle orderType=%s' % (orderDetails.orderType, )) an_order = IbridgePyOrder(requestedContract=contract, requestedOrder=order, createdTime=createdTime) return an_order
def simulate_process_order(self, timeNow): # to simulate placing order self._log.debug(__name__ + '::simulate_process_order: timeNow=%s' % (timeNow, )) if len(self.orderToBeProcessed) == 0: self._log.debug(__name__ + '::processOrder: No order to process') return for int_orderId in list(self.orderToBeProcessed.keys())[:]: contract, order = self.orderToBeProcessed[int_orderId] security = from_contract_to_security(contract) ask_price, bid_price, high_price, low_price = \ self._dataProvider.provide_real_time_price_from_local_variable_hist(security, timeNow, [IBCpp.TickType.ASK, IBCpp.TickType.BID, IBCpp.TickType.HIGH, IBCpp.TickType.LOW]) flag = False # if a order meets the processing conditions # based on the current prices, decide which pending orders should be processed/simulated this round. ex_price = 0.0 # avoid PEP8 warning if order.orderType == 'MKT': # for MKT order, just Fill it if order.action == 'BUY': ex_price = ask_price else: ex_price = bid_price flag = True elif order.orderType == 'LMT': # always assume simulation sequence: ask_price -> low_price -> high_price -> close_price if order.action == 'BUY': if order.lmtPrice >= ask_price: flag = True ex_price = ask_price elif low_price <= order.lmtPrice < ask_price: flag = True ex_price = order.lmtPrice else: flag = False else: # SELL if order.lmtPrice <= ask_price: flag = True ex_price = ask_price elif ask_price < order.lmtPrice <= high_price: flag = True ex_price = order.lmtPrice else: flag = False elif order.orderType == 'STP': ex_price = order.auxPrice if order.action == 'BUY': if order.auxPrice <= ask_price: flag = True ex_price = ask_price elif ask_price < order.auxPrice <= high_price: flag = True ex_price = order.auxPrice else: flag = False else: if order.auxPrice >= bid_price: flag = True ex_price = bid_price elif low_price <= order.auxPrice < bid_price: flag = True ex_price = order.auxPrice else: flag = False else: self._log.error( __name__ + '::simulate_process_order: cannot handle order.orderType = %s' % (order.orderType, )) exit() # this order should be processed/simulated right now if flag and ex_price > 0.001: # IBCpp call-back function self.simulateOrderStatus(int_orderId, 'Filled', order.totalQuantity, 0, ex_price, 0, 0, 0, 0, '') del self.orderToBeProcessed[int_orderId] # after an order is executed, need to simulate execDetails (call-back function) execution = IBCpp.Execution() execution.acctNumber = order.account execution.orderId = int_orderId if order.action == 'BUY': execution.side = 'BOT' else: execution.side = 'SLD' execution.shares = int(order.totalQuantity) execution.price = ex_price execution.orderRef = order.orderRef self.simulateExecDetails( -1, contract, execution, from_contract_to_security(contract).full_print()) # IBCpp::simulatePosition needs more calculation because it needs to consider the current # positions. oldPosition = self._singleTrader.get_position( self.name, self._accountCode, security) # print(__name__ + '::simulate_process_order:: oldPosition=%s' % (position,)) oldPrice = oldPosition.price hold = oldPosition.amount amount = None price = None if order.action == 'BUY': if hold + order.totalQuantity != 0: price = (oldPrice * hold + ex_price * order.totalQuantity) / ( hold + order.totalQuantity) else: price = 0.0 amount = hold + order.totalQuantity elif order.action == 'SELL': if hold == order.totalQuantity: price = 0.0 else: price = (oldPrice * hold - ex_price * order.totalQuantity) / ( hold - order.totalQuantity) amount = hold - order.totalQuantity self.simulatePosition( order.account, contract, amount, price, from_contract_to_security(contract).full_print()) self._transactionLog.info( '%s %s %s %s %s %s' % (self.get_datetime(), execution.orderId, from_contract_to_security(contract).full_print(), execution.side, execution.shares, execution.price))
# print (a.exchange) ######## ''' c=ContextClass(('aaa','bbb')) print (c.portfolio['aaa'].positions) c.portfolio['aaa'].positions['aa']=1 print (c.portfolio['aaa'].positions) print (c.portfolio['bbb'].positions) ''' ######## # a=LimitOrder(2355.0) # print (a.__dict__) ####### # print (search_security_in_file('STK', 'XIV', 'exchange')) ###### # c = Positions() ##c['a'] = 1 # print(c['b']) a_contract = IBCpp.Contract() a_contract.secType = 'OPT' a_contract.symbol = 'ES' a_contract.exchange = 'test' a_contract.primaryExchange = 'test' a_contract.currency = 'USD' a_contract.expiry = '20180726' print(from_contract_to_security(a_contract).full_print())