backtesting-analysis
4
总安装量
4
周安装量
#50926
全站排名
安装命令
npx skills add https://github.com/sayujks0071/antidhan --skill backtesting-analysis
Agent 安装分布
opencode
4
claude-code
4
codex
4
mcpjam
3
openhands
3
zencoder
3
Skill 文档
Backtesting & Analysis
Quick Start
When running backtests:
- Use the backtest engine or AITRAPP integration
- Configure date range, capital, and parameters
- Run backtest and collect metrics
- Analyze results and compare strategies
- Generate ranking reports
Backtest Execution
Simple Backtest Engine
Location: openalgo/strategies/utils/simple_backtest_engine.py
from openalgo.strategies.utils.simple_backtest_engine import SimpleBacktestEngine
from openalgo.strategies.scripts.your_strategy import YourStrategy
# Initialize engine
engine = SimpleBacktestEngine(
strategy_class=YourStrategy,
symbol="NIFTY",
start_date="2025-08-15",
end_date="2025-11-10",
capital=1000000
)
# Run backtest
results = engine.run()
# Get metrics
print(f"Total Return: {results['total_return']:.2f}%")
print(f"Win Rate: {results['win_rate']:.2f}%")
print(f"Profit Factor: {results['profit_factor']:.2f}")
print(f"Max Drawdown: {results['max_drawdown']:.2f}%")
AITRAPP Backtest Integration
Location: openalgo/strategies/scripts/run_backtest_ranking.py
cd openalgo/strategies
python3 scripts/run_backtest_ranking.py \
--symbol NIFTY \
--start-date 2025-08-15 \
--end-date 2025-11-10 \
--capital 1000000
Output:
- CSV report:
backtest_results/ranking_report_{symbol}_{date}.csv - JSON report:
backtest_results/ranking_report_{symbol}_{date}.json - Comparison table with all strategies
Performance Metrics
Key Metrics
Returns:
- Total Return (%)
- Annualized Return (%)
- Monthly Return (%)
Risk Metrics:
- Max Drawdown (%)
- Average Drawdown (%)
- Volatility (%)
Trade Statistics:
- Win Rate (%)
- Profit Factor (Gross Profit / Gross Loss)
- Average Win / Loss
- Largest Win / Loss
- Total Trades
Risk-Adjusted:
- Sharpe Ratio
- Sortino Ratio
- Calmar Ratio (Return / Max Drawdown)
Metric Calculation
def calculate_metrics(trades, equity_curve):
"""Calculate comprehensive performance metrics"""
if not trades:
return {}
wins = [t for t in trades if t.pnl > 0]
losses = [t for t in trades if t.pnl < 0]
total_return = (equity_curve[-1] - equity_curve[0]) / equity_curve[0] * 100
win_rate = len(wins) / len(trades) * 100 if trades else 0
gross_profit = sum(t.pnl for t in wins)
gross_loss = abs(sum(t.pnl for t in losses))
profit_factor = gross_profit / gross_loss if gross_loss > 0 else 0
max_dd = calculate_max_drawdown(equity_curve)
return {
'total_return': total_return,
'win_rate': win_rate,
'profit_factor': profit_factor,
'max_drawdown': max_dd,
'total_trades': len(trades)
}
Strategy Comparison
Ranking Criteria
Strategies are ranked by composite score:
def calculate_composite_score(metrics):
"""Calculate composite ranking score"""
# Weighted components
return_score = metrics['total_return'] * 0.30
sharpe_score = metrics['sharpe_ratio'] * 0.25
win_rate_score = metrics['win_rate'] * 0.20
profit_factor_score = metrics['profit_factor'] * 10 * 0.15
drawdown_penalty = metrics['max_drawdown'] * -0.10
return return_score + sharpe_score + win_rate_score + profit_factor_score + drawdown_penalty
Comparison Table Format
Strategy Name | Return | Win Rate | PF | Max DD | Score
-----------------------|---------|----------|-------|---------|-------
MCX Advanced | 15.2% | 58.3% | 1.85 | -8.5% | 8.2
NIFTY Greeks Enhanced | 12.8% | 62.1% | 2.10 | -6.2% | 8.5
ML Momentum | 18.5% | 55.0% | 1.65 | -12.3% | 7.8
Parameter Optimization
Grid Search
from openalgo.strategies.utils.parameter_space import ParameterSpace
param_space = {
'adx_threshold': [20, 25, 30],
'rsi_overbought': [70, 75, 80],
'risk_per_trade': [0.01, 0.02, 0.03]
}
best_params = None
best_score = -float('inf')
for params in ParameterSpace(param_space):
strategy = YourStrategy(symbol, params)
results = engine.run()
score = calculate_composite_score(results)
if score > best_score:
best_score = score
best_params = params
Walk-Forward Analysis
def walk_forward_optimization(start_date, end_date, window_months=3):
"""Optimize parameters using walk-forward analysis"""
results = []
current_start = start_date
while current_start < end_date:
current_end = current_start + timedelta(days=window_months * 30)
# Optimize on training period
best_params = optimize_parameters(current_start, current_end)
# Test on out-of-sample period
test_results = backtest(best_params, current_end, current_end + timedelta(days=30))
results.append(test_results)
current_start = current_end
return aggregate_results(results)
Report Generation
CSV Report
import pandas as pd
def generate_csv_report(results, filename):
"""Generate CSV report from backtest results"""
df = pd.DataFrame([{
'strategy': r['name'],
'return_pct': r['total_return'],
'win_rate': r['win_rate'],
'profit_factor': r['profit_factor'],
'max_drawdown': r['max_drawdown'],
'sharpe_ratio': r['sharpe_ratio'],
'total_trades': r['total_trades']
} for r in results])
df = df.sort_values('composite_score', ascending=False)
df.to_csv(filename, index=False)
JSON Report
import json
def generate_json_report(results, filename):
"""Generate detailed JSON report"""
report = {
'backtest_period': {
'start': start_date,
'end': end_date
},
'capital': capital,
'strategies': results,
'summary': {
'best_strategy': max(results, key=lambda x: x['composite_score']),
'worst_strategy': min(results, key=lambda x: x['composite_score'])
}
}
with open(filename, 'w') as f:
json.dump(report, f, indent=2)
Common Analysis Tasks
Equity Curve Analysis
import matplotlib.pyplot as plt
def plot_equity_curve(equity_curve, dates):
"""Plot equity curve over time"""
plt.figure(figsize=(12, 6))
plt.plot(dates, equity_curve)
plt.title('Equity Curve')
plt.xlabel('Date')
plt.ylabel('Portfolio Value')
plt.grid(True)
plt.show()
Drawdown Analysis
def calculate_drawdowns(equity_curve):
"""Calculate drawdown periods"""
peak = equity_curve[0]
drawdowns = []
for value in equity_curve:
if value > peak:
peak = value
dd = (peak - value) / peak * 100
drawdowns.append(dd)
return drawdowns
Trade Distribution Analysis
def analyze_trade_distribution(trades):
"""Analyze distribution of trade outcomes"""
pnls = [t.pnl for t in trades]
print(f"Mean PnL: {np.mean(pnls):.2f}")
print(f"Median PnL: {np.median(pnls):.2f}")
print(f"Std Dev: {np.std(pnls):.2f}")
print(f"Skewness: {scipy.stats.skew(pnls):.2f}")
print(f"Kurtosis: {scipy.stats.kurtosis(pnls):.2f}")
Troubleshooting
No Trades Generated
Check:
- Date range has sufficient data
- Entry conditions are not too strict
- Market hours filter is correct
- Symbol/instrument is valid
Unrealistic Results
Verify:
- Transaction costs are included (slippage, commissions)
- Position sizing is realistic
- Data quality (no gaps, correct prices)
- Market impact is considered for large orders
Slow Backtests
Optimize:
- Reduce date range for initial testing
- Use lower resolution data (15m instead of 5m)
- Cache indicator calculations
- Parallelize strategy runs
Additional Resources
- Backtest engine:
openalgo/strategies/utils/simple_backtest_engine.py - AITRAPP integration:
openalgo/strategies/AITRAPP_INTEGRATION_GUIDE.md - Results location:
openalgo/strategies/backtest_results/ - Ranking script:
openalgo/strategies/scripts/run_backtest_ranking.py