关于 trade-journal
面向希望系统复盘表现与行为的交易者的交易日志技能。它以 JSON 或 CSV 记录交易背景和结果,并提供分析及行为模式检测脚本。
主要功能
- 01结构化交易记录
- 02JSON 存储与 CSV 导出
- 03按策略分析表现
- 04检测交易行为模式
- 05日、周、月度复盘
- 06命令行记录与分析脚本
适用场景
- 01比较不同交易策略的表现
- 02发现报复性交易或 FOMO 模式
- 03按时段或代币复盘表现
- 04跟踪交易流程调整效果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill trade-journal安装后在 Claude Code 中输入/trade-journal确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/record_format.mdreview_framework.mdscripts/journal_analyzer.pytrade_logger.py详细介绍
交易日志
通过结构化交易日志实现系统性改进。记录每笔交易及其背景,按多个周期回顾表现,发现损害优势的行为模式,并将收益归因到具体策略。
为什么记录交易日志很重要
大多数交易者失败,不是因为策略不佳,而是因为行为不当。交易日志能将主观的“感觉”转化为客观数据:
- 策略归因:了解哪些形态真正赚钱,哪些只是感觉有利可图
- 行为检测:在报复性交易、FOMO 入场和过早离场造成更大影响之前及时发现
- 模式识别:发现自己周一早上的交易会亏钱,或是过早卖出 SOL 盈利仓位
- 问责:入场前写下理由,促使自己审慎决策
- 改进跟踪:衡量流程的改变是否真的改善了结果
没有日志,你只能根据噪声进行优化。有了日志,你才能根据有效信号进行优化。
交易记录结构
每条交易记录都会记录入场时的背景和离场时的结果。完整的 18 个字段结构请参阅 references/record_format.md。
最低必填字段
trade = {
"id": "T-20250310-001",
"token": "SOL",
"direction": "long",
"entry_date": "2025-03-10T14:30:00Z",
"entry_price": 142.50,
"size_sol": 5.0,
"strategy": "momentum-breakout",
"rationale": "Breaking above 4h resistance at 141.80 with volume confirmation",
"exit_date": "2025-03-10T16:45:00Z",
"exit_price": 146.20,
"pnl_sol": 0.648,
"outcome": "win",
"lessons": "Held through initial pullback to 143.0, rewarded for patience"
}
策略标签
使用统一的标签来进行表现归因:
| 类别 | 标签 |
|---|---|
| 动量 | momentum-breakout、trend-continuation、pullback-entry |
| 均值回归 | range-fade、oversold-bounce、deviation-snap |
| 事件驱动 | listing-play、catalyst-trade、news-reaction |
| 链上 | whale-follow、wallet-copy、flow-signal |
| DeFi | lp-entry、yield-farm、arb-capture |
理由模板
入场前先写下理由。以下是按形态类型分类的模板:
Momentum: "[Token] breaking [level] on [timeframe] with [confirmation]. Target [price], stop [price]."
Mean Reversion: "[Token] at [X] std devs from [mean] on [timeframe]. Expecting reversion to [target]."
On-Chain: "[Signal type] detected — [wallet/flow description]. Historical hit rate [X]%."
存储格式
日志使用 JSON 进行结构化查询,并使用 CSV 兼容电子表格。
JSON 格式(主要)
{
"journal_version": "1.0",
"trader_id": "anon",
"trades": [
{
"id": "T-20250310-001",
"token": "SOL",
"direction": "long",
"entry_date": "2025-03-10T14:30:00Z",
"entry_price": 142.50,
"size_sol": 5.0,
"size_usd": 712.50,
"strategy": "momentum-breakout",
"setup_quality": 8,
"rationale": "Breaking above 4h resistance with volume",
"exit_date": "2025-03-10T16:45:00Z",
"exit_price": 146.20,
"pnl_sol": 0.648,
"pnl_pct": 2.60,
"outcome": "win",
"hold_time_minutes": 135,
"emotional_state": "calm",
"lessons": "Patience through pullback paid off",
"tags": ["high-conviction", "clean-setup"]
}
]
}
CSV 格式(导出)
id,token,direction,entry_date,entry_price,size_sol,strategy,exit_date,exit_price,pnl_sol,pnl_pct,outcome,lessons
T-20250310-001,SOL,long,2025-03-10T14:30:00Z,142.50,5.0,momentum-breakout,2025-03-10T16:45:00Z,146.20,0.648,2.60,win,"Patience paid off"
交易日志数据分析
按策略统计胜率
from collections import Counter
def win_rate_by_strategy(trades: list[dict]) -> dict[str, float]:
"""Compute win rate grouped by strategy tag."""
strategy_outcomes: dict[str, list[str]] = {}
for t in trades:
strat = t["strategy"]
strategy_outcomes.setdefault(strat, []).append(t["outcome"])
return {
strat: outcomes.count("win") / len(outcomes)
for strat, outcomes in strategy_outcomes.items()
if len(outcomes) >= 5 # minimum sample size
}
按时段统计表现
from datetime import datetime
def pnl_by_hour(trades: list[dict]) -> dict[int, float]:
"""Aggregate P&L by entry hour (UTC)."""
hourly: dict[int, float] = {}
for t in trades:
hour = datetime.fromisoformat(t["entry_date"].rstrip("Z")).hour
hourly[hour] = hourly.get(hour, 0.0) + t.get("pnl_sol", 0.0)
return dict(sorted(hourly.items()))
按代币类型统计盈利因子
def profit_factor(trades: list[dict], group_key: str = "token") -> dict[str, float]:
"""Compute profit factor (gross wins / gross losses) by grouping key."""
groups: dict[str, dict[str, float]] = {}
for t in trades:
key = t.get(group_key, "unknown")
groups.setdefault(key, {"wins": 0.0, "losses": 0.0})
pnl = t.get("pnl_sol", 0.0)
if pnl > 0:
groups[key]["wins"] += pnl
else:
groups[key]["losses"] += abs(pnl)
return {
k: v["wins"] / v["losses"] if v["losses"] > 0 else float("inf")
for k, v in groups.items()
}
行为模式检测
交易日志有助于发现破坏性的交易模式。完整框架请参阅 references/review_framework.md。
报复性交易
亏损后迅速重新入场,通常仓位更大:
def detect_revenge_trades(trades: list[dict], max_gap_minutes: int = 15) -> list[dict]:
"""Find trades entered within max_gap_minutes of a losing exit."""
sorted_trades = sorted(trades, key=lambda t: t["entry_date"])
revenge = []
for i in range(1, len(sorted_trades)):
prev, curr = sorted_trades[i - 1], sorted_trades[i]
if prev["outcome"] == "loss":
prev_exit = datetime.fromisoformat(prev["exit_date"].rstrip("Z"))
curr_entry = datetime.fromisoformat(curr["entry_date"].rstrip("Z"))
gap = (curr_entry - prev_exit).total_seconds() / 60
if gap <= max_gap_minutes:
revenge.append(curr)
return revenge
FOMO 检测
在价格大幅波动后入场,却没有合适的形态:
- 入场理由含糊不清或缺失
- 形态质量自评低于 5/10
- 入场时的波动幅度已超过 1 ATR
过早止盈/持有亏损仓位
def winner_loser_hold_times(trades: list[dict]) -> dict[str, float]:
"""Compare average hold time for wins vs losses."""
win_times = [t["hold_time_minutes"] for t in trades if t["outcome"] == "win"]
loss_times = [t["hold_time_minutes"] for t in trades if t["outcome"] == "loss"]
return {
"avg_win_hold_min": sum(win_times) / len(win_times) if win_times else 0,
"avg_loss_hold_min": sum(loss_times) / len(loss_times) if loss_times else 0,
}
# RED FLAG: if avg_loss_hold > avg_win_hold, you're cutting winners and riding losers
情绪失控检测
亏损后加大仓位表明交易受到情绪影响:
def detect_tilt(trades: list[dict], threshold: float = 1.5) -> list[dict]:
"""Flag trades where size increased >threshold after a loss."""
tilt_trades = []
for i in range(1, len(trades)):
prev, curr = trades[i - 1], trades[i]
if prev["outcome"] == "loss" and curr["size_sol"] > prev["size_sol"] * threshold:
tilt_trades.append(curr)
return tilt_trades
回顾频率
每日回顾(5 分钟)
- 今天进行了多少笔交易?盈亏如何?
- 每笔交易是否都遵守了规则?
- 是否做出了受情绪影响的决策?
- 一件做得好的事,以及一件需要改进的事
每周回顾(30 分钟)
- 按策略统计胜率和盈利因子
- 检查行为模式(报复性交易、情绪失控、FOMO)
- 本周最佳和最差的交易——它们有何不同?
- 策略表现与预期是否相符
- 如有需要,调整仓位规模
每月回顾(2 小时)
- 全面分析策略归因
- 回顾权益曲线——回撤阶段及恢复情况
- 比较每笔交易的实际风险与计划风险
- 按代币类型、时段和星期几分析表现
- 是否有策略持续亏损?考虑弃用
- 回顾并更新策略参数
详细的回顾清单和问题请参阅 references/review_framework.md。
部分离场和分批入场
实际交易涉及分批建仓和平仓。日志通过子记录处理这些情况:
# Parent trade with two scale-out exits
parent = {
"id": "T-20250310-001",
"token": "BONK",
"direction": "long",
"entry_date": "2025-03-10T14:30:00Z",
"entry_price": 0.000023,
"size_sol": 10.0,
"strategy": "momentum-breakout",
"exits": [
{"date": "2025-03-10T15:00:00Z", "price": 0.000025, "size_pct": 50, "reason": "first-target"},
{"date": "2025-03-10T16:30:00Z", "price": 0.000028, "size_pct": 50, "reason": "trailing-stop"},
]
}
部分离场处理的完整说明请参阅 references/record_format.md。
文件
参考资料
references/record_format.md— 完整的 18 字段交易记录架构、字段说明、标签分类、CSV/JSON 示例、部分平仓处理references/review_framework.md— 每日/每周/每月复盘清单、行为预警信号、绩效衰退检测
脚本
scripts/trade_logger.py— CLI 交易记录工具:添加、列出、更新、计算统计数据、筛选、演示模式(仅使用标准库)scripts/journal_analyzer.py— 交易日志分析:策略表现、行为模式、基于时间的分析、演示模式(仅使用标准库)
依赖项
两个脚本仅使用 Python 标准库(json、datetime、argparse、collections)。无需安装外部包。
# No installation needed — stdlib only
python scripts/trade_logger.py --demo
python scripts/journal_analyzer.py --demo
免责声明
此技能提供交易记录和绩效分析工具,不提供财务建议或交易推荐,也不保证任何交易结果。所有分析仅供参考,仅用于个人复盘。