refactor: Enhance multi-ticker backtest error handling and debugging

This commit is contained in:
Bobby (aider) 2025-02-14 00:04:40 -08:00
parent 0b9742eb61
commit 8c2b8233cf

View File

@ -466,40 +466,67 @@ def run_multi_ticker_backtest(tickers: list, start_date: datetime, end_date: dat
print(f"\nTesting strategy on {ticker}")
df = get_stock_data(ticker, start_date, end_date, 'daily')
if df.empty:
if df is None or df.empty:
print(f"No data available for {ticker}")
continue
df = prepare_data_for_backtest(df)
print(f"Data shape for {ticker}: {df.shape}")
print(f"Date range: {df.index.min()} to {df.index.max()}")
print(f"Columns: {df.columns.tolist()}")
try:
df = prepare_data_for_backtest(df)
except Exception as e:
print(f"Error preparing data for {ticker}: {str(e)}")
continue
print(f"Prepared data shape: {df.shape}")
print(f"Final columns: {df.columns.tolist()}")
# Run backtest
DynamicStrategy.indicator_configs = indicator_settings
bt = Backtest(df, DynamicStrategy, cash=100000, commission=.002)
stats = bt.run()
try:
DynamicStrategy.indicator_configs = indicator_settings
bt = Backtest(df, DynamicStrategy, cash=100000, commission=.002)
stats = bt.run()
# Print raw stats for debugging
print("Debug - Available stats keys:", stats.keys())
print(f"Backtest completed for {ticker}")
print("Available stats keys:", stats.keys())
# Store results with error handling for each metric
result = {
'Ticker': ticker,
'Return [%]': stats.get('Return [%]', stats.get('Return', 0)),
'Sharpe Ratio': stats.get('Sharpe Ratio', 0),
'Max Drawdown [%]': stats.get('Max. Drawdown [%]', stats.get('Max Drawdown', 0)),
'Win Rate [%]': stats.get('Win Rate [%]', stats.get('Win Rate', 0)),
'Number of Trades': stats.get('# Trades', stats.get('Number of Trades', 0))
}
all_results.append(result)
# Store results with error handling for each metric
result = {
'Ticker': ticker,
'Return [%]': float(stats.get('Return [%]', stats.get('Return', 0))),
'Sharpe Ratio': float(stats.get('Sharpe Ratio', 0)),
'Max Drawdown [%]': float(stats.get('Max. Drawdown [%]', stats.get('Max Drawdown', 0))),
'Win Rate [%]': float(stats.get('Win Rate [%]', stats.get('Win Rate', 0))),
'Number of Trades': int(stats.get('# Trades', stats.get('Number of Trades', 0)))
}
print(f"{ticker} - Return: {result['Return [%]']:.2f}%, "
f"Sharpe: {result['Sharpe Ratio']:.2f}, "
f"Drawdown: {result['Max Drawdown [%]']:.2f}%")
# Verify results are valid
if any(pd.isna(val) for val in result.values()):
print(f"Warning: NaN values in results for {ticker}")
continue
all_results.append(result)
print(f"Success - {ticker} results:")
for key, value in result.items():
print(f"{key}: {value}")
except Exception as e:
print(f"Error during backtest for {ticker}: {str(e)}")
continue
except Exception as e:
print(f"Error processing {ticker}: {str(e)}")
continue
if not all_results:
print("No valid results were generated. Check the following:")
print("1. Are the tickers valid?")
print("2. Is there data available for the selected date range?")
print("3. Are the indicator settings valid?")
print("4. Are there any errors in the strategy logic?")
raise ValueError("No valid results were generated from any ticker")
return pd.DataFrame(all_results)