Why does TWS API recognize combo as 'OPT' not 'BAG'

301 Views Asked by At

I've successfully submitted a combo order (iron condor) through the IB API as security type 'BAG'. But when I try to retrieve the position through reqPositions, it is recognized as 'OPT' not 'BAG' and I can only see the strike of one of the legs.

Here's my code for the submission:

long_put_contract = app.get_contract_details(102, long_put_contract) 
        short_put_contract = app.get_contract_details(103, short_put_contract) 
        short_call_contract = app.get_contract_details(104, short_call_contract) 
        long_call_contract = app.get_contract_details(105, long_call_contract) 

        combo_contract = Contract()
        combo_contract.symbol = short_put_contract.symbol
        combo_contract.secType = 'BAG'
        combo_contract.currency = short_put_contract.currency
        combo_contract.exchange = short_put_contract.exchange
        
        leg1 = ComboLeg()
        leg1.conId = long_put_contract.conId
        leg1.ratio = 1
        leg1.action = 'BUY'
        leg1.exchange = long_put_contract.exchange
        
        leg2 = ComboLeg()
        leg2.conId = short_put_contract.conId #DBK MAR 15 2019 C
        leg2.ratio = 1
        leg2.action = 'SELL'
        leg2.exchange = short_put_contract.exchange
        
        leg3 = ComboLeg()
        leg3.conId = short_call_contract.conId #DBK MAR 15 2019 C
        leg3.ratio = 1
        leg3.action = 'SELL'
        leg3.exchange = short_call_contract.exchange
        
        leg4 = ComboLeg()
        leg4.conId = long_call_contract.conId #DBK MAR 15 2019 C
        leg4.ratio = 1
        leg4.action = 'BUY'
        leg4.exchange = long_call_contract.exchange
        
        combo_contract.comboLegs = []
        combo_contract.comboLegs.append(leg1)
        combo_contract.comboLegs.append(leg2)
        combo_contract.comboLegs.append(leg3)
        combo_contract.comboLegs.append(leg4)

...

        trade = app.placeOrder(order.orderId, combo_contract, order)

which follows all the examples I've seen online. But when I retrieve the position through this code:

    def position(self, account: str, contract: Contract, position: float, avgCost: float):
        super().position(account, contract, position, avgCost)
        global positions
        pos = Position(contract.symbol)
        pos.position = position
        pos.sec_type = contract.secType
        pos.currency = contract.currency
        pos.strike = contract.strike
        pos.lastTradeDateOrContractMonth = contract.lastTradeDateOrContractMonth
        pos.comboLegs = contract.comboLegs
        positions[contract.symbol] = pos
        
    def positionEnd(self):
        super().positionEnd()
        print("Done fetching positions.")
        global position_end
        position_end = True

    def get_positions(self):
        global position_end
        position_end = False
        self.reqPositions()
        while not position_end:
            time.sleep(0.1)
        global positions
        return positions


my_positions = app.get_positions()

for symbol in my_positions:
    position = my_positions[symbol]
    print(position)

I get the following:

Symbol: SPY Currency: USD Position: 3.0 Sec Type: OPT Strike (if option): 424.0 Expiry (if option): 20230614 Combo Legs: None

It should recognize the combo legs, and the security type should be 'BAG'. I think the issue is with how I've defined the wrapper functions but I'm not sure where I went wrong.

Help!

Thanks

Chris

1

There are 1 best solutions below

0
chenju On

The tws reqPositions api doesn't recognize combo leg. see the decode method(in java api), we can't find combo leg decode ops.

    int version = readInt();
    String account = readStr();

    Contract contract = new Contract();
    contract.conid(readInt());
    contract.symbol(readStr());
    contract.secType(readStr());
    contract.lastTradeDateOrContractMonth(readStr());
    contract.strike(readDouble());
    contract.right(readStr());
    contract.multiplier(readStr());
    contract.exchange(readStr());
    contract.currency(readStr());
    contract.localSymbol(readStr());
    if (version >= 2) {
        contract.tradingClass(readStr());
    }

    Decimal pos = readDecimal();
    double avgCost = 0;
    if (version >= 3) {
        avgCost = readDouble();
    }