def BracketOrder(parentOrderId: int, action: str, quantity: float, limitPrice: float, takeProfitLimitPrice: float, stopLossPrice: float): #This will be our main or "parent" order parent = Order() parent.orderId = parentOrderId parent.action = action parent.orderType = "LMT" parent.totalQuantity = quantity parent.lmtPrice = round(limitPrice, 2) #The parent and children orders will need this attribute set to False to prevent accidental executions. #The LAST CHILD will have it set to True, parent.transmit = False takeProfit = Order() takeProfit.orderId = parent.orderId + 1 takeProfit.action = "SELL" if action == "BUY" else "BUY" takeProfit.orderType = "LMT" takeProfit.totalQuantity = quantity takeProfit.lmtPrice = round(takeProfitLimitPrice, 2) takeProfit.parentId = parentOrderId takeProfit.transmit = False stopLoss = Order() stopLoss.orderId = parent.orderId + 2 stopLoss.action = "SELL" if action == "BUY" else "BUY" stopLoss.orderType = "STP" stopLoss.auxPrice = round(limitPrice + stopLossPrice, 2) stopLoss.triggerPrice = round(limitPrice - stopLossPrice, 2) stopLoss.adjustedOrderType = "STP" stopLoss.adjustedStopPrice = round(limitPrice, 2) # stopLoss.orderType = "TRAIL" # #Stop trigger price # stopLoss.auxPrice = round(stopLossPrice,2) stopLoss.totalQuantity = quantity stopLoss.parentId = parentOrderId #In this case, the low side order will be the last child being sent. Therefore, it needs to set this attribute to True #to activate all its predecessors stopLoss.transmit = True bracketOrder = [parent, takeProfit, stopLoss] return bracketOrder
def get_stop_loss(self) -> Order: dollar_with_direction = self.dollar * self.direction stop_loss = Order() stop_loss.action = "SELL" if self.market_is_rising else "BUY" stop_loss.totalQuantity = self.order_size stop_loss.orderType = "STP LMT" stop_loss.lmtPrice = self.parent_price + dollar_with_direction * 5 stop_loss.auxPrice = self.parent_price - dollar_with_direction * 20 stop_loss.adjustedOrderType = "TRAIL LIMIT" stop_loss.adjustedStopPrice = self.parent_price + dollar_with_direction * 12 stop_loss.adjustedStopLimitPrice = self.parent_price + dollar_with_direction * 5 stop_loss.triggerPrice = self.parent_price + dollar_with_direction * 30 stop_loss.adjustedTrailingAmount = self.dollar * 10 stop_loss.tif = "GTC" stop_loss.outsideRth = True stop_loss.parentId = self.parent_order_id # stop_loss.triggerMethod = 3 stop_loss.transmit = False return stop_loss
def processOpenOrder(self, fields): sMsgId = next(fields) version = decode(int, fields) order = Order() order.orderId = decode(int, fields) contract = Contract() contract.conId = decode(int, fields) # ver 17 field contract.symbol = decode(str, fields) contract.secType = decode(str, fields) contract.lastTradeDateOrContractMonth = decode(str, fields) contract.strike = decode(float, fields) contract.right = decode(str, fields) if version >= 32: contract.multiplier = decode(str, fields) contract.exchange = decode(str, fields) contract.currency = decode(str, fields) contract.localSymbol = decode(str, fields) # ver 2 field if version >= 32: contract.tradingClass = decode(str, fields) # read order fields order.action = decode(str, fields) if self.serverVersion >= MIN_SERVER_VER_FRACTIONAL_POSITIONS: order.totalQuantity = decode(float, fields) else: order.totalQuantity = decode(int, fields) order.orderType = decode(str, fields) if version < 29: order.lmtPrice = decode(float, fields) else: order.lmtPrice = decode(float, fields, SHOW_UNSET) if version < 30: order.auxPrice = decode(float, fields) else: order.auxPrice = decode(float, fields, SHOW_UNSET) order.tif = decode(str, fields) order.ocaGroup = decode(str, fields) order.account = decode(str, fields) order.openClose = decode(str, fields) order.origin = decode(int, fields) order.orderRef = decode(str, fields) order.clientId = decode(int, fields) # ver 3 field order.permId = decode(int, fields) # ver 4 field order.outsideRth = decode(bool, fields) # ver 18 field order.hidden = decode(bool, fields) # ver 4 field order.discretionaryAmt = decode(float, fields) # ver 4 field order.goodAfterTime = decode(str, fields) # ver 5 field order.sharesAllocation = decode(str, fields) # deprecated ver 6 field order.faGroup = decode(str, fields) # ver 7 field order.faMethod = decode(str, fields) # ver 7 field order.faPercentage = decode(str, fields) # ver 7 field order.faProfile = decode(str, fields) # ver 7 field if self.serverVersion >= MIN_SERVER_VER_MODELS_SUPPORT: order.modelCode = decode(str, fields) order.goodTillDate = decode(str, fields) # ver 8 field order.rule80A = decode(str, fields) # ver 9 field order.percentOffset = decode(float, fields, SHOW_UNSET) # ver 9 field order.settlingFirm = decode(str, fields) # ver 9 field order.shortSaleSlot = decode(int, fields) # ver 9 field order.designatedLocation = decode(str, fields) # ver 9 field if self.serverVersion == MIN_SERVER_VER_SSHORTX_OLD: exemptCode = decode(int, fields) elif version >= 23: order.exemptCode = decode(int, fields) order.auctionStrategy = decode(int, fields) # ver 9 field order.startingPrice = decode(float, fields, SHOW_UNSET) # ver 9 field order.stockRefPrice = decode(float, fields, SHOW_UNSET) # ver 9 field order.delta = decode(float, fields, SHOW_UNSET) # ver 9 field order.stockRangeLower = decode(float, fields, SHOW_UNSET) # ver 9 field order.stockRangeUpper = decode(float, fields, SHOW_UNSET) # ver 9 field order.displaySize = decode(int, fields) # ver 9 field #if( version < 18) { # # will never happen # /* order.rthOnly = */ readBoolFromInt() #} order.blockOrder = decode(bool, fields) # ver 9 field order.sweepToFill = decode(bool, fields) # ver 9 field order.allOrNone = decode(bool, fields) # ver 9 field order.minQty = decode(int, fields, SHOW_UNSET) # ver 9 field order.ocaType = decode(int, fields) # ver 9 field order.eTradeOnly = decode(bool, fields) # ver 9 field order.firmQuoteOnly = decode(bool, fields) # ver 9 field order.nbboPriceCap = decode(float, fields, SHOW_UNSET) # ver 9 field order.parentId = decode(int, fields) # ver 10 field order.triggerMethod = decode(int, fields) # ver 10 field order.volatility = decode(float, fields, SHOW_UNSET) # ver 11 field order.volatilityType = decode(int, fields) # ver 11 field order.deltaNeutralOrderType = decode(str, fields) # ver 11 field (had a hack for ver 11) order.deltaNeutralAuxPrice = decode(float, fields, SHOW_UNSET) # ver 12 field if version >= 27 and order.deltaNeutralOrderType: order.deltaNeutralConId = decode(int, fields) order.deltaNeutralSettlingFirm = decode(str, fields) order.deltaNeutralClearingAccount = decode(str, fields) order.deltaNeutralClearingIntent = decode(str, fields) if version >= 31 and order.deltaNeutralOrderType: order.deltaNeutralOpenClose = decode(str, fields) order.deltaNeutralShortSale = decode(bool, fields) order.deltaNeutralShortSaleSlot = decode(int, fields) order.deltaNeutralDesignatedLocation = decode(str, fields) order.continuousUpdate = decode(bool, fields) # ver 11 field # will never happen #if( self.serverVersion == 26) { # order.stockRangeLower = readDouble() # order.stockRangeUpper = readDouble() #} order.referencePriceType = decode(int, fields) # ver 11 field order.trailStopPrice = decode(float, fields, SHOW_UNSET) # ver 13 field if version >= 30: order.trailingPercent = decode(float, fields, SHOW_UNSET) order.basisPoints = decode(float, fields, SHOW_UNSET) # ver 14 field order.basisPointsType = decode(int, fields, SHOW_UNSET) # ver 14 field contract.comboLegsDescrip = decode(str, fields) # ver 14 field if version >= 29: contract.comboLegsCount = decode(int, fields) if contract.comboLegsCount > 0: contract.comboLegs = [] for idxLeg in range(contract.comboLegsCount): comboLeg = ComboLeg() comboLeg.conId = decode(int, fields) comboLeg.ratio = decode(int, fields) comboLeg.action = decode(str, fields) comboLeg.exchange = decode(str, fields) comboLeg.openClose = decode(int, fields) comboLeg.shortSaleSlot = decode(int, fields) comboLeg.designatedLocation = decode(str, fields) comboLeg.exemptCode = decode(int, fields) contract.comboLegs.append(comboLeg) order.orderComboLegsCount = decode(int, fields) if order.orderComboLegsCount > 0: order.orderComboLegs = [] for idxOrdLeg in range(order.orderComboLegsCount): orderComboLeg = OrderComboLeg() orderComboLeg.price = decode(float, fields, SHOW_UNSET) order.orderComboLegs.append(orderComboLeg) if version >= 26: order.smartComboRoutingParamsCount = decode(int, fields) if order.smartComboRoutingParamsCount > 0: order.smartComboRoutingParams = [] for idxPrm in range(order.smartComboRoutingParamsCount): tagValue = TagValue() tagValue.tag = decode(str, fields) tagValue.value = decode(str, fields) order.smartComboRoutingParams.append(tagValue) if version >= 20: order.scaleInitLevelSize = decode(int, fields, SHOW_UNSET) order.scaleSubsLevelSize = decode(int, fields, SHOW_UNSET) else: # ver 15 fields order.notSuppScaleNumComponents = decode(int, fields, SHOW_UNSET) order.scaleInitLevelSize = decode(int, fields, SHOW_UNSET) # scaleComponectSize order.scalePriceIncrement = decode(float, fields, SHOW_UNSET) # ver 15 field if version >= 28 and order.scalePriceIncrement != UNSET_DOUBLE \ and order.scalePriceIncrement > 0.0: order.scalePriceAdjustValue = decode(float, fields, SHOW_UNSET) order.scalePriceAdjustInterval = decode(int, fields, SHOW_UNSET) order.scaleProfitOffset = decode(float, fields, SHOW_UNSET) order.scaleAutoReset = decode(bool, fields) order.scaleInitPosition = decode(int, fields, SHOW_UNSET) order.scaleInitFillQty = decode(int, fields, SHOW_UNSET) order.scaleRandomPercent = decode(bool, fields) if version >= 24: order.hedgeType = decode(str, fields) if order.hedgeType: order.hedgeParam = decode(str, fields) if version >= 25: order.optOutSmartRouting = decode(bool, fields) order.clearingAccount = decode(str, fields) # ver 19 field order.clearingIntent = decode(str, fields) # ver 19 field if version >= 22: order.notHeld = decode(bool, fields) if version >= 20: contract.underCompPresent = decode(bool, fields) if contract.underCompPresent: contract.underComp = UnderComp() contract.underComp.conId = decode(int, fields) contract.underComp.delta = decode(float, fields) contract.underComp.price = decode(float, fields) if version >= 21: order.algoStrategy = decode(str, fields) if order.algoStrategy: order.algoParamsCount = decode(int, fields) if order.algoParamsCount > 0: order.algoParams = [] for idxAlgoPrm in range(order.algoParamsCount): tagValue = TagValue() tagValue.tag = decode(str, fields) tagValue.value = decode(str, fields) order.algoParams.append(tagValue) if version >= 33: order.solicited = decode(bool, fields) orderState = OrderState() order.whatIf = decode(bool, fields) # ver 16 field orderState.status = decode(str, fields) # ver 16 field orderState.initMargin = decode(str, fields) # ver 16 field orderState.maintMargin = decode(str, fields) # ver 16 field orderState.equityWithLoan = decode(str, fields) # ver 16 field orderState.commission = decode(float, fields, SHOW_UNSET) # ver 16 field orderState.minCommission = decode(float, fields, SHOW_UNSET) # ver 16 field orderState.maxCommission = decode(float, fields, SHOW_UNSET) # ver 16 field orderState.commissionCurrency = decode(str, fields) # ver 16 field orderState.warningText = decode(str, fields) # ver 16 field if version >= 34: order.randomizeSize = decode(bool, fields) order.randomizePrice = decode(bool, fields) if self.serverVersion >= MIN_SERVER_VER_PEGGED_TO_BENCHMARK: if order.orderType == "PEG BENCH": order.referenceContractId = decode(int, fields) order.isPeggedChangeAmountDecrease = decode(bool, fields) order.peggedChangeAmount = decode(float, fields) order.referenceChangeAmount = decode(float, fields) order.referenceExchangeId = decode(str, fields) order.conditionsSize = decode(int, fields) if order.conditionsSize > 0: order.conditions = [] for idxCond in range(order.conditionsSize): order.conditionType = decode(int, fields) condition = order_condition.Create(order.conditionType) condition.decode(fields) order.conditions.append(condition) order.conditionsIgnoreRth = decode(bool, fields) order.conditionsCancelOrder = decode(bool, fields) order.adjustedOrderType = decode(str, fields) order.triggerPrice = decode(float, fields) order.trailStopPrice = decode(float, fields) order.lmtPriceOffset = decode(float, fields) order.adjustedStopPrice = decode(float, fields) order.adjustedStopLimitPrice = decode(float, fields) order.adjustedTrailingAmount = decode(float, fields) order.adjustableTrailingUnit = decode(int, fields) if self.serverVersion >= MIN_SERVER_VER_SOFT_DOLLAR_TIER: name = decode(str, fields) value = decode(str, fields) displayName = decode(str, fields) order.softDollarTier = SoftDollarTier(name, value, displayName) self.wrapper.openOrder(order.orderId, contract, order, orderState)