From 93930bfea80d5887701c3d751c2bed71715822bd Mon Sep 17 00:00:00 2001 From: moshferatu Date: Tue, 16 Jan 2024 06:32:27 -0800 Subject: [PATCH] Add spread information to backtest result data frame --- backtesting/backtest_iron_condor.py | 35 +++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/backtesting/backtest_iron_condor.py b/backtesting/backtest_iron_condor.py index d268ce9..42e9f2d 100644 --- a/backtesting/backtest_iron_condor.py +++ b/backtesting/backtest_iron_condor.py @@ -41,6 +41,7 @@ class BacktestResult: date: str entry_time: str exit_time: str + spreads: list trade_entered: bool trade_pnl: float profit: float @@ -190,6 +191,24 @@ def _backtest_iron_condor( premium_received = original_call_spread_price + original_put_spread_price + call_spread_details = { + "legs": [{"action": "SELL", "strike": call_spread_entry['strike_short_strike'], "type": "CALL"}, + {"action": "BUY", "strike": call_spread_entry['strike_long_strike'], "type": "CALL"}], + "open": original_call_spread_price, + "high": None, + "low": None, + "close": None + } + + put_spread_details = { + "legs": [{"action": "SELL", "strike": put_spread_entry['strike_short_strike'], "type": "PUT"}, + {"action": "BUY", "strike": put_spread_entry['strike_long_strike'], "type": "PUT"}], + "open": original_put_spread_price, + "high": None, + "low": None, + "close": None + } + trades_entered = False call_spread_stopped_out = False put_spread_stopped_out = False @@ -222,25 +241,35 @@ def _backtest_iron_condor( current_put_spread_price = put_spread['high_short_strike'] - put_spread['high_long_strike'] else: current_put_spread_price = ((put_spread['ask_short_strike'] + put_spread['bid_short_strike']) / 2.0) - ((put_spread['ask_long_strike'] + put_spread['bid_long_strike']) / 2.0) + + call_spread_details['high'] = max(call_spread_details['high'] or float('-inf'), current_call_spread_price) + call_spread_details['low'] = min(call_spread_details['low'] or float('inf'), current_call_spread_price) + call_spread_details['close'] = current_call_spread_price + + put_spread_details['high'] = max(put_spread_details['high'] or float('-inf'), current_put_spread_price) + put_spread_details['low'] = min(put_spread_details['low'] or float('inf'), current_put_spread_price) + put_spread_details['close'] = current_put_spread_price if not call_spread_stopped_out: if current_call_spread_price >= ((call_spread_strat.stop_loss_multiple + 1) * original_call_spread_price): premium_received -= original_call_spread_price * (call_spread_strat.stop_loss_multiple + 1) + call_spread_details['close'] = original_call_spread_price * (call_spread_strat.stop_loss_multiple + 1) + 0.10 # Calculate exit slippage. premium_received -= 0.10 # TODO: Make this configurable. call_spread_stopped_out = True - # exit_time = int(call_spread.name[-8:].replace(':', '')) exit_time = call_spread.name[-8:] logging.info('Call Spread Stopped Out') + break if not put_spread_stopped_out: if current_put_spread_price >= ((put_spread_strat.stop_loss_multiple + 1) * original_put_spread_price): premium_received -= original_put_spread_price * (put_spread_strat.stop_loss_multiple + 1) premium_received -= 0.10 # TODO: Make this configurable. + put_spread_details['close'] = original_put_spread_price * (put_spread_strat.stop_loss_multiple + 1) + 0.10 put_spread_stopped_out = True - # exit_time = int(call_spread.name[-8:].replace(':', '')) exit_time = call_spread.name[-8:] logging.info('Put Spread Stopped Out') + break if not (call_spread_stopped_out and put_spread_stopped_out): if current_call_spread_price > current_put_spread_price: @@ -299,6 +328,7 @@ def _backtest_iron_condor( date=current_date, entry_time=f'{current_date} {entry_time}', exit_time=f'{current_date} {exit_time}', + spreads=[call_spread_details, put_spread_details], trade_entered=True, trade_pnl=premium_received, profit=0.0, # TODO: Calculated elsewhere. Clean this up. @@ -373,6 +403,7 @@ def backtest_iron_condor( 'Strategy': strategy_name, 'Entry Time': result.entry_time, 'Exit Time': result.exit_time, + 'Spreads': result.spreads, 'Profit': result.trade_pnl, 'Cumulative Profit': result.profit } for result in backtest_results])