trading-visualization について
mplfinance、matplotlib、plotlyを使った取引チャート作成スキルです。価格や指標、戦略の成績とリスクを可視化し、分析・レポート向けに静的またはインタラクティブ形式で出力します。
主な機能
- 01オーバーレイ付きローソク足チャート
- 02資産曲線とドローダウンのプロット
- 03リターン分布と相関ヒートマップ
- 04取引マーカーと指標パネル
- 05PNG・SVG・HTMLへの出力
活用シーン
- 01戦略のリターンとドローダウンを確認
- 02価格・出来高・指標のパターンを調査
- 03視覚的なパフォーマンスレポートを作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill trading-visualizationインストール後、Claude Code で/trading-visualizationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/chart_recipes.mdstyling_guide.mdscripts/chart_generator.pyperformance_report.py詳細
トレーディングの可視化
可視化は、トレーダーとデータをつなぐ主要なインターフェースです。チャートは、表や数値では見えてこないパターンを明らかにします。戦略の破綻、レジームの移行、損失の集中、リスクの形状などです。適切に設計されたチャートは、統計情報を1ページ見るよりも多くの情報をひと目で伝えます。
トレーディングチャートの3つの用途:
- パターン認識 — 定量的なフィルターでは見逃される、価格、出来高、モメンタムの構造変化を見つけます。
- 戦略の評価 — エクイティカーブ、ドローダウンプロット、リターン分布から、戦略の堅牢性やカーブフィッティングの有無を確認できます。
- レポート — ステークホルダー、記録、または将来の自分に、出版品質のビジュアルでパフォーマンスを伝えます。
対象となるチャートの種類
| チャートの種類 | 用途 | ライブラリ |
|---|---|---|
| ローソク足 | オーバーレイ付きのOHLCV価格推移 | mplfinance |
| エクイティカーブ | 時間経過に伴うポートフォリオ価値 | matplotlib |
| ドローダウン | 水中エクイティプロット | matplotlib |
| リターン分布 | ヒストグラム+正規分布フィット | matplotlib |
| 相関ヒートマップ | 複数資産の相関行列 | matplotlib / seaborn |
| トレードマーカー | 価格チャート上のエントリー/決済ポイント | mplfinance / matplotlib |
| インジケーターパネル | 価格チャート下部のRSI、MACD | mplfinance |
| ポジションのタイムライン | ポジションを保有していた期間 | 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
出力形式
| 形式 | 方法 | 用途 |
|---|---|---|
| PNG | fig.savefig("chart.png", dpi=150) | 共有、埋め込み |
| SVG | fig.savefig("chart.svg") | 編集、拡大縮小 |
| HTML | fig.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— よく使われる6種類のチャートのコードレシピ一式references/styling_guide.md— ダークテーマの設定、色、タイポグラフィ、レイアウト、エクスポート設定
スクリプト
scripts/chart_generator.py— 合成データから4種類のチャート(ローソク足、エクイティ、リターン、取引)を生成しますscripts/performance_report.py— 概要統計付きの複数チャートによるパフォーマンスレポート
コメント
Markdown 対応