From 577aa73ec3770620bd8836aa5eb82a5cc043c0e1 Mon Sep 17 00:00:00 2001 From: moshferatu Date: Mon, 19 Feb 2024 14:29:49 -0800 Subject: [PATCH] Refactor order submission to utilize new IBKR client --- iron_condor.py | 81 +++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/iron_condor.py b/iron_condor.py index fc35193..db75166 100644 --- a/iron_condor.py +++ b/iron_condor.py @@ -60,10 +60,10 @@ def monitor_spread_price(short_leg: OptionLeg, long_leg: OptionLeg, stop_price: short_leg_exit = replace(short_leg, action = BUY if short_leg.action == SELL else SELL) long_leg_exit = replace(long_leg, action = BUY if long_leg.action == SELL else SELL) if long_contract.bid > 0: - client.submit_combo_option_order([short_leg_exit, long_leg_exit], quantity) + client.submit_spread_order(short_leg_exit, long_leg_exit) logging.info('Whole spread exited.') else: - client.submit_single_option_order(short_leg_exit, quantity) + client.submit_option_order(short_leg_exit) logging.info('Short leg only exited.') # Unsubscribe from market data updates once the trade has exited. @@ -121,51 +121,57 @@ def _enter_iron_condor(entry_time: datetime): ibkr_client = Client() - trade_records = [] - call_spread_details = {} - put_spread_details = {} - short_call_leg = OptionLeg(symbol, expiration, short_call_strike, CALL, SELL, sub_symbol) long_call_leg = OptionLeg(symbol, expiration, long_call_strike, CALL, BUY, sub_symbol) - call_spread_order = ibkr_client.submit_combo_option_order([short_call_leg, long_call_leg], quantity) - while not call_spread_order.isDone(): - ibkr_client.ib.waitOnUpdate() + call_spread_order = ibkr_client.submit_spread_order(short_call_leg, long_call_leg) + call_spread_limit = call_spread_order.limit_price + call_spread_fill = call_spread_order.fill_price + logging.info(f'Call Spread Limit Price: {call_spread_limit}') + logging.info(f'Call Spread Fill Price: {call_spread_fill}') + logging.info(f'Call Spread Slippage: {call_spread_fill - call_spread_limit}') - if call_spread_order.orderStatus.status == 'Filled': - fill_price = abs(call_spread_order.orderStatus.avgFillPrice) - logging.info(f'Call Spread Fill Price: {fill_price}') - monitor_spread_price(short_call_leg, long_call_leg, fill_price * 2, ibkr_client) - - call_spread_details = { - 'Legs': [ - {'Action': 'SELL', 'Strike': short_call_strike, 'Type': 'CALL'}, - {'Action': 'BUY', 'Strike': long_call_strike, 'Type': 'CALL'} - ], - 'Open': fill_price - } + monitor_spread_price( + short_leg = short_call_leg, + long_leg = long_call_leg, + stop_price = call_spread_fill * 2, + client = ibkr_client + ) short_put_leg = OptionLeg(symbol, expiration, short_put_strike, PUT, SELL, sub_symbol) long_put_leg = OptionLeg(symbol, expiration, long_put_strike, PUT, BUY, sub_symbol) - put_spread_order = ibkr_client.submit_combo_option_order([short_put_leg, long_put_leg], quantity) - while not put_spread_order.isDone(): - ibkr_client.ib.waitOnUpdate() + put_spread_order = ibkr_client.submit_spread_order(short_put_leg, long_put_leg) + put_spread_limit = put_spread_order.limit_price + put_spread_fill = put_spread_order.fill_price + logging.info(f'Put Spread Limit Price: {put_spread_limit}') + logging.info(f'Put Spread Fill Price: {put_spread_fill}') + logging.info(f'Put Spread Slippage: {put_spread_fill - put_spread_limit}') - if put_spread_order.orderStatus.status == 'Filled': - fill_price = abs(put_spread_order.orderStatus.avgFillPrice) - logging.info(f'Put Spread Fill Price: {fill_price}') - monitor_spread_price(short_put_leg, long_put_leg, fill_price * 2, ibkr_client) + monitor_spread_price( + short_leg = short_put_leg, + long_leg = long_put_leg, + stop_price = put_spread_fill * 2, + client = ibkr_client + ) - put_spread_details = { - 'Legs': [ - {'Action': 'SELL', 'Strike': short_put_strike, 'Type': 'PUT'}, - {'Action': 'BUY', 'Strike': long_put_strike, 'Type': 'PUT'} - ], - 'Open': fill_price - } + call_spread_details = { + 'Legs': [ + {'Action': 'SELL', 'Strike': short_call_strike, 'Type': 'CALL'}, + {'Action': 'BUY', 'Strike': long_call_strike, 'Type': 'CALL'} + ], + 'Open': call_spread_fill + } - trade_records.append({ + put_spread_details = { + 'Legs': [ + {'Action': 'SELL', 'Strike': short_put_strike, 'Type': 'PUT'}, + {'Action': 'BUY', 'Strike': long_put_strike, 'Type': 'PUT'} + ], + 'Open': put_spread_fill + } + + upsert(pd.DataFrame([{ 'Date': datetime.now().date(), 'Symbol': symbol, 'Strategy': f'${credit_target:.2f} Iron Condor', @@ -173,8 +179,7 @@ def _enter_iron_condor(entry_time: datetime): 'Exit Time': None, 'Spreads': [call_spread_details, put_spread_details], 'Profit': None - }) - upsert(pd.DataFrame(trade_records)) + }])) # TODO: Add a shutdown hook. ibkr_client.run_event_loop() \ No newline at end of file