Add spread information to backtest result data frame

This commit is contained in:
moshferatu 2024-01-16 06:32:27 -08:00
parent 1b475175c0
commit 93930bfea8

View File

@ -41,6 +41,7 @@ class BacktestResult:
date: str date: str
entry_time: str entry_time: str
exit_time: str exit_time: str
spreads: list
trade_entered: bool trade_entered: bool
trade_pnl: float trade_pnl: float
profit: float profit: float
@ -190,6 +191,24 @@ def _backtest_iron_condor(
premium_received = original_call_spread_price + original_put_spread_price 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 trades_entered = False
call_spread_stopped_out = False call_spread_stopped_out = False
put_spread_stopped_out = False put_spread_stopped_out = False
@ -223,24 +242,34 @@ def _backtest_iron_condor(
else: 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) 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 not call_spread_stopped_out:
if current_call_spread_price >= ((call_spread_strat.stop_loss_multiple + 1) * original_call_spread_price): 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) 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. # Calculate exit slippage.
premium_received -= 0.10 # TODO: Make this configurable. premium_received -= 0.10 # TODO: Make this configurable.
call_spread_stopped_out = True call_spread_stopped_out = True
# exit_time = int(call_spread.name[-8:].replace(':', ''))
exit_time = call_spread.name[-8:] exit_time = call_spread.name[-8:]
logging.info('Call Spread Stopped Out') logging.info('Call Spread Stopped Out')
break
if not put_spread_stopped_out: if not put_spread_stopped_out:
if current_put_spread_price >= ((put_spread_strat.stop_loss_multiple + 1) * original_put_spread_price): 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 -= original_put_spread_price * (put_spread_strat.stop_loss_multiple + 1)
premium_received -= 0.10 # TODO: Make this configurable. 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 put_spread_stopped_out = True
# exit_time = int(call_spread.name[-8:].replace(':', ''))
exit_time = call_spread.name[-8:] exit_time = call_spread.name[-8:]
logging.info('Put Spread Stopped Out') logging.info('Put Spread Stopped Out')
break
if not (call_spread_stopped_out and put_spread_stopped_out): if not (call_spread_stopped_out and put_spread_stopped_out):
if current_call_spread_price > current_put_spread_price: if current_call_spread_price > current_put_spread_price:
@ -299,6 +328,7 @@ def _backtest_iron_condor(
date=current_date, date=current_date,
entry_time=f'{current_date} {entry_time}', entry_time=f'{current_date} {entry_time}',
exit_time=f'{current_date} {exit_time}', exit_time=f'{current_date} {exit_time}',
spreads=[call_spread_details, put_spread_details],
trade_entered=True, trade_entered=True,
trade_pnl=premium_received, trade_pnl=premium_received,
profit=0.0, # TODO: Calculated elsewhere. Clean this up. profit=0.0, # TODO: Calculated elsewhere. Clean this up.
@ -373,6 +403,7 @@ def backtest_iron_condor(
'Strategy': strategy_name, 'Strategy': strategy_name,
'Entry Time': result.entry_time, 'Entry Time': result.entry_time,
'Exit Time': result.exit_time, 'Exit Time': result.exit_time,
'Spreads': result.spreads,
'Profit': result.trade_pnl, 'Profit': result.trade_pnl,
'Cumulative Profit': result.profit 'Cumulative Profit': result.profit
} for result in backtest_results]) } for result in backtest_results])