Back to Ib Api Reloaded

Source code for ib_async.order

ib-underscore-async-underscore-modules-ib-underscore-async-order.md

latest16.2 KB
Original Source

Source code for ib_async.order

"""Order types used by Interactive Brokers."""from \_\_future\_\_ importannotationsimport dataclassesfrom dataclasses importdataclass,fieldfrom decimal importDecimalfrom typing importClassVar,NamedTuplefrom eventkit importEventfrom .contract importContract,TagValuefrom .objects importFill,SoftDollarTier,TradeLogEntryfrom .util importUNSET\_DOUBLE,UNSET\_INTEGER,dataclassNonDefaults
[[docs]](../../api.html#ib_async.order.Order)@dataclassclass Order:""" Order for trading contracts. https://interactivebrokers.github.io/tws-api/available\_orders.html """orderId: int = 0clientId: int = 0permId: int = 0action: str = ""totalQuantity: float = 0.0orderType: str = ""lmtPrice: float | Decimal | None = UNSET\_DOUBLEauxPrice: float | Decimal | None = UNSET\_DOUBLEtif: str = ""activeStartTime: str = ""activeStopTime: str = ""ocaGroup: str = ""ocaType: int = 0orderRef: str = ""transmit: bool = TrueparentId: int = 0blockOrder: bool = FalsesweepToFill: bool = FalsedisplaySize: int = 0triggerMethod: int = 0outsideRth: bool = Falsehidden: bool = FalsegoodAfterTime: str = ""goodTillDate: str = ""rule80A: str = ""allOrNone: bool = FalseminQty: int = UNSET\_INTEGERpercentOffset: float | Decimal = UNSET\_DOUBLEoverridePercentageConstraints: bool = FalsetrailStopPrice: float | Decimal = UNSET\_DOUBLEtrailingPercent: float | Decimal = UNSET\_DOUBLEfaGroup: str = ""faProfile: str = ""# obsoletefaMethod: str = ""faPercentage: str = ""designatedLocation: str = ""openClose: str = "O"origin: int = 0shortSaleSlot: int = 0exemptCode: int = -1discretionaryAmt: float = 0.0eTradeOnly: bool = FalsefirmQuoteOnly: bool = FalsenbboPriceCap: float | Decimal = UNSET\_DOUBLEoptOutSmartRouting: bool = FalseauctionStrategy: int = 0startingPrice: float | Decimal = UNSET\_DOUBLEstockRefPrice: float | Decimal = UNSET\_DOUBLEdelta: float | Decimal = UNSET\_DOUBLEstockRangeLower: float | Decimal = UNSET\_DOUBLEstockRangeUpper: float | Decimal = UNSET\_DOUBLErandomizePrice: bool = FalserandomizeSize: bool = Falsevolatility: float | Decimal = UNSET\_DOUBLEvolatilityType: int = UNSET\_INTEGERdeltaNeutralOrderType: str = ""deltaNeutralAuxPrice: float | Decimal = UNSET\_DOUBLEdeltaNeutralConId: int = 0deltaNeutralSettlingFirm: str = ""deltaNeutralClearingAccount: str = ""deltaNeutralClearingIntent: str = ""deltaNeutralOpenClose: str = ""deltaNeutralShortSale: bool = FalsedeltaNeutralShortSaleSlot: int = 0deltaNeutralDesignatedLocation: str = ""continuousUpdate: bool = FalsereferencePriceType: int = UNSET\_INTEGERbasisPoints: float | Decimal = UNSET\_DOUBLEbasisPointsType: int = UNSET\_INTEGERscaleInitLevelSize: int = UNSET\_INTEGERscaleSubsLevelSize: int = UNSET\_INTEGERscalePriceIncrement: float | Decimal = UNSET\_DOUBLEscalePriceAdjustValue: float | Decimal = UNSET\_DOUBLEscalePriceAdjustInterval: int = UNSET\_INTEGERscaleProfitOffset: float | Decimal = UNSET\_DOUBLEscaleAutoReset: bool = FalsescaleInitPosition: int = UNSET\_INTEGERscaleInitFillQty: int = UNSET\_INTEGERscaleRandomPercent: bool = FalsescaleTable: str = ""hedgeType: str = ""hedgeParam: str = ""account: str = ""settlingFirm: str = ""clearingAccount: str = ""clearingIntent: str = ""algoStrategy: str = ""algoParams: list[TagValue] = field(default\_factory=list)smartComboRoutingParams: list[TagValue] = field(default\_factory=list)algoId: str = ""whatIf: bool = FalsenotHeld: bool = Falsesolicited: bool = FalsemodelCode: str = ""orderComboLegs: list[OrderComboLeg] = field(default\_factory=list)orderMiscOptions: list[TagValue] = field(default\_factory=list)referenceContractId: int = 0peggedChangeAmount: float = 0.0isPeggedChangeAmountDecrease: bool = FalsereferenceChangeAmount: float = 0.0referenceExchangeId: str = ""adjustedOrderType: str = ""triggerPrice: float | Decimal | None = UNSET\_DOUBLEadjustedStopPrice: float | Decimal = UNSET\_DOUBLEadjustedStopLimitPrice: float | Decimal = UNSET\_DOUBLEadjustedTrailingAmount: float | Decimal = UNSET\_DOUBLEadjustableTrailingUnit: int = 0lmtPriceOffset: float | Decimal = UNSET\_DOUBLEconditions: list[OrderCondition] = field(default\_factory=list)conditionsCancelOrder: bool = FalseconditionsIgnoreRth: bool = FalseextOperator: str = ""softDollarTier: SoftDollarTier = field(default\_factory=SoftDollarTier)cashQty: float | Decimal = UNSET\_DOUBLEmifid2DecisionMaker: str = ""mifid2DecisionAlgo: str = ""mifid2ExecutionTrader: str = ""mifid2ExecutionAlgo: str = ""dontUseAutoPriceForHedge: bool = FalseisOmsContainer: bool = FalsediscretionaryUpToLimitPrice: bool = FalseautoCancelDate: str = ""filledQuantity: float | Decimal = UNSET\_DOUBLErefFuturesConId: int = 0autoCancelParent: bool = Falseshareholder: str = ""imbalanceOnly: bool = FalserouteMarketableToBbo: bool = FalseparentPermId: int = 0usePriceMgmtAlgo: bool = Falseduration: int = UNSET\_INTEGERpostToAts: int = UNSET\_INTEGERadvancedErrorOverride: str = ""manualOrderTime: str = ""minTradeQty: int = UNSET\_INTEGERminCompeteSize: int = UNSET\_INTEGERcompeteAgainstBestOffset: float | Decimal = UNSET\_DOUBLEmidOffsetAtWhole: float | Decimal = UNSET\_DOUBLEmidOffsetAtHalf: float | Decimal = UNSET\_DOUBLEdef \_\_repr\_\_(self):attrs = dataclassNonDefaults(self)if self.\_\_class\_\_ is not Order:attrs.pop("orderType", None)if not self.softDollarTier:attrs.pop("softDollarTier")clsName = self.\_\_class\_\_.\_\_qualname\_\_kwargs = ", ".join(f"{k}={v!r}" for k, v in attrs.items())return f"{clsName}({kwargs})"\_\_str\_\_ = \_\_repr\_\_def \_\_eq\_\_(self, other):return self is otherdef \_\_hash\_\_(self):return id(self)

[[docs]](../../api.html#ib_async.order.LimitOrder)class LimitOrder(Order):def \_\_init\_\_(self, action: str, totalQuantity: float, lmtPrice: float, \*\*kwargs):Order.\_\_init\_\_(self,orderType="LMT",action=action,totalQuantity=totalQuantity,lmtPrice=lmtPrice,\*\*kwargs,)

[[docs]](../../api.html#ib_async.order.MarketOrder)class MarketOrder(Order):def \_\_init\_\_(self, action: str, totalQuantity: float, \*\*kwargs):Order.\_\_init\_\_(self, orderType="MKT", action=action, totalQuantity=totalQuantity, \*\*kwargs)

[[docs]](../../api.html#ib_async.order.StopOrder)class StopOrder(Order):def \_\_init\_\_(self, action: str, totalQuantity: float, stopPrice: float, \*\*kwargs):Order.\_\_init\_\_(self,orderType="STP",action=action,totalQuantity=totalQuantity,auxPrice=stopPrice,\*\*kwargs,)

[[docs]](../../api.html#ib_async.order.StopLimitOrder)class StopLimitOrder(Order):def \_\_init\_\_(self,action: str,totalQuantity: float,lmtPrice: float,stopPrice: float,\*\*kwargs,):Order.\_\_init\_\_(self,orderType="STP LMT",action=action,totalQuantity=totalQuantity,lmtPrice=lmtPrice,auxPrice=stopPrice,\*\*kwargs,)

[[docs]](../../api.html#ib_async.order.OrderStatus)@dataclassclass OrderStatus:orderId: int = 0status: str = ""filled: float = 0.0remaining: float = 0.0avgFillPrice: float = 0.0permId: int = 0parentId: int = 0lastFillPrice: float = 0.0clientId: int = 0whyHeld: str = ""mktCapPrice: float = 0.0@propertydef total(self) -\> float:"""Helper property to return the total size of this requested order."""return self.filled + self.remainingPendingSubmit: ClassVar[str] = "PendingSubmit"PendingCancel: ClassVar[str] = "PendingCancel"PreSubmitted: ClassVar[str] = "PreSubmitted"Submitted: ClassVar[str] = "Submitted"ApiPending: ClassVar[str] = "ApiPending"ApiCancelled: ClassVar[str] = "ApiCancelled"ApiUpdate: ClassVar[str] = "ApiUpdate"Cancelled: ClassVar[str] = "Cancelled"Filled: ClassVar[str] = "Filled"Inactive: ClassVar[str] = "Inactive"ValidationError: ClassVar[str] = "ValidationError"# order has either been completed, cancelled, or destroyed by IBKR's risk managementDoneStates: ClassVar[frozenset[str]] = frozenset(["Filled", "Cancelled", "ApiCancelled", "Inactive"])# order is capable of executing at sometime in the futureActiveStates: ClassVar[frozenset[str]] = frozenset(["PendingSubmit","ApiPending","PreSubmitted","Submitted","ValidationError","ApiUpdate",])# order hasn't triggered "live" yet (but it could become live and execute before we receive a notice)WaitingStates: ClassVar[frozenset[str]] = frozenset(["PendingSubmit","ApiPending","PreSubmitted",])# order is live and "working" at the broker against public exchangesWorkingStates: ClassVar[frozenset[str]] = frozenset(["Submitted",# ValidationError can happen on submit or modify.# If ValidationError happens on submit, the states go PreSubmitted -\> ValidationError -\> Submitted (if it can be ignored automatically), so order is still live.# If ValidationError happens on modify, the update is just ValidationError with no new Submitted, so the previous order state remains active."ValidationError","ApiUpdate",])

[[docs]](../../api.html#ib_async.order.OrderState)@dataclassclass OrderState:status: str = ""initMarginBefore: str = ""maintMarginBefore: str = ""equityWithLoanBefore: str = ""initMarginChange: str = ""maintMarginChange: str = ""equityWithLoanChange: str = ""initMarginAfter: str = ""maintMarginAfter: str = ""equityWithLoanAfter: str = ""commission: float = UNSET\_DOUBLEminCommission: float = UNSET\_DOUBLEmaxCommission: float = UNSET\_DOUBLEcommissionCurrency: str = ""warningText: str = ""completedTime: str = ""completedStatus: str = ""
[[docs]](../../api.html#ib_async.order.OrderState.transform)def transform(self, transformer):"""Convert the numeric values of this OrderState into a new OrderState transformed by 'using'"""return dataclasses.replace(self,initMarginBefore=transformer(self.initMarginBefore),maintMarginBefore=transformer(self.maintMarginBefore),equityWithLoanBefore=transformer(self.equityWithLoanBefore),initMarginChange=transformer(self.initMarginChange),maintMarginChange=transformer(self.maintMarginChange),equityWithLoanChange=transformer(self.equityWithLoanChange),initMarginAfter=transformer(self.initMarginAfter),maintMarginAfter=transformer(self.maintMarginAfter),equityWithLoanAfter=transformer(self.equityWithLoanAfter),commission=transformer(self.commission),minCommission=transformer(self.minCommission),maxCommission=transformer(self.maxCommission),)

[[docs]](../../api.html#ib_async.order.OrderState.numeric)def numeric(self, digits: int = 2) -\> OrderStateNumeric:"""Return a new OrderState with the current values values to floats instead of strings as returned from IBKR directly."""def floatOrNone(what, precision) -\> float | None:"""Attempt to convert input to a float, but if we fail (value is just empty string) return None"""try:# convertfloated = float(what)# if the conversion is IBKR speak for "this value is not set" then give us Noneif floated == UNSET\_DOUBLE:return None# else, round to the requested precisionreturn round(floated, precision)except Exception as \_:# initial conversion failed so just return None in its placereturn Nonereturn self.transform(lambda x: floatOrNone(x, digits))

[[docs]](../../api.html#ib_async.order.OrderState.formatted)def formatted(self, digits: int = 2):"""Return a new OrderState with the current values as formatted strings."""return self.numeric(8).transform(# 300000.21 -\> 300,000.21# 0.0 -\> 0.00# 431.342000000001 -\> 431.34# Note: we need 'is not None' here because 'x=0' is a valid numeric input toolambda x: f"{x:,.{digits}f}" if x is not None else None)

[[docs]](../../api.html#ib_async.order.OrderStateNumeric)@dataclassclass OrderStateNumeric(OrderState):"""Just a type helper for mypy to check against if you convert OrderState to .numeric(). Usage: state\_numeric: OrderStateNumeric = state.numeric(digits=2)"""initMarginBefore: float = float("nan")# type: ignoremaintMarginBefore: float = float("nan")# type: ignoreequityWithLoanBefore: float = float("nan")# type: ignoreinitMarginChange: float = float("nan")# type: ignoremaintMarginChange: float = float("nan")# type: ignoreequityWithLoanChange: float = float("nan")# type: ignoreinitMarginAfter: float = float("nan")# type: ignoremaintMarginAfter: float = float("nan")# type: ignoreequityWithLoanAfter: float = float("nan")# type: ignore

[[docs]](../../api.html#ib_async.order.OrderComboLeg)@dataclassclass OrderComboLeg:price: float | Decimal = UNSET\_DOUBLE

[[docs]](../../api.html#ib_async.order.Trade)@dataclassclass Trade:""" Trade keeps track of an order, its status and all its fills. Events: \* ``statusEvent`` (trade: :class:`.Trade`) \* ``modifyEvent`` (trade: :class:`.Trade`) \* ``fillEvent`` (trade: :class:`.Trade`, fill: :class:`.Fill`) \* ``commissionReportEvent`` (trade: :class:`.Trade`, fill: :class:`.Fill`, commissionReport: :class:`.CommissionReport`) \* ``filledEvent`` (trade: :class:`.Trade`) \* ``cancelEvent`` (trade: :class:`.Trade`) \* ``cancelledEvent`` (trade: :class:`.Trade`) """contract: Contract = field(default\_factory=Contract)order: Order = field(default\_factory=Order)orderStatus: OrderStatus = field(default\_factory=OrderStatus)fills: list[Fill] = field(default\_factory=list)log: list[TradeLogEntry] = field(default\_factory=list)advancedError: str = ""# TODO: replace these with an enum?events: ClassVar = ("statusEvent","modifyEvent","fillEvent","commissionReportEvent","filledEvent","cancelEvent","cancelledEvent",)def \_\_post\_init\_\_(self):self.statusEvent = Event("statusEvent")self.modifyEvent = Event("modifyEvent")self.fillEvent = Event("fillEvent")self.commissionReportEvent = Event("commissionReportEvent")self.filledEvent = Event("filledEvent")self.cancelEvent = Event("cancelEvent")self.cancelledEvent = Event("cancelledEvent")
[[docs]](../../api.html#ib_async.order.Trade.isWaiting)def isWaiting(self) -\> bool:"""True if sent to IBKR but not "Submitted" for live execution yet."""return self.orderStatus.status in OrderStatus.WaitingStates

[[docs]](../../api.html#ib_async.order.Trade.isWorking)def isWorking(self) -\> bool:"""True if sent to IBKR but not "Submitted" for live execution yet."""return self.orderStatus.status in OrderStatus.WorkingStates

[[docs]](../../api.html#ib_async.order.Trade.isActive)def isActive(self) -\> bool:"""True if eligible for execution, false otherwise."""return self.orderStatus.status in OrderStatus.ActiveStates

[[docs]](../../api.html#ib_async.order.Trade.isDone)def isDone(self) -\> bool:"""True if completely filled or cancelled, false otherwise."""return self.orderStatus.status in OrderStatus.DoneStates

[[docs]](../../api.html#ib_async.order.Trade.filled)def filled(self) -\> float:"""Number of shares filled."""fills = self.fillsif self.contract.secType == "BAG":# don't count fills for the leg contractsfills = [f for f in fills if f.contract.secType == "BAG"]return sum([f.execution.shares for f in fills])

[[docs]](../../api.html#ib_async.order.Trade.remaining)def remaining(self) -\> float:"""Number of shares remaining to be filled."""return float(self.order.totalQuantity) - self.filled()

[[docs]](../../api.html#ib_async.order.BracketOrder)class BracketOrder(NamedTuple):parent: OrdertakeProfit: OrderstopLoss: Order

[[docs]](../../api.html#ib_async.order.OrderCondition)@dataclassclass OrderCondition:
[[docs]](../../api.html#ib_async.order.OrderCondition.createClass)@staticmethoddef createClass(condType):d = {1: PriceCondition,3: TimeCondition,4: MarginCondition,5: ExecutionCondition,6: VolumeCondition,7: PercentChangeCondition,}return d[condType]

[[docs]](../../api.html#ib_async.order.OrderCondition.And)def And(self):self.conjunction = "a"return self

[[docs]](../../api.html#ib_async.order.OrderCondition.Or)def Or(self):self.conjunction = "o"return self

[[docs]](../../api.html#ib_async.order.PriceCondition)@dataclassclass PriceCondition(OrderCondition):condType: int = 1conjunction: str = "a"isMore: bool = Trueprice: float = 0.0conId: int = 0exch: str = ""triggerMethod: int = 0

[[docs]](../../api.html#ib_async.order.TimeCondition)@dataclassclass TimeCondition(OrderCondition):condType: int = 3conjunction: str = "a"isMore: bool = Truetime: str = ""

[[docs]](../../api.html#ib_async.order.MarginCondition)@dataclassclass MarginCondition(OrderCondition):condType: int = 4conjunction: str = "a"isMore: bool = Truepercent: int = 0

[[docs]](../../api.html#ib_async.order.ExecutionCondition)@dataclassclass ExecutionCondition(OrderCondition):condType: int = 5conjunction: str = "a"secType: str = ""exch: str = ""symbol: str = ""

[[docs]](../../api.html#ib_async.order.VolumeCondition)@dataclassclass VolumeCondition(OrderCondition):condType: int = 6conjunction: str = "a"isMore: bool = Truevolume: int = 0conId: int = 0exch: str = ""

[[docs]](../../api.html#ib_async.order.PercentChangeCondition)@dataclassclass PercentChangeCondition(OrderCondition):condType: int = 7conjunction: str = "a"isMore: bool = TruechangePercent: float = 0.0conId: int = 0exch: str = ""