I am trying to place a limit order for each of three stocks at their current best bid and update order prices if their corresponding best bid changes and the order is not fully filled yet. 10 min before market closes if the order is still not fully filled, I will cancel them and place a market at close order with ib_insync. I got stuck in the first part.
I am using ticker event callback function and check if the order is unfilled, whether new best bid is different from old price and modify orders based on that. But I am getting errors like this.
<code>assert trade.orderStatus.status not in OrderStatus.DoneStates
AssertionError
Value (Ticker(contract=Stock(symbol='NVDA', exchange='SMART', currency='USD'), time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), marketDataType=3, minTick=0.01, bid=-1.0, bidSize=0.0, ask=-1.0, askSize=0.0, last=136.4, lastSize=100.0, volume=2943386.0, open=0.0, high=136.33, low=130.69, close=130.98, ticks=[TickData(time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), tickType=66, price=-1.0, size=0.0), TickData(time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), tickType=67, price=-1.0, size=0.0)]),) caused exception for event Event<updateEvent, [[None, None, <function onPendingTickers at 0x7fe840298280>]]>
</code>
<code>assert trade.orderStatus.status not in OrderStatus.DoneStates
AssertionError
Value (Ticker(contract=Stock(symbol='NVDA', exchange='SMART', currency='USD'), time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), marketDataType=3, minTick=0.01, bid=-1.0, bidSize=0.0, ask=-1.0, askSize=0.0, last=136.4, lastSize=100.0, volume=2943386.0, open=0.0, high=136.33, low=130.69, close=130.98, ticks=[TickData(time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), tickType=66, price=-1.0, size=0.0), TickData(time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), tickType=67, price=-1.0, size=0.0)]),) caused exception for event Event<updateEvent, [[None, None, <function onPendingTickers at 0x7fe840298280>]]>
</code>
assert trade.orderStatus.status not in OrderStatus.DoneStates
AssertionError
Value (Ticker(contract=Stock(symbol='NVDA', exchange='SMART', currency='USD'), time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), marketDataType=3, minTick=0.01, bid=-1.0, bidSize=0.0, ask=-1.0, askSize=0.0, last=136.4, lastSize=100.0, volume=2943386.0, open=0.0, high=136.33, low=130.69, close=130.98, ticks=[TickData(time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), tickType=66, price=-1.0, size=0.0), TickData(time=datetime.datetime(2024, 6, 19, 4, 22, 25, 60397, tzinfo=datetime.timezone.utc), tickType=67, price=-1.0, size=0.0)]),) caused exception for event Event<updateEvent, [[None, None, <function onPendingTickers at 0x7fe840298280>]]>
Any help is greatly appreciated.
<code>from ib_insync import *
ib = IB().connect("127.0.0.1", 7497, clientId=1)
watchlist = ['AAPL', 'MSFT', 'NVDA']
market_data = {} # store ticker here
contracts = {} # store contracts here
trades = {} # store trades here
def onNewOrderEvent(trade: Trade):
print('New {} order placed'.format(trade.contract.symbol))
print(trade.orderStatus.status)
def onOrderStatusEvent(trade: Trade):
print('{} order status changed'.format(trade.contract.symbol))
print(trade.orderStatus.status)
def onPendingTickers(tickers: Ticker):
"""update unfilled orders with new bid price"""
if trades[tickers.contract.symbol].orderStatus.status != 'Filled':
if tickers.bid != trades[tickers.contract.symbol].order.lmtPrice:
trades[tickers.contract.symbol].order.lmtPrice = tickers.bid
ib.placeOrder(tickers.contract, trades[tickers.contract.symbol].order)
print('best bid', tickers.contract.symbol, tickers.bid)
# Define stocks
for stk in watchlist:
contracts[stk] = Stock(stk, 'SMART', 'USD')
print(f"contract:{contracts[stk]}")
# Request current prices
ib.reqMarketDataType(3)
market_data[stk] = ib.reqMktData(contracts[stk], '', False, False)
market_data[stk].updateEvent += onPendingTickers
order = LimitOrder('Buy', 1, market_data[stk].bid)
trades[stk] = ib.placeOrder(contracts[stk], order)
ib.newOrderEvent.clear()
ib.orderStatusEvent.clear()
ib.newOrderEvent += onNewOrderEvent
ib.orderStatusEvent += onOrderStatusEvent
# wait for tickers to fill
ib.sleep(2)
print("wait for pendingTickersEvent to produce data")
ib.sleep(10)
_ = [ib.cancelMktData(_c) for _c in contracts.values()]
print("the end")
ib.disconnect()
</code>
<code>from ib_insync import *
ib = IB().connect("127.0.0.1", 7497, clientId=1)
watchlist = ['AAPL', 'MSFT', 'NVDA']
market_data = {} # store ticker here
contracts = {} # store contracts here
trades = {} # store trades here
def onNewOrderEvent(trade: Trade):
print('New {} order placed'.format(trade.contract.symbol))
print(trade.orderStatus.status)
def onOrderStatusEvent(trade: Trade):
print('{} order status changed'.format(trade.contract.symbol))
print(trade.orderStatus.status)
def onPendingTickers(tickers: Ticker):
"""update unfilled orders with new bid price"""
if trades[tickers.contract.symbol].orderStatus.status != 'Filled':
if tickers.bid != trades[tickers.contract.symbol].order.lmtPrice:
trades[tickers.contract.symbol].order.lmtPrice = tickers.bid
ib.placeOrder(tickers.contract, trades[tickers.contract.symbol].order)
print('best bid', tickers.contract.symbol, tickers.bid)
# Define stocks
for stk in watchlist:
contracts[stk] = Stock(stk, 'SMART', 'USD')
print(f"contract:{contracts[stk]}")
# Request current prices
ib.reqMarketDataType(3)
market_data[stk] = ib.reqMktData(contracts[stk], '', False, False)
market_data[stk].updateEvent += onPendingTickers
order = LimitOrder('Buy', 1, market_data[stk].bid)
trades[stk] = ib.placeOrder(contracts[stk], order)
ib.newOrderEvent.clear()
ib.orderStatusEvent.clear()
ib.newOrderEvent += onNewOrderEvent
ib.orderStatusEvent += onOrderStatusEvent
# wait for tickers to fill
ib.sleep(2)
print("wait for pendingTickersEvent to produce data")
ib.sleep(10)
_ = [ib.cancelMktData(_c) for _c in contracts.values()]
print("the end")
ib.disconnect()
</code>
from ib_insync import *
ib = IB().connect("127.0.0.1", 7497, clientId=1)
watchlist = ['AAPL', 'MSFT', 'NVDA']
market_data = {} # store ticker here
contracts = {} # store contracts here
trades = {} # store trades here
def onNewOrderEvent(trade: Trade):
print('New {} order placed'.format(trade.contract.symbol))
print(trade.orderStatus.status)
def onOrderStatusEvent(trade: Trade):
print('{} order status changed'.format(trade.contract.symbol))
print(trade.orderStatus.status)
def onPendingTickers(tickers: Ticker):
"""update unfilled orders with new bid price"""
if trades[tickers.contract.symbol].orderStatus.status != 'Filled':
if tickers.bid != trades[tickers.contract.symbol].order.lmtPrice:
trades[tickers.contract.symbol].order.lmtPrice = tickers.bid
ib.placeOrder(tickers.contract, trades[tickers.contract.symbol].order)
print('best bid', tickers.contract.symbol, tickers.bid)
# Define stocks
for stk in watchlist:
contracts[stk] = Stock(stk, 'SMART', 'USD')
print(f"contract:{contracts[stk]}")
# Request current prices
ib.reqMarketDataType(3)
market_data[stk] = ib.reqMktData(contracts[stk], '', False, False)
market_data[stk].updateEvent += onPendingTickers
order = LimitOrder('Buy', 1, market_data[stk].bid)
trades[stk] = ib.placeOrder(contracts[stk], order)
ib.newOrderEvent.clear()
ib.orderStatusEvent.clear()
ib.newOrderEvent += onNewOrderEvent
ib.orderStatusEvent += onOrderStatusEvent
# wait for tickers to fill
ib.sleep(2)
print("wait for pendingTickersEvent to produce data")
ib.sleep(10)
_ = [ib.cancelMktData(_c) for _c in contracts.values()]
print("the end")
ib.disconnect()