Error IB API

Discussion in 'Automated Trading' started by Leopard9, Sep 25, 2024.

  1. Leopard9

    Leopard9

    Thanks! Will that fix or just print information?
     
    #61     Sep 30, 2024
  2. d08

    d08

    It will print the string, required to diagnose what's wrong.
     
    #62     Sep 30, 2024
    Leopard9 likes this.
  3. Leopard9

    Leopard9


    ahhhhh... Like this?

    upload_2024-9-30_19-20-45.png
     
    #63     Sep 30, 2024
  4. Leopard9

    Leopard9

    This is what I got in one of the orders:

    upload_2024-9-30_19-25-56.png

    Still crashed.
     
    #64     Sep 30, 2024
  5. d08

    d08

    Paste code in appropriate tags, I don't want to rewrite everything.

    original_order_id is splitting 20240930120328_ENTRY, you're getting the first returned value which is "ENTRY" and trying to get an integer of it (it's a string).
     
    #65     Sep 30, 2024
    Leopard9 likes this.
  6. Leopard9

    Leopard9


    Sorry my bad. Should I erase the word entry? From where?

    Thanks for your help man, really.

    Here is the full code:

    def initialise_trade_list_from_broker_data(self):
    # if orders are found at the broker that do not correspond to a trade in the trade list, a trade record is made.
    # This will happen when the software is restarted, and there are existing trades from the previous run.

    trade_order_refs = [t.entry_order.orderRef for t in self.trade_list] + \
    [t.profit_order.orderRef for t in self.trade_list] + \
    [t.stop_loss_order.orderRef for t in self.trade_list]

    # Gather orphaned callbacks

    # FORMATS OF CALLBACK VARIABLES:
    # self.raw_open_orders[order.orderRef] = [orderId, contract, order, orderState]
    # self.raw_order_status[permId] = [orderId, status, filled, remaining, avgFillPrice, permId, parentId,
    # lastFillPrice, clientId, whyHeld, mktCapPrice]
    # self.raw_completed_orders[order.orderRef] = [contract, order, orderState]
    # main_order.orderRef = f'{self.trade_id}_{entry_order_id}_{self.datetime_stamp}_ENTRY_{cancel_price}'

    with self.ib.order_id_lock:
    success = False
    while not success:
    self.ib.verify_connection(ignore_market_data=True)
    self.ib.reqOpenOrders()
    self.ib.reqCompletedOrders(True)
    success = True
    if not self.ib.event_open_order_end.is_set() and not self.ib.event_open_order_end.wait(5):
    success = False
    if not self.ib.event_completed_order_end.is_set() and not self.ib.event_completed_order_end.wait(5):
    success = False
    if not success:
    LOG.warning(f'{self.contract_ticker} ~ api ~ Could not retrieve open/completed orders. Check '
    f'connection. Will try again in 60 seconds')
    sleeper.sleep(60)

    orphaned_open_orders = {k: v for k, v in self.ib.raw_open_orders.items()
    if k not in trade_order_refs
    and v[1].symbol == self.contract_ticker}
    orphaned_completed_orders = {k: v for k, v in self.ib.raw_completed_orders.items()
    if k not in trade_order_refs
    and v[0].symbol == self.contract_ticker}
    # orphaned_order_statuses = {k: v for k, v in self.raw_order_status.items() if k not in trade_order_ids}

    # combine orphaned open orders and orphaned completed orders
    orphaned_orders = dict()
    for order_ref, order_details in orphaned_completed_orders.items():
    orphaned_orders[order_ref] = [None] + order_details # make consistent with openOrder callback format
    for order_ref, order_details in orphaned_open_orders.items():
    if order_ref not in orphaned_orders.keys(): # only add orders that are not already found in completed dict
    orphaned_orders[order_ref] = order_details

    # reconstruct trades from orphaned callbacks
    reconstructed_trades = []
    for entry_order_ref, order_details in orphaned_orders.items():
    if 'ENTRY' in entry_order_ref:

    # Print the entry_order_ref string
    print(f"Entry Order Reference: {entry_order_ref}")

    # collect trade parameters
    contract = order_details[1]
    entry_order_object = order_details[2]
    trade_id = int(entry_order_ref.split('_')[0])
    original_order_id = int(entry_order_ref.split('_')[1])
    cancel_price = float(entry_order_ref.split('_')[4])

    # find associated stop loss order and profit taking order
    child_order_objects = dict()
    not_found = False
    for order_type_text in ['STOP_LOSS', 'PROFIT_TARGET']:
    # look in completed orders first
    child_order_objects[order_type_text] = [v[1] for k, v in self.ib.raw_completed_orders.items()
    if '_' in k and
    int(k.split('_')[0]) == trade_id
    and order_type_text in k]
    if not child_order_objects[order_type_text]:
    # if no completed order, search for an open order
    child_order_objects[order_type_text] = [v[2] for k, v in self.ib.raw_open_orders.items()
    if '_' in k and int(k.split('_')[0]) == trade_id
    and order_type_text in k]
    if not child_order_objects[order_type_text]:
    not_found = True
    else:
    child_order_objects[order_type_text] = child_order_objects[order_type_text][0]
    if not_found:
    continue

    assert isinstance(entry_order_object, Order)
    assert isinstance(child_order_objects['STOP_LOSS'], Order)
    assert isinstance(child_order_objects['PROFIT_TARGET'], Order)

    # rebuild the trade record
    t = Trade(entry_order_id=original_order_id,
    contract=contract,
    entry_action=entry_order_object.action,
    quantity=entry_order_object.totalQuantity,
    limit_price=entry_order_object.lmtPrice,
    trigger_price=entry_order_object.auxPrice,
    take_profit_price=child_order_objects['PROFIT_TARGET'],
    stop_loss_price=child_order_objects['STOP_LOSS'],
    cancel_price=cancel_price,
    trade_outside_rth=entry_order_object.outsideRth,
    manual_trade_id=trade_id)

    # overwrite __init__ generated values of Trade object
    t.datetime_stamp = entry_order_ref.split('_')[2]
    # TODO: trade_datetime must be timezone aware, to enable comparison with live trades
    t.trade_datetime = datetime.strptime(t.datetime_stamp,
    '%Y%m%d-%H%M%S').replace(tzinfo=ZoneInfo(key='US/Central'))
    t.contract = contract
    t.direction = 'LONG' if entry_order_object.action == 'BUY' else 'SHORT'
    t.entry_order.orderRef = entry_order_object.orderRef
    t.stop_loss_order.orderRef = child_order_objects['STOP_LOSS'].orderRef
    t.profit_order.orderRef = child_order_objects['PROFIT_TARGET'].orderRef
    if t.entry_order.totalQuantity == 0 and entry_order_object.filledQuantity != 0:
    t.entry_order.totalQuantity = entry_order_object.filledQuantity

    # append to reconstructed trades list

    status = t.status_at_broker(self.ib)
    if status in ['OPEN', 'ACTIVE']:
    LOG.info(f'{self.contract_ticker} ~ reconstruction ~ Reconstructed a trade record from broker data '
    f'for trade id {t.trade_id}: {t.entry_order.action} '
    f'{t.entry_order.totalQuantity} x {t.contract.symbol} ' # type: ignore
    f'Status: {t.status_at_broker(self.ib)}\n\n')
    reconstructed_trades.append(t)
    else:
    pass

    # add reconstructed trades to trade_list object
    self.trade_list += reconstructed_trades

    # set next trade id
    broker_trade_ids = ([int(k.split('_')[0]) for k in self.ib.raw_completed_orders.keys()
    if k.split('_')[0].isnumeric()] +
    [int(k.split('_')[0]) for k in self.ib.raw_open_orders.keys()
    if k.split('_')[0].isnumeric()])
    with Trade.trade_object_lock:
    Trade.trade_counter = max([len(self.trade_list)] + [t.trade_id for t in self.trade_list] + broker_trade_ids)
     
    #66     Sep 30, 2024
  7. spy

    spy

    Lol, no good deed goes unpunished!

    Can you help me fix my code too please?

    Code:
    #!/usr/bin/perl
    # 472-byte qrpff, Keith Winstein and Marc Horowitz <sipb-iap-dvd@mit.edu>
    # MPEG 2 PS VOB file -> descrambled output on stdout.
    # usage: perl -I <k1>:<k2>:<k3>:<k4>:<k5> qrpff
    # where k1..k5 are the title key bytes in least to most-significant order
    
    s''$/=\2048;while(<>){G=29;R=142;if((@a=unqT="C*",_)[20]&48){D=89;_=unqb24,qT,@
    b=map{ord qB8,unqb8,qT,_^$a[--D]}@INC;s/...$/1$&/;Q=unqV,qb25,_;H=73;O=$b[4]<<9
    |256|$b[3];Q=Q>>8^(P=(E=255)&(Q>>12^Q>>4^Q/8^Q))<<17,O=O>>8^(E&(F=(S=O>>14&7^O)
    ^S*8^S<<6))<<9,_=(map{U=_%16orE^=R^=110&(S=(unqT,"\xb\ntd\xbz\x14d")[_/16%8]);E
    ^=(72,@z=(64,72,G^=12*(U-2?0:S&17)),H^=_%64?12:0,@z)[_%8]}(16..271))[_]^((D>>=8
    )+=P+(~F&E))for@a[128..$#a]}print+qT,@a}';s/[D-HO-U_]/\$$&/g;s/q/pack+/g;eval
    
    I can't figure out WTF it's doing!
     
    Last edited: Sep 30, 2024
    #67     Sep 30, 2024
    d08 likes this.
  8. Leopard9

    Leopard9

    Funny.
     
    #68     Sep 30, 2024
    spy likes this.
  9. spy

    spy

    :D:D:D:D:D

    I wonder if my post will get deleted by the moderators again for being too acerbic. Softies :p
     
    #69     Sep 30, 2024
  10. Leopard9

    Leopard9

    Maybe the moderators actually like their forum organized where people actually contribute and help each other. Think about that.
     
    #70     Sep 30, 2024