Skip to content

reqContractDetails called on BAG contracts after ib_async migration — combo/roll orders dropped from broker order view, console spammed with IB warnings #1639

Description

@rorymac

Summary

After the ib_insync → ib_async migration, viewing the broker order stack with a live combo/spread (roll) order produces a stream of ib_async.wrapper warnings, and the combo order is silently omitted from the displayed list.

Steps to reproduce

  1. Have a live futures spread/roll order at IB (IB represents these as a BAG contract).
  2. Run interactive_order_stack → 0 (View) → 4 (View IB orders and fills).

Observed behaviour

WARNING ib_async.wrapper Warning 2104, reqId -1: Market data farm connection is OK:cafarm
... (2104 / 2106 / 2158 messages) ...
WARNING ib_async.wrapper Warning 321, reqId 664678: Error validating request.-'bI' :
cause - 'BAG' isn't supported for contract data request. Please enter a valid
security type, contract: Bag(conId=..., symbol='HE', ..., comboLegs=[...])

The combo order does not appear in the order list.

Root cause

_create_broker_control_order_object (sysbrokers/IB/ib_orders.py) passes the raw contract to the instrument-code lookup:

ib_contract = trade_with_contract_from_ib.ibcontract_with_legs.ibcontract
instrument_code = self.futures_instrument_data.get_instrument_code_from_broker_contract_object(ib_contract)

For a combo order that ib_contract is a BAG. The lookup chain ends at ibClient._get_contract_details → self.ib.reqContractDetails(BAG). IB's API does not support reqContractDetails on a BAG contract (Warning 321), so it returns
nothing → missingContract → caught by the bare except in _create_broker_control_order_object → order skipped as "usual behaviour for FX and equities trades".

So a system's own roll orders are silently dropped from "View IB orders and fills". This is a long-standing logic issue, but it was previously masked: commit 741906a ("remove error reporting from ib_client. we get same messages
direct from logger"), part of the ib_async migration, deleted ibClient.error_handler, which used to intercept and filter IB messages. Now ib_async's own logger emits every IB message — including the BAG warning and the harmless
2104/2106/2158 "connection is OK" notices — straight to the console at WARNING level.

Two separable problems

  1. Combo orders dropped / spurious Warning 321. reqContractDetails should never be called on a BAG. Each resolved leg (already available in ibcontract_with_legs.legs) is an ordinary futures contract for the same instrument and
    can be used for the instrument-code lookup instead.
  2. Console noise. With error_handler removed, routine IB informational warnings (2104/2106/2158) now print at WARNING level on every connection. Consider re-adding a lightweight handler or filtering these, or documenting the
    expected log output.

Suggested fix for (1)

When the contract is a BAG with resolved legs, identify the instrument from the first leg rather than the BAG:

def _ib_contract_for_instrument_lookup(ibcontract_with_legs):
ib_contract = ibcontract_with_legs.ibcontract
legs = ibcontract_with_legs.legs
if getattr(ib_contract, "secType", "") == "BAG" and len(legs) > 0:
return legs[0]
return ib_contract

…and call it in _create_broker_control_order_object. Happy to open a PR if useful.

Environment

  • pysystemtrade develop (post ib_async migration, commit 741906a present)
  • ib_async 2.x
  • Python 3.10

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions