mcpField
T
trading-visualization

trading-visualization

github.com/agiprolabs数据与数据库456515 次安装8 周前更新
代码仓库

关于 trading-visualization

使用 mplfinance、matplotlib 和 plotly 制作交易图表的技能。内容涵盖价格与指标视图、策略表现和风险图表,并支持静态及交互式输出,用于分析和报告。

主要功能

  1. 01带叠加指标的蜡烛图
  2. 02权益曲线与回撤图
  3. 03收益分布与相关性热图
  4. 04交易标记与指标面板
  5. 05输出 PNG、SVG 和 HTML

适用场景

  1. 01检查策略收益和回撤
  2. 02探索价格、成交量及指标模式
  3. 03制作可视化绩效报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/agiprolabs/claude-trading-skills --skill trading-visualization

安装后在 Claude Code 中输入/trading-visualization确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
chart_recipes.md
styling_guide.md
scripts/
chart_generator.py
performance_report.py

详细介绍

交易可视化

可视化是交易者与数据之间的主要接口。图表能够揭示表格和数字无法呈现的模式:策略失效、市场状态转换、亏损聚集以及风险形态。设计良好的图表一眼传达的信息,胜过一整页统计数据。

交易图表的三种用途:

  1. 模式识别 — 发现定量筛选器会遗漏的价格、成交量和动量结构变化。
  2. 策略评估 — 权益曲线、回撤图和收益分布可以揭示策略是否稳健,还是经过曲线拟合。
  3. 报告 — 通过出版级视觉效果,向利益相关者、交易日志或未来的自己传达业绩。

涵盖的图表类型

图表类型用途库
蜡烛图带叠加指标的 OHLCV 价格走势mplfinance
权益曲线随时间变化的投资组合价值matplotlib
回撤水下权益图matplotlib
收益分布直方图 + 正态拟合matplotlib
相关性热力图跨资产相关性矩阵matplotlib / seaborn
交易标记价格图上的入场/出场点mplfinance / matplotlib
指标面板价格图下方的 RSI、MACDmplfinance
持仓时间线持仓时间段matplotlib

库

mplfinance

最适合绘制蜡烛图。基于 matplotlib 构建,默认设置专为金融图表设计。

uv pip install mplfinance
import mplfinance as mpf

# Basic candlestick from a DataFrame with DatetimeIndex
# Columns: Open, High, Low, Close, Volume
mpf.plot(df, type="candle", volume=True, style="charles")

主要功能:

  • 原生支持 OHLCV — 可直接传入 DataFrame
  • 内置成交量柱
  • 使用 addplot 添加叠加指标(移动平均线、布林带)
  • 通过 mpf.make_mpf_style() 自定义样式
matplotlib

通用且灵活性最高。需要完全控制布局时使用。

uv pip install matplotlib
import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 1, figsize=(14, 8), height_ratios=[3, 1],
                         sharex=True)
axes[0].plot(dates, equity, color="#00ff88")
axes[1].fill_between(dates, drawdown, 0, color="#ff4444", alpha=0.5)
plotly

以 HTML 格式渲染的交互式图表。最适合探索和仪表板。

uv pip install plotly
import plotly.graph_objects as go

fig = go.Figure(data=[go.Candlestick(
    x=df.index, open=df["Open"], high=df["High"],
    low=df["Low"], close=df["Close"]
)])
fig.update_layout(template="plotly_dark")
fig.write_html("chart.html")

样式:默认使用深色主题

交易终端默认使用深色背景。本技能中的所有图表均遵循这一惯例。

快速设置深色主题
import matplotlib.pyplot as plt

plt.style.use("dark_background")
plt.rcParams.update({
    "figure.facecolor": "#1a1a2e",
    "axes.facecolor": "#1a1a2e",
    "axes.edgecolor": "#333333",
    "grid.color": "#333333",
    "grid.alpha": 0.4,
    "text.color": "#e0e0e0",
    "xtick.color": "#aaaaaa",
    "ytick.color": "#aaaaaa",
})
交易配色方案
元素颜色Hex
看涨 / 盈利绿色#00ff88
看跌 / 亏损红色#ff4444
中性 / 信息蓝色#4488ff
警告琥珀色#ffaa00
短期 MA橙色#ff6600
长期 MA蓝色#3399ff
信号 MA黄色#ffcc00

完整的字体排版、布局比例和导出设置请参阅 references/styling_guide.md。


图表构成:多面板布局

大多数交易图表需要多个同步面板 — 顶部显示价格,中间显示成交量,底部显示指标。

共享 x 轴的堆叠面板
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(14, 10))
gs = gridspec.GridSpec(3, 1, height_ratios=[3, 1, 1], hspace=0.05)

ax_price = fig.add_subplot(gs[0])
ax_volume = fig.add_subplot(gs[1], sharex=ax_price)
ax_rsi = fig.add_subplot(gs[2], sharex=ax_price)

# Hide x-tick labels on upper panels
ax_price.tick_params(labelbottom=False)
ax_volume.tick_params(labelbottom=False)
面板高度比例
布局比例使用场景
价格 + 成交量[3, 1]简单的 OHLCV 图表
价格 + 成交量 + 指标[3, 1, 1]标准分析视图
权益 + 回撤[2, 1]业绩回顾
价格 + RSI + MACD[3, 1, 1]完整指标面板

带叠加指标的蜡烛图

import mplfinance as mpf
import pandas as pd

# df: DataFrame with DatetimeIndex, columns Open/High/Low/Close/Volume
ema20 = df["Close"].ewm(span=20).mean()
ema50 = df["Close"].ewm(span=50).mean()

ap = [
    mpf.make_addplot(ema20, color="#ff6600", width=1.2),
    mpf.make_addplot(ema50, color="#3399ff", width=1.2),
]

style = mpf.make_mpf_style(
    base_mpf_style="nightclouds",
    marketcolors=mpf.make_marketcolors(
        up="#00ff88", down="#ff4444",
        wick={"up": "#00ff88", "down": "#ff4444"},
        edge={"up": "#00ff88", "down": "#ff4444"},
        volume={"up": "#00ff88", "down": "#ff4444"},
    ),
    facecolor="#1a1a2e", figcolor="#1a1a2e",
    gridcolor="#333333", gridstyle="--",
)

mpf.plot(df, type="candle", style=style, addplot=ap,
         volume=True, figsize=(14, 8),
         title="Token / SOL — 15m", savefig="candles.png")

带回撤面板的权益曲线

import numpy as np
import matplotlib.pyplot as plt

def plot_equity_drawdown(equity: pd.Series, title: str = "Portfolio") -> plt.Figure:
    """Plot equity curve with drawdown panel below."""
    peak = equity.cummax()
    drawdown = (equity - peak) / peak

    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8),
                                    height_ratios=[2, 1], sharex=True)
    ax1.plot(equity.index, equity, color="#00ff88", linewidth=1.5)
    ax1.plot(equity.index, peak, color="#555555", linewidth=0.8,
             linestyle="--", label="Peak")
    ax1.set_title(title, fontsize=14, fontweight="bold", color="white")
    ax1.set_ylabel("Portfolio Value", fontsize=11)
    ax1.legend(loc="upper left")
    ax1.grid(True, alpha=0.3)

    ax2.fill_between(equity.index, drawdown, 0, color="#ff4444", alpha=0.5)
    ax2.set_ylabel("Drawdown", fontsize=11)
    ax2.set_xlabel("Date", fontsize=11)
    ax2.grid(True, alpha=0.3)

    fig.tight_layout()
    return fig

收益分布

from scipy import stats

def plot_return_distribution(returns: pd.Series) -> plt.Figure:
    """Histogram of returns with normal fit and risk metrics."""
    fig, ax = plt.subplots(figsize=(10, 6))

    ax.hist(returns, bins=50, density=True, alpha=0.7,
            color="#4488ff", edgecolor="#333333")

    # Normal fit overlay
    mu, sigma = returns.mean(), returns.std()
    x = np.linspace(returns.min(), returns.max(), 200)
    ax.plot(x, stats.norm.pdf(x, mu, sigma), color="#ffaa00",
            linewidth=2, label=f"Normal(μ={mu:.4f}, σ={sigma:.4f})")

    # VaR line
    var_95 = returns.quantile(0.05)
    ax.axvline(var_95, color="#ff4444", linestyle="--",
               label=f"VaR 95%: {var_95:.4f}")

    ax.set_title("Return Distribution", fontsize=14, fontweight="bold")
    ax.set_xlabel("Return", fontsize=11)
    ax.legend()
    ax.grid(True, alpha=0.3)
    fig.tight_layout()
    return fig

相关性热力图

def plot_correlation_heatmap(returns_df: pd.DataFrame) -> plt.Figure:
    """Correlation matrix heatmap with annotations."""
    corr = returns_df.corr()
    fig, ax = plt.subplots(figsize=(10, 8))
    im = ax.imshow(corr, cmap="RdYlGn", vmin=-1, vmax=1, aspect="auto")

    ax.set_xticks(range(len(corr.columns)))
    ax.set_yticks(range(len(corr.columns)))
    ax.set_xticklabels(corr.columns, rotation=45, ha="right")
    ax.set_yticklabels(corr.columns)

    for i in range(len(corr)):
        for j in range(len(corr)):
            ax.text(j, i, f"{corr.iloc[i, j]:.2f}",
                    ha="center", va="center", fontsize=9,
                    color="black" if abs(corr.iloc[i, j]) < 0.5 else "white")

    fig.colorbar(im, ax=ax, shrink=0.8)
    ax.set_title("Correlation Matrix", fontsize=14, fontweight="bold")
    fig.tight_layout()
    return fig

价格图上的交易标记

def plot_trades_on_price(
    price: pd.Series,
    entries: pd.DataFrame,  # columns: date, price, side
    exits: pd.DataFrame,    # columns: date, price, pnl
) -> plt.Figure:
    """Price chart with entry/exit markers."""
    fig, ax = plt.subplots(figsize=(14, 7))
    ax.plot(price.index, price, color="#aaaaaa", linewidth=1)

    # Entry markers
    buy_mask = entries["side"] == "long"
    ax.scatter(entries.loc[buy_mask, "date"], entries.loc[buy_mask, "price"],
               marker="^", color="#00ff88", s=100, zorder=5, label="Buy")
    ax.scatter(entries.loc[~buy_mask, "date"], entries.loc[~buy_mask, "price"],
               marker="v", color="#ff4444", s=100, zorder=5, label="Short")

    # Exit markers
    win_mask = exits["pnl"] > 0
    ax.scatter(exits.loc[win_mask, "date"], exits.loc[win_mask, "price"],
               marker="x", color="#00ff88", s=80, zorder=5)
    ax.scatter(exits.loc[~win_mask, "date"], exits.loc[~win_mask, "price"],
               marker="x", color="#ff4444", s=80, zorder=5)

    ax.set_title("Trades on Price", fontsize=14, fontweight="bold")
    ax.legend()
    ax.grid(True, alpha=0.3)
    fig.tight_layout()
    return fig

输出格式

格式方法使用场景
PNGfig.savefig("chart.png", dpi=150)分享、嵌入
SVGfig.savefig("chart.svg")编辑、缩放
HTMLfig.write_html("chart.html") (plotly)交互式探索
内联plt.show()Jupyter 笔记本
使用深色背景保存
fig.savefig("chart.png", dpi=150, facecolor=fig.get_facecolor(),
            edgecolor="none", bbox_inches="tight")

与其他技能集成

技能集成方式
pandas-ta计算指标,并传递给 addplot 叠加图
vectorbt提取权益曲线和交易列表以进行可视化
portfolio-analytics绘制夏普比率、回撤和收益指标
risk-management可视化随时间变化的头寸限额和风险敞口
position-sizing绘制随时间变化的头寸规模与账户权益
regime-detection根据检测到的市场状态为背景着色
correlation-analysis根据收益数据生成相关性热力图

文件

参考资料
  • references/chart_recipes.md — 六种常见图表类型的完整代码示例
  • references/styling_guide.md — 深色主题设置、颜色、排版、布局和导出设置
脚本
  • scripts/chart_generator.py — 使用合成数据生成四种图表(蜡烛图、权益图、收益图、交易图)
  • scripts/performance_report.py — 包含汇总统计的多图表绩效报告

评论

支持 Markdown