mirror of
https://github.com/B-Wear/QuantumEdge.git
synced 2026-07-27 15:37:46 +00:00
bf08d59def
Signed-off-by: B-Wear <Bwear008@gmail.com>
169 lines
4.8 KiB
Python
169 lines
4.8 KiB
Python
import pandas as pd
|
|
import plotly.graph_objects as go
|
|
from plotly.subplots import make_subplots
|
|
from typing import Dict, List
|
|
import json
|
|
import os
|
|
|
|
def plot_backtest_results(results_file: str, save_path: str = None):
|
|
"""
|
|
Create interactive plots for backtest results
|
|
"""
|
|
# Load results
|
|
with open(results_file, 'r') as f:
|
|
results = json.load(f)
|
|
|
|
# Convert data to DataFrames
|
|
trades_df = pd.DataFrame(results['trades'])
|
|
equity_df = pd.DataFrame(results['equity_curve'])
|
|
|
|
# Create figure with secondary y-axis
|
|
fig = make_subplots(
|
|
rows=2, cols=1,
|
|
shared_xaxes=True,
|
|
vertical_spacing=0.03,
|
|
subplot_titles=('Price and Trades', 'Equity Curve'),
|
|
row_heights=[0.7, 0.3]
|
|
)
|
|
|
|
# Add price line
|
|
fig.add_trace(
|
|
go.Scatter(
|
|
x=trades_df['timestamp'],
|
|
y=trades_df['price'],
|
|
name='Price',
|
|
line=dict(color='blue')
|
|
),
|
|
row=1, col=1
|
|
)
|
|
|
|
# Add buy trades
|
|
buy_trades = trades_df[trades_df['action'] == 'buy']
|
|
fig.add_trace(
|
|
go.Scatter(
|
|
x=buy_trades['timestamp'],
|
|
y=buy_trades['price'],
|
|
mode='markers',
|
|
name='Buy',
|
|
marker=dict(color='green', size=10)
|
|
),
|
|
row=1, col=1
|
|
)
|
|
|
|
# Add sell trades
|
|
sell_trades = trades_df[trades_df['action'] == 'sell']
|
|
fig.add_trace(
|
|
go.Scatter(
|
|
x=sell_trades['timestamp'],
|
|
y=sell_trades['price'],
|
|
mode='markers',
|
|
name='Sell',
|
|
marker=dict(color='red', size=10)
|
|
),
|
|
row=1, col=1
|
|
)
|
|
|
|
# Add equity curve
|
|
fig.add_trace(
|
|
go.Scatter(
|
|
x=equity_df['timestamp'],
|
|
y=equity_df['equity'],
|
|
name='Equity',
|
|
line=dict(color='purple')
|
|
),
|
|
row=2, col=1
|
|
)
|
|
|
|
# Update layout
|
|
fig.update_layout(
|
|
title='Backtest Results',
|
|
xaxis_title='Date',
|
|
yaxis_title='Price',
|
|
yaxis2_title='Equity',
|
|
showlegend=True,
|
|
height=800
|
|
)
|
|
|
|
# Save plot if path is provided
|
|
if save_path:
|
|
fig.write_html(save_path)
|
|
print(f"Plot saved to {save_path}")
|
|
|
|
return fig
|
|
|
|
def plot_performance_metrics(results_files: List[str], save_path: str = None):
|
|
"""
|
|
Create comparison plot of performance metrics across different scenarios
|
|
"""
|
|
metrics_data = []
|
|
|
|
for file in results_files:
|
|
with open(file, 'r') as f:
|
|
results = json.load(f)
|
|
metrics = results['performance_metrics']
|
|
|
|
# Extract scenario name from filename
|
|
scenario_name = os.path.basename(file).replace('backtest_results_', '').replace('.json', '')
|
|
|
|
metrics_data.append({
|
|
'Scenario': scenario_name,
|
|
'Total Return': metrics['total_return'],
|
|
'Annual Return': metrics['annual_return'],
|
|
'Sharpe Ratio': metrics['sharpe_ratio'],
|
|
'Max Drawdown': metrics['max_drawdown'],
|
|
'Win Rate': metrics['win_rate']
|
|
})
|
|
|
|
# Create DataFrame
|
|
df = pd.DataFrame(metrics_data)
|
|
|
|
# Create figure
|
|
fig = go.Figure()
|
|
|
|
# Add bars for each metric
|
|
metrics = ['Total Return', 'Annual Return', 'Sharpe Ratio', 'Max Drawdown', 'Win Rate']
|
|
for metric in metrics:
|
|
fig.add_trace(
|
|
go.Bar(
|
|
name=metric,
|
|
x=df['Scenario'],
|
|
y=df[metric]
|
|
)
|
|
)
|
|
|
|
# Update layout
|
|
fig.update_layout(
|
|
title='Performance Metrics Comparison',
|
|
xaxis_title='Scenario',
|
|
yaxis_title='Value',
|
|
barmode='group',
|
|
height=600
|
|
)
|
|
|
|
# Save plot if path is provided
|
|
if save_path:
|
|
fig.write_html(save_path)
|
|
print(f"Plot saved to {save_path}")
|
|
|
|
return fig
|
|
|
|
def main():
|
|
# Example usage
|
|
results_dir = 'backtest_results'
|
|
results_files = [
|
|
os.path.join(results_dir, f) for f in os.listdir(results_dir)
|
|
if f.startswith('backtest_results_') and f.endswith('.json')
|
|
]
|
|
|
|
# Create plots for each scenario
|
|
for file in results_files:
|
|
scenario_name = os.path.basename(file).replace('.json', '')
|
|
plot_path = os.path.join(results_dir, f'{scenario_name}_plot.html')
|
|
plot_backtest_results(file, plot_path)
|
|
|
|
# Create comparison plot
|
|
comparison_path = os.path.join(results_dir, 'performance_comparison.html')
|
|
plot_performance_metrics(results_files, comparison_path)
|
|
|
|
if __name__ == "__main__":
|
|
main() |