Files
my_metatrader5_mcp/mtlib/plot.py
T

53 lines
2.0 KiB
Python
Raw Normal View History

"""回测图表 - 4 面板图(价格+交易 / 权益 / 每笔PnL分布 / 累计PnL)"""
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def plot_results(df, equity_curve, trades, metrics, save_path):
fig, axes = plt.subplots(4, 1, figsize=(16, 20),
gridspec_kw={'height_ratios': [3, 1, 1, 1]})
ax1 = axes[0]
ax1.plot(df['time'], df['close'], color='black', linewidth=0.5, label='Close')
if trades:
for t in trades:
color = 'green' if t['direction'] == 1 else 'red'
marker = '^' if t['direction'] == 1 else 'v'
ax1.scatter(df['time'].iloc[t['entry_bar']], t['entry_price'],
marker=marker, color=color, s=30, zorder=5)
ax1.set_title(f'Price & Trades (Total: {metrics["total_trades"]})')
ax1.legend()
ax1.grid(True, alpha=0.3)
ax2 = axes[1]
ax2.plot(df['time'], equity_curve, color='blue', linewidth=0.8)
ax2.axhline(y=equity_curve[0] if equity_curve else 10000,
color='gray', linestyle='--', alpha=0.5)
ax2.set_title(f'Equity Curve - Return: {metrics["total_return_pct"]}% '
f'| MaxDD: {metrics["max_drawdown_pct"]}%')
ax2.grid(True, alpha=0.3)
ax3 = axes[2]
if trades:
pnl = [t['pnl'] for t in trades]
colors = ['green' if p > 0 else 'red' for p in pnl]
ax3.bar(range(len(trades)), pnl, color=colors, width=1)
ax3.set_title(f'Trade P&L Distribution - Win Rate: {metrics["win_rate"]}% '
f'| PF: {metrics["profit_factor"]}')
ax3.axhline(y=0, color='black', linewidth=0.5)
ax3.grid(True, alpha=0.3)
ax4 = axes[3]
if trades:
cum_pnl = np.cumsum([t['pnl'] for t in trades])
ax4.plot(range(len(trades)), cum_pnl, color='purple', linewidth=1)
ax4.set_title('Cumulative P&L')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
fig.savefig(save_path, dpi=100, bbox_inches='tight')
plt.close(fig)