erdewit / ib_insync

Python sync/async framework for Interactive Brokers API
BSD 2-Clause "Simplified" License
2.75k stars 723 forks source link

Getting Error 478 on options expiring in Feb - leap year. #693

Closed reservoirinvest closed 4 months ago

reservoirinvest commented 4 months ago

I have some option positions in my portfolio and extract it using the following function:

def quick_pf(ib):
    pf = ib.portfolio() 
    if pf != []:
        df_pf = util.df(pf)
        df_pf = df_pf.assign(conttract=df_pf.contract)
    else:
        df_pf = None
   return df_pf

when an option contract in df_pf is qualified using ib.qualifyContracts, it works fine and gives me, like this one below: Contract(secType='OPT', conId=679139121, symbol='ABNB', lastTradeDateOrContractMonth='20240217', strike=124.0, right='P', multiplier='100', exchange='SMART'). Note that the expiry date is wrong. ref: this yahoo link

... but when I remove the conId , the qualifyContracts fails and it gives me an Unknown contracts error.

... running the wrong expiry dated conId contract through ib.whatIfOrderAsync(wrong_expiry_dt_contract, Order('SELL', 100)) throws the undocumented Error 478 exception:
Parameters in request conflicts with contract parameters received by contract id: requested expiry 20240217, in contract 20240216;

I don't get the error in options expiring in March 2024.

  1. Is this error in the portfolio due to leap-year?
  2. Can ib.qualifyContracts / ib.qualifyContractsAsync be tightened to replace the lastTradeDateOrContractMonth with correct expiry, if Contract(conId=679139121, lastTradeDateOrContractMonth='20240217') is given?
reservoirinvest commented 4 months ago

It looks like Leap Year is not the issue. Could be solved reconstructing the option contract, using ContractDetails.realExpirationDate instead of lastTradeDateOrContractMonth. However, an easier way, as suggested here , is to change the timezone to US Central Time.