Expected behavior
Code sample
import numpy as np
import pandas as pd
def run_backtest(
df: pd.DataFrame, initial_balance: float = 1000.0, fee: float = 0.001
):
"""Simple event-driven backtest loop for AI signal validation.
df must contain: 'close', 'signal' (1 for Buy, -1 for Sell, 0 for Hold)
"""
balance = initial_balance
position = 0.0 # Amount of crypto held
equity_curve = []
for i, row in df.iterrows():
price = row["close"]
signal = row["signal"]
# Buy Signal (Entry)
if signal == 1 and balance > 0:
position = (balance * (1 - fee)) / price
balance = 0.0
# Sell Signal (Exit)
elif signal == -1 and position > 0:
balance = (position * price) * (1 - fee)
position = 0.0
# Calculate current net portfolio value
current_value = balance + (position * price)
equity_curve.append(current_value)
df["portfolio_val"] = equity_curve
df["returns"] = df["portfolio_val"].pct_change()
total_return = (
df["portfolio_val"].iloc[-1] - initial_balance
) / initial_balance
max_drawdown = (
(df["portfolio_val"].cummax() - df["portfolio_val"])
/ df["portfolio_val"].cummax()
).max()
return {
"Final Balance ($)": round(df["portfolio_val"].iloc[-1], 2),
"Total Return (%)": round(total_return * 100, 2),
"Max Drawdown (%)": round(max_drawdown * 100, 2),
}
Actual behavior
import numpy as np
import pandas as pd
def run_backtest(
df: pd.DataFrame, initial_balance: float = 1000.0, fee: float = 0.001
):
"""Simple event-driven backtest loop for AI signal validation.
df must contain: 'close', 'signal' (1 for Buy, -1 for Sell, 0 for Hold)
"""
balance = initial_balance
position = 0.0 # Amount of crypto held
equity_curve = []
for i, row in df.iterrows():
price = row["close"]
signal = row["signal"]
# Buy Signal (Entry)
if signal == 1 and balance > 0:
position = (balance * (1 - fee)) / price
balance = 0.0
# Sell Signal (Exit)
elif signal == -1 and position > 0:
balance = (position * price) * (1 - fee)
position = 0.0
# Calculate current net portfolio value
current_value = balance + (position * price)
equity_curve.append(current_value)
df["portfolio_val"] = equity_curve
df["returns"] = df["portfolio_val"].pct_change()
total_return = (
df["portfolio_val"].iloc[-1] - initial_balance
) / initial_balance
max_drawdown = (
(df["portfolio_val"].cummax() - df["portfolio_val"])
/ df["portfolio_val"].cummax()
).max()
return {
"Final Balance ($)": round(df["portfolio_val"].iloc[-1], 2),
"Total Return (%)": round(total_return * 100, 2),
"Max Drawdown (%)": round(max_drawdown * 100, 2),
}
Additional info, steps to reproduce, full crash traceback, screenshots
- Critical Pitfalls in AI Crypto Backtesting
Overfitting (Curve Fitting): Machine learning models easily memorize historical price patterns that do not repeat in live markets. Use cross-validation techniques like Time Series Split.
Look-Ahead Bias: Accidental use of future features (e.g., calculating indicators using future candle data or global normalization across the full dataset instead of rolling windows).
Regime Shift Neglect: Models trained during trending bull markets often incur heavy drawdowns during sideways (range-bound) or bear market cycles. Test your bot across distinct market phases:
Bull Market: Continuous upward trend
Bear Market: High-volatility downward trend
Crab Market: Low-volatility horizontal consolidation
Ignoring Liquidity & Order Book Impact: Placing high-volume simulated trades into low-liquidity order books will skew backtest results unless order book depth is factored into execution price calculations.
Software versions
backtesting.__version__:
pandas.__version__:
numpy.__version__:
bokeh.__version__:
- OS:
Expected behavior
Code sample
Actual behavior
import numpy as np
import pandas as pd
def run_backtest(
df: pd.DataFrame, initial_balance: float = 1000.0, fee: float = 0.001
):
"""Simple event-driven backtest loop for AI signal validation.
Additional info, steps to reproduce, full crash traceback, screenshots
Overfitting (Curve Fitting): Machine learning models easily memorize historical price patterns that do not repeat in live markets. Use cross-validation techniques like Time Series Split.
Look-Ahead Bias: Accidental use of future features (e.g., calculating indicators using future candle data or global normalization across the full dataset instead of rolling windows).
Regime Shift Neglect: Models trained during trending bull markets often incur heavy drawdowns during sideways (range-bound) or bear market cycles. Test your bot across distinct market phases:
Bull Market: Continuous upward trend
Bear Market: High-volatility downward trend
Crab Market: Low-volatility horizontal consolidation
Ignoring Liquidity & Order Book Impact: Placing high-volume simulated trades into low-liquidity order books will skew backtest results unless order book depth is factored into execution price calculations.
Software versions
backtesting.__version__:pandas.__version__:numpy.__version__:bokeh.__version__: