def placeOrder(self, contract: Contract, order: Order) -> Trade: """ Place a new order or modify an existing order. Returns a Trade that is kept live updated with status changes, fills, etc. """ orderId = order.orderId or self.client.getReqId() self.client.placeOrder(orderId, contract, order) now = datetime.datetime.now(datetime.timezone.utc) if not isinstance(order, Order): order = Order(**order.__dict__) trade = self.wrapper.trades.get(orderId) if trade: # this is a modification of an existing order assert trade.orderStatus.status in OrderStatus.ActiveStates logEntry = TradeLogEntry(now, trade.orderStatus.status, 'Modify') trade.log.append(logEntry) else: # this is a new order order.orderId = orderId orderStatus = OrderStatus(status=OrderStatus.PendingSubmit) logEntry = TradeLogEntry(now, orderStatus.status, '') trade = Trade(contract, order, orderStatus, [], [logEntry]) self.wrapper.trades[orderId] = trade _logger.info(f'placeOrder: {trade}') return trade
def CreateBracketOrder(orderDetails, account=None): qty = calculateQty(orderDetails) exitAction = determineDirection(orderDetails) orders = BracketOrder() orders.entryOrder = Order() orders.entryOrder.account = account orders.entryOrder.transmit = False orders.entryOrder.action = orderDetails.entryAction orders.entryOrder.totalQuantity = qty orders.entryOrder.orderType = 'LMT' orders.entryOrder.lmtPrice = Round(orderDetails.entryPrice, orderDetails.wContract.priceIncrement) orders.entryOrder.tif = 'DAY' exitPrice = calculateProfitPrice(orderDetails, orderDetails.entryAction) orders.exitOrder = Order() orders.exitOrder.account = account orders.exitOrder.transmit = False orders.exitOrder.action = exitAction orders.exitOrder.totalQuantity = qty orders.exitOrder.orderType = 'LMT' orders.exitOrder.lmtPrice = Round(exitPrice, orderDetails.wContract.priceIncrement) orders.exitOrder.tif = 'GTC' orders.exitOrder.outsideRth = orderDetails.config.exitOutsideRth if orderDetails.config.dayOrder: dayPrice = calculateDayPrice(orderDetails, orderDetails.entryAction) orders.dayOrder = Order() orders.dayOrder.account = account orders.dayOrder.transmit = False orders.dayOrder.action = exitAction orders.dayOrder.totalQuantity = qty orders.dayOrder.orderType = 'LOC' orders.dayOrder.lmtPrice = Round(dayPrice, orderDetails.wContract.priceIncrement) orders.dayOrder.tif = 'DAY' orders.dayOrder.outsideRth = orderDetails.config.exitOutsideRth orders.stopOrder = Order() orders.stopOrder.account = account orders.stopOrder.transmit = True orders.stopOrder.action = exitAction orders.stopOrder.totalQuantity = qty orders.stopOrder.tif = 'GTC' orders.stopOrder.outsideRth = orderDetails.config.exitOutsideRth if orderDetails.config.trail: orders.stopOrder.orderType = 'TRAIL' if orderDetails.config.stopPercent is not None: orders.stopOrder.trailingPercent = orderDetails.config.stopPercent elif orderDetails.config.stopTarget: orders.stopOrder.auxPrice = orderDetails.config.stopTarget else: stopPrice = calculateStopPrice(orderDetails, orderDetails.entryAction) orders.stopOrder.orderType = 'STP' orders.stopOrder.auxPrice = Round(stopPrice, orderDetails.wContract.priceIncrement) orderDetails.entryPrice = orders.entryOrder.lmtPrice # for debugging clarity logging.info('created bracket orders: %s', orders) return orders
def __init__(self, action, totalQuantity, trailStopPrice, trailingPercent, **kwargs): Order.__init__(self, orderType='TRAIL', action=action, totalQuantity=totalQuantity, trailStopPrice=trailStopPrice, trailingPercent=trailingPercent, **kwargs)
def buildOrders(ib, tradeContract, action, quantity, cciProfile, buyStopLossPrice, sellStopLossPrice, modTrailStopLoss, bars_15mclosePrice): #STP order #closeOpen = findOpenOrders(ib, True) parentId = ib.client.getReqId() #Entry Order log.info("buildOrders: tradeContract: {tc} ".format(tc=tradeContract)) log.info("buildOrders: action: {a} ".format(a=action)) log.info("buildOrders: qty : {q}".format(q=quantity)) log.info("buildOrders: cciprofile: {p} ".format(p=cciProfile)) log.info( "buildOrders: buystoplossprice: {sl} ".format(sl=buyStopLossPrice)) log.info( "buildOrders: sellstoplossprice: {stl} ".format(stl=sellStopLossPrice)) log.info( "buildOrders: bars_15mclosePrice: {cp}".format(cp=bars_15mclosePrice)) MktOrder = Order( action=action, orderType="MKT", #lmtPrice = limitPrice, orderId=parentId, faProfile=cciProfile, totalQuantity=quantity, transmit=False) trademkt = ib.placeOrder(tradeContract, MktOrder) stopAction = "Buy" stoplossprice = sellStopLossPrice stoplimitprice = stoplossprice + 1 if action == "Buy": stopAction = "Sell" stoplossprice = buyStopLossPrice stoplimitprice = stoplossprice - 1 #Stop Loss Order stopLossOrder = Order( action=stopAction, orderType="STP", auxPrice=stoplossprice, lmtPrice=stoplimitprice, #trailStopPrice = modTrailStopLoss, faProfile=cciProfile, totalQuantity=quantity, orderId=ib.client.getReqId(), parentId=parentId, outsideRth=True, tif="GTC", transmit=True) tradestp = ib.placeOrder(tradeContract, stopLossOrder) return trademkt, tradestp, parentId, MktOrder, stopLossOrder
def buildOrders( ib, tradeContract, action, quantity, cciProfile, stoplossprice, ): #STP order closeOpen = findOpenOrders(ib, True) parentId = ib.client.getReqId() stopAction = "BUY" if action == "BUY": stopAction = "SELL" #Entry Order print("buildOrders: tradeContract ", tradeContract) print("buildOrders: action: ", action) print("buildOrders: qty : ", quantity) print("buildOrders: cciprofile ", cciProfile) print("buildOrders: stoplosspricee ", stoplossprice) MktOrder = Order(action=action, orderType="MKT", orderId=parentId, faProfile=cciProfile, totalQuantity=quantity, transmit=False) #Stop Loss Order stoplossOrder = Order(action=stopAction, orderType="STP", auxPrice=stoplossprice, lmtPrice=0, faProfile=cciProfile, totalQuantity=quantity, orderId=ib.client.getReqId(), parentId=parentId, transmit=True) trademkt = ib.placeOrder(tradeContract, MktOrder) checkOrderStatus = updateOrderandTrades( ib, trademkt, "trademkt") #wait for status t/f - false since this is tradestp = ib.placeOrder(tradeContract, stoplossOrder) checkOrderStatus = updateOrderandTrades(ib, tradestp, "tradestp") #wait for status t/f print("buildOrders: Order placed ", action, quantity) print("") print("buildOrders: did place order", trademkt) print("") print("buildOrders: placed stop order ", tradestp) return [MktOrder], [stoplossOrder], parentId
def openOrder(self, orderId, contract, order, orderState): """ This wrapper is called to: * feed in open orders at startup; * feed in open orders or order updates from other clients and TWS if clientId=master id; * feed in manual orders and order updates from TWS if clientId=0. """ if order.whatIf: # response to whatIfOrder orderState = OrderState(**orderState.__dict__) self._endReq(order.orderId, orderState) else: if order.softDollarTier: order.softDollarTier = SoftDollarTier( **order.softDollarTier.__dict__) key = self.orderKey(order.clientId, order.orderId, order.permId) trade = self.trades.get(key) if trade: trade.order.update(**order.__dict__) else: contract = self._getContract(contract) order = Order(**order.__dict__) orderStatus = OrderStatus(status=orderState.status) trade = Trade(contract, order, orderStatus, [], []) self.trades[key] = trade self._logger.info(f'openOrder: {trade}') results = self._results.get('openOrders') if results is None: self._ib.openOrderEvent.emit(trade) else: # response to reqOpenOrders results.append(order)
def openOrder(self, orderId, contract, order, orderState): """ This wrapper is called to: * feed in open orders at startup; * feed in open orders or order updates from other clients and TWS if clientId=master id; * feed in manual orders and order updates from TWS if clientId=0; * handle openOrders and allOpenOrders responses. """ if order.whatIf: # response to whatIfOrder self._endReq(order.orderId, orderState) else: key = self.orderKey(order.clientId, order.orderId, order.permId) trade = self.trades.get(key) # ignore '?' values in the order d = {k: v for k, v in order.dict().items() if v != '?'} if trade: trade.order.update(**d) else: contract = Contract.create(**contract.dict()) order = Order(**d) orderStatus = OrderStatus(status=orderState.status) trade = Trade(contract, order, orderStatus, [], []) self.trades[key] = trade self._logger.info(f'openOrder: {trade}') self.permId2Trade.setdefault(order.permId, trade) results = self._results.get('openOrders') if results is None: self.ib.openOrderEvent.emit(trade) else: # response to reqOpenOrders or reqAllOpenOrders results.append(order)
def openOrder(self, orderId, contract, order, orderState): contract = Contract(**contract.__dict__) order = Order(**order.__dict__) orderStatus = OrderStatus(status=orderState.status) trade = Trade(contract, order, orderStatus, [], []) self._results['openOrders'].append(trade) if order.clientId == self.clientId and orderId not in self.trades: self.trades[orderId] = trade _logger.info(f'openOrder: {trade}')
def validate_order_trigger(order: Order, price: BarData) -> None: """ Verify if adjustable order triggered modification. If so modify order in place. """ # order doesn't have a trigger price (default value) if order.triggerPrice == 1.7976931348623157e+308: log.debug('validate_order_trigger returned') return if ((order.action.upper() == 'BUY' and order.triggerPrice >= price.low) or (order.action.upper() == 'SELL' and order.triggerPrice <= price.high)): order.orderType = order.adjustedOrderType order.auxPrice = order.adjustedStopPrice # prevent future trigger verification order.triggerPrice = 1.7976931348623157e+308 log.debug(f'Order adjusted: {order}')
def validate_trail(order: Order, price: BarData) -> Union[None, float]: price = (price.open, price.high, price.low, price.close) # check if BUY order hit if order.action.upper() == 'BUY': if order.trailStopPrice <= max(price): return order.trailStopPrice else: order.trailStopPrice = min(order.trailStopPrice, min(price) + order.auxPrice) return False # check if SELL order hit if order.action.upper() == 'SELL': if order.trailStopPrice >= min(price): return order.trailStopPrice else: order.trailStopPrice = max(order.trailStopPrice, max(price) - order.auxPrice) return False
def openOrder(self, orderId, contract, order, orderState): if order.whatIf: # response to whatIfOrder orderState = OrderState(**orderState.__dict__) self._endReq(orderId, orderState) else: contract = Contract(**contract.__dict__) order = Order(**order.__dict__) orderStatus = OrderStatus(status=orderState.status) if order.softDollarTier: order.softDollarTier = SoftDollarTier( **order.softDollarTier.__dict__) trade = Trade(contract, order, orderStatus, [], []) if order.clientId == self.clientId and orderId not in self.trades: self.trades[orderId] = trade _logger.info(f'openOrder: {trade}') results = self._results.get('openOrders') if results is not None: # response to reqOpenOrders results.append(order)
def modify_limit_price_given_original_objects( self, original_order_object: ibOrder, original_contract_object_with_legs: ibcontractWithLegs, new_limit_price: float) -> tradeWithContract: original_contract_object = original_contract_object_with_legs.ibcontract original_order_object.lmtPrice = new_limit_price new_trade_object = self.ib.placeOrder(original_contract_object, original_order_object) new_trade_with_contract = tradeWithContract( original_contract_object_with_legs, new_trade_object) return new_trade_with_contract
def openOrder( self, orderId: int, contract: Contract, order: Order, orderState: OrderState): """ This wrapper is called to: * feed in open orders at startup; * feed in open orders or order updates from other clients and TWS if clientId=master id; * feed in manual orders and order updates from TWS if clientId=0; * handle openOrders and allOpenOrders responses. """ if order.whatIf: # response to whatIfOrder if orderState.commissionCurrency: self._endReq(order.orderId, orderState) else: key = self.orderKey(order.clientId, order.orderId, order.permId) trade = self.trades.get(key) if trade: trade.order.permId = order.permId trade.order.totalQuantity = order.totalQuantity trade.order.lmtPrice = order.lmtPrice trade.order.auxPrice = order.auxPrice trade.order.orderType = order.orderType else: # ignore '?' values in the order order = Order(**{ k: v for k, v in dataclassAsDict(order).items() if v != '?'}) contract = Contract.create(**dataclassAsDict(contract)) orderStatus = OrderStatus( orderId=orderId, status=orderState.status) trade = Trade(contract, order, orderStatus, [], []) self.trades[key] = trade self._logger.info(f'openOrder: {trade}') self.permId2Trade.setdefault(order.permId, trade) results = self._results.get('openOrders') if results is None: self.ib.openOrderEvent.emit(trade) else: # response to reqOpenOrders or reqAllOpenOrders results.append(order) # make sure that the client issues order ids larger then any # order id encountered (even from other clients) to avoid # "Duplicate order id" error self.ib.client.updateReqId(orderId + 1)
def closeOrders(ib, tradeContract, account, action, quantity): #closeOpen = findOpenOrders(ib,True) parentId = ib.client.getReqId() #Entry Order log.info( "closeOrders: tradeContract: {tc} account: {ac} action: {act} qty: {qty}" .format(tc=tradeContract, ac=account, act=action, qty=quantity)) MktOrder = Order(account=account, action=action, orderType="MKT", orderId=parentId, totalQuantity=quantity, transmit=True) trademkt = ib.placeOrder(tradeContract, MktOrder) checkOrderStatus = updateOrderandTrades(ib, trademkt, "trademkt") #ib.sleep(1) #trademkt.log #Stop Loss Order return [MktOrder]
def closePositionsOrders(ib, tradeContract, account, action, quantity): #closeOpen = findOpenOrders(ib,True) parentId = ib.client.getReqId() #Entry Order log.info( "closePositionsOrders: tradeContract: {tc} account: {ac} action: {act} qty: {qty}" .format(tc=tradeContract, ac=account, act=action, qty=quantity)) MktOrder = Order(account=account, action=action, orderType="MKT", orderId=parentId, totalQuantity=quantity, transmit=True) trademkt = ib.placeOrder(tradeContract, MktOrder) symbol, orderId, orderType, action, quantity, status, date_order, faProfile, parentId, avgFillPrice, account, permID = parseTradeString( ib, trademkt) print("closePositionsOrders: trademkt ", trademkt) writeToCsv = writeOrdersToCSV(ib, MktOrder, "MktOrder", status, openOrderType=False) return trademkt, MktOrder
def TrailBracketOrder(self, parentOrderId, childOrderId, action, quantity, limitPrice, trailAmount): # This will be our main or "parent" order parent = Order() parent.orderId = parentOrderId parent.action = action parent.orderType = "LMT" parent.totalQuantity = 1000 #quantity parent.lmtPrice = limitPrice parent.transmit = False stopLoss = Order() stopLoss.orderId = childOrderId logging.info("Action is " + action) if action == "Buy": stopLoss.action = "Sell" stopLoss.trailStopPrice = limitPrice - (limitPrice * .02) if action == "Sell": stopLoss.action = "Buy" stopLoss.trailStopPrice = limitPrice + (limitPrice * .02) stopLoss.orderType = "TRAIL" stopLoss.auxPrice = limitPrice #trailAmount #trailAmount stopLoss.totalQuantity = 1000 #quantity stopLoss.parentId = parentOrderId stopLoss.transmit = True bracketOrder = [parent, stopLoss] return bracketOrder
#util.startLoop() ib = IB() ib.connect('127.0.0.1', 55555, clientId=6) contContract = ib.reqContractDetails( ContFuture(symbol=config.SYMBOL, exchange=config.EXCHANGE)) print("contContract ", contContract) print("") tradeContract = Contract(exchange=config.EXCHANGE, secType="FUT", localSymbol="ESM0") #tradeContract = ib.qualifyContracts(contContract)[0] # gives all the details of a contract so we can trade it #contract = ib.reqContractDetails(ContFuture(symbol=config.SYMBOL, exchange=config.EXCHANGE)) #order = LimitOrder('SELL',2,2800) limitOrder = Order(action="SELL", orderType="LMT", auxPrice=0, lmtPrice=2800, faProfile="cci_day", totalQuantity=1, tif="GTC", transmit=True) print("tradeContract ", tradeContract) print("") print("order ", limitOrder) print("") trade = ib.placeOrder(tradeContract, limitOrder) ib.sleep(1) print("trade log ", trade.log)
def whatIfOrderAsync(self, contract, order): whatIfOrder = Order(**order.dict()).update(whatIf=True) reqId = self.client.getReqId() future = self.wrapper.startReq(reqId) self.client.placeOrder(reqId, contract, whatIfOrder) return future