Update trades table upon stopping out of a spread so that it includes the closing price and slippage incurred on exit
This commit is contained in:
parent
b6c0738e00
commit
d868192002
@ -11,9 +11,10 @@ from ibkr import Client, OptionLeg
|
||||
from ibkr.option_type import CALL, PUT
|
||||
from ibkr.order_action import BUY, SELL
|
||||
|
||||
from iron_condor_trade import IronCondorTrade
|
||||
from options_chain import OptionsChain
|
||||
from option_type import OptionType
|
||||
from trades_table import insert_trade
|
||||
from trades_table import insert_trade, update_on_stop_loss
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@ -21,7 +22,7 @@ load_dotenv()
|
||||
# Necessary for monitoring spread prices asynchronously while interacting with the IBKR client.
|
||||
nest_asyncio.apply()
|
||||
|
||||
def monitor_spread_price(short_leg: OptionLeg, long_leg: OptionLeg, stop_price: float, client: Client):
|
||||
def monitor_spread_price(trade: IronCondorTrade, short_leg: OptionLeg, long_leg: OptionLeg, stop_price: float, client: Client):
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
Stop loss orders will not execute if trying to sell back a contract with no bid while paper trading.
|
||||
Therefore, the spread price must be monitored and the spread manually exited if the stop price is reached.
|
||||
@ -60,7 +61,10 @@ def monitor_spread_price(short_leg: OptionLeg, long_leg: OptionLeg, stop_price:
|
||||
exit_order = client.submit_option_order(short_leg_exit)
|
||||
logging.info('Short leg only exited.')
|
||||
|
||||
logging.info(f'Exit Slippage: {round(exit_order.fill_price - stop_price, 3)}')
|
||||
exit_slippage = round(exit_order.fill_price - stop_price, 3)
|
||||
logging.info(f'Exit Slippage: {exit_slippage}')
|
||||
|
||||
update_on_stop_loss(trade, short_leg.option_type, exit_order.fill_price, exit_slippage)
|
||||
|
||||
# Unsubscribe from market data updates once the trade has exited.
|
||||
for leg in [short_leg, long_leg]:
|
||||
@ -116,6 +120,7 @@ def _enter_iron_condor(entry_time: datetime):
|
||||
logging.info(f'Long Call Strike: {long_call_strike}')
|
||||
|
||||
ibkr_client = Client()
|
||||
trade = IronCondorTrade(symbol, credit_target, entry_time, float(getenv('STOP_MULTIPLE')))
|
||||
|
||||
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)
|
||||
@ -123,9 +128,10 @@ def _enter_iron_condor(entry_time: datetime):
|
||||
call_spread_order = ibkr_client.submit_spread_order(short_call_leg, long_call_leg)
|
||||
logging.info(f'Call Spread Mid Price: {call_spread_order.mid_price}')
|
||||
logging.info(f'Call Spread Fill Price: {call_spread_order.fill_price}')
|
||||
logging.info(f'Call Spread Slippage: {call_spread_order.fill_price - call_spread_order.mid_price}')
|
||||
logging.info(f'Call Spread Slippage: {call_spread_order.mid_price - call_spread_order.fill_price}')
|
||||
|
||||
monitor_spread_price(
|
||||
trade = trade,
|
||||
short_leg = short_call_leg,
|
||||
long_leg = long_call_leg,
|
||||
stop_price = call_spread_order.fill_price * 2,
|
||||
@ -138,16 +144,17 @@ def _enter_iron_condor(entry_time: datetime):
|
||||
put_spread_order = ibkr_client.submit_spread_order(short_put_leg, long_put_leg)
|
||||
logging.info(f'Put Spread Mid Price: {put_spread_order.mid_price}')
|
||||
logging.info(f'Put Spread Fill Price: {put_spread_order.fill_price}')
|
||||
logging.info(f'Put Spread Slippage: {put_spread_order.fill_price - put_spread_order.mid_price}')
|
||||
logging.info(f'Put Spread Slippage: {put_spread_order.mid_price - put_spread_order.fill_price}')
|
||||
|
||||
monitor_spread_price(
|
||||
trade = trade,
|
||||
short_leg = short_put_leg,
|
||||
long_leg = long_put_leg,
|
||||
stop_price = put_spread_order.fill_price * 2,
|
||||
client = ibkr_client
|
||||
)
|
||||
|
||||
insert_trade(symbol, credit_target, entry_time, call_spread_order, put_spread_order)
|
||||
insert_trade(trade, call_spread_order, put_spread_order)
|
||||
|
||||
# TODO: Add a shutdown hook.
|
||||
ibkr_client.run_event_loop()
|
@ -1,13 +1,13 @@
|
||||
from datetime import datetime
|
||||
from pandas import DataFrame
|
||||
|
||||
from backtesting.credit_targeting import iron_condor_strategy
|
||||
from database.trades import get_leg, get_spread, upsert
|
||||
from database.trades import get_leg, get_spread, trade, upsert
|
||||
from database.trades.action import Action
|
||||
from database.trades.option_type import OptionType
|
||||
from ibkr import option_type as IBKROptionType
|
||||
from ibkr.option_order import OptionOrder
|
||||
|
||||
from iron_condor_trade import IronCondorTrade
|
||||
|
||||
def translate_action(action_string: str) -> Action:
|
||||
for action in Action:
|
||||
if action_string == action.value:
|
||||
@ -37,22 +37,43 @@ def spread(spread_order: OptionOrder) -> dict:
|
||||
entry_slippage = round(spread_order.mid_price - spread_order.fill_price, 3)
|
||||
)
|
||||
|
||||
def insert_trade(
|
||||
symbol: str,
|
||||
target: float,
|
||||
entry_time: datetime,
|
||||
call_spread_order: OptionOrder,
|
||||
put_spread_order: OptionOrder
|
||||
):
|
||||
|
||||
def insert_trade(iron_condor: IronCondorTrade, call_spread_order: OptionOrder, put_spread_order: OptionOrder):
|
||||
upsert(
|
||||
DataFrame([{
|
||||
'Date': datetime.now().date(),
|
||||
'Symbol': symbol,
|
||||
'Strategy': iron_condor_strategy(target),
|
||||
'Entry Time': entry_time.replace(tzinfo = None),
|
||||
'Date': iron_condor.entry_time.date(),
|
||||
'Symbol': iron_condor.symbol,
|
||||
'Strategy': iron_condor.strategy,
|
||||
'Entry Time': iron_condor.entry_time,
|
||||
'Exit Time': None, # Required.
|
||||
'Spreads': [spread(call_spread_order), spread(put_spread_order)],
|
||||
'Profit': None # Required.
|
||||
}])
|
||||
)
|
||||
|
||||
def update_on_stop_loss(iron_condor: IronCondorTrade, option_type: str, close_price: float, exit_slippage: float):
|
||||
date = iron_condor.entry_time.date()
|
||||
|
||||
trade_record = trade(
|
||||
date = date,
|
||||
symbol = iron_condor.symbol,
|
||||
strategy = iron_condor.strategy,
|
||||
entry_time = iron_condor.entry_time
|
||||
)
|
||||
spreads = trade_record['Spreads'].iloc[0]
|
||||
|
||||
spread_index = 0 if option_type == 'C' else 1 # 'C' for call spread, 'P' for put spread.
|
||||
|
||||
spreads[spread_index]['Close'] = close_price
|
||||
spreads[spread_index]['Exit Slippage'] = exit_slippage
|
||||
|
||||
upsert(
|
||||
DataFrame([{
|
||||
'Date': date,
|
||||
'Symbol': iron_condor.symbol,
|
||||
'Strategy': iron_condor.strategy,
|
||||
'Entry Time': iron_condor.entry_time,
|
||||
'Exit Time': None,
|
||||
'Spreads': spreads,
|
||||
'Profit': None # To be updated end of day.
|
||||
}])
|
||||
)
|
Loading…
Reference in New Issue
Block a user