|
| 1 | +--- |
| 2 | +name: trade-journal |
| 3 | +description: Analyze a user's trade journal (CSV/Excel broker export). Parses 同花顺/东方财富/富途/generic formats, produces a trading profile and 4 behavior diagnostics (disposition effect, overtrading, chasing, anchoring). Use the `analyze_trade_journal` tool. |
| 4 | +category: tool |
| 5 | +--- |
| 6 | +# Trade Journal Analysis |
| 7 | + |
| 8 | +## Purpose |
| 9 | + |
| 10 | +Users upload broker exports (交割单) and get an honest, data-grounded portrait |
| 11 | +of their own trading. Two layers are live: |
| 12 | + |
| 13 | +- **Profile** — holding days, frequency, win rate, PnL ratio, cumulative PnL, |
| 14 | + max drawdown, top symbols, market/hourly distribution. |
| 15 | +- **Behavior diagnostics** — 4 biases, each with severity (low/medium/high) |
| 16 | + and numeric evidence: disposition effect, overtrading, chasing momentum, |
| 17 | + anchoring. |
| 18 | + |
| 19 | +Strategy extraction → backtest bridge lands in Phase 4c. |
| 20 | + |
| 21 | +Supported formats (auto-detected): |
| 22 | +- **同花顺** (Tonghuashun) — A-share CSV, typically GBK-encoded |
| 23 | +- **东方财富** (Eastmoney) — A-share CSV, typically GBK-encoded |
| 24 | +- **富途** (Futu) — HK/US CSV, UTF-8 |
| 25 | +- **Generic** — any CSV with columns like `datetime/symbol/side/qty/price` |
| 26 | + |
| 27 | +## Usage |
| 28 | + |
| 29 | +**Call the `analyze_trade_journal` tool directly. Never run Python from bash.** |
| 30 | + |
| 31 | +``` |
| 32 | +analyze_trade_journal(file_path="uploads/xxx.csv") |
| 33 | +analyze_trade_journal(file_path="uploads/xxx.csv", analysis_type="profile") |
| 34 | +analyze_trade_journal(file_path="uploads/xxx.csv", filter_expr="2026-01 to 2026-03") |
| 35 | +analyze_trade_journal(file_path="uploads/xxx.csv", filter_expr="symbol=600519.SH") |
| 36 | +analyze_trade_journal(file_path="uploads/xxx.csv", filter_expr="market=china_a") |
| 37 | +``` |
| 38 | + |
| 39 | +`analysis_type`: |
| 40 | +- `full` (default) — profile + behavior (strategy still placeholder) |
| 41 | +- `profile` — profile metrics only (fastest) |
| 42 | +- `behavior` — 4 behavior diagnostics only |
| 43 | +- `strategy` — Phase 4c placeholder |
| 44 | + |
| 45 | +`filter_expr` (optional): |
| 46 | +- Date range: `"YYYY-MM to YYYY-MM"` or `"YYYY-MM-DD to YYYY-MM-DD"` |
| 47 | +- Symbol: `"symbol=600519.SH"` (exact match on qualified symbol) |
| 48 | +- Market: `"market=china_a|us|hk|crypto"` |
| 49 | + |
| 50 | +## Return shape (profile subset) |
| 51 | + |
| 52 | +```json |
| 53 | +{ |
| 54 | + "status": "ok", |
| 55 | + "file": "xxx.csv", |
| 56 | + "format_detected": "tonghuashun", |
| 57 | + "total_records": 326, |
| 58 | + "date_range": "2026-01-06 ~ 2026-03-28", |
| 59 | + "symbols_count": 42, |
| 60 | + "market": "china_a", |
| 61 | + "profile": { |
| 62 | + "total_trades": 326, |
| 63 | + "total_roundtrips": 118, |
| 64 | + "avg_holding_days": 3.2, |
| 65 | + "trade_frequency_per_week": 4.1, |
| 66 | + "win_rate": 0.48, |
| 67 | + "profit_loss_ratio": 1.35, |
| 68 | + "total_pnl": 18240.55, |
| 69 | + "max_drawdown": -9820.10, |
| 70 | + "top_symbols": [{"symbol": "600519.SH", "trades": 14, "total_amount": 1.02e6}, ...], |
| 71 | + "market_distribution": {"china_a": 326}, |
| 72 | + "hourly_distribution": {9: 52, 10: 84, ...}, |
| 73 | + "roundtrips_sample": [{"symbol": "600519.SH", "buy_dt": "...", "sell_dt": "...", "pnl": 3400.1, "pnl_pct": 0.021, "hold_days": 2.5}, ...] |
| 74 | + } |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +Note: PnL uses FIFO lot matching; unmatched open positions are excluded from |
| 79 | +win rate / PnL ratio (only closed round-trips count). |
| 80 | + |
| 81 | +## Presenting results to the user |
| 82 | + |
| 83 | +Produce a **single markdown report** in the user's language. Lead with the |
| 84 | +top-line numbers, then section-by-section. Keep it dense — this is retail |
| 85 | +readers skimming on a phone. |
| 86 | + |
| 87 | +### Report template |
| 88 | + |
| 89 | +``` |
| 90 | +## 你的交易画像 — {date_range} |
| 91 | +
|
| 92 | +**总体** |
| 93 | +- 交易笔数:{total_trades}(完整来回 {total_roundtrips} 次) |
| 94 | +- 平均持仓:{avg_holding_days} 天 |
| 95 | +- 交易频率:{trade_frequency_per_week} 次/周 |
| 96 | +- 胜率:{win_rate:.0%} |
| 97 | +- 盈亏比:{profit_loss_ratio} |
| 98 | +- 累计盈亏:{total_pnl} |
| 99 | +- 最大回撤:{max_drawdown} |
| 100 | +
|
| 101 | +**最常交易的标的**(前 5 名) |
| 102 | +| 标的 | 笔数 | 成交额 | |
| 103 | +|------|------|--------| |
| 104 | +| ... | ... | ... | |
| 105 | +
|
| 106 | +**市场分布** |
| 107 | +{market_distribution} |
| 108 | +
|
| 109 | +**交易时段** |
| 110 | +{hourly_distribution — highlight peak hours} |
| 111 | +
|
| 112 | +**一句话观察** |
| 113 | +(根据数据写 1-2 句:过度交易?只做窄范围标的?集中在某时段?) |
| 114 | +``` |
| 115 | + |
| 116 | +Guidance: |
| 117 | +- If `win_rate < 0.4` AND `profit_loss_ratio < 1.0` → explicit warning: losing |
| 118 | + on both win rate and payoff. Ask whether they want behavior diagnostics |
| 119 | + (Phase 4b) or a cooling-off reality check. |
| 120 | +- If `avg_holding_days < 1` AND `trade_frequency_per_week > 15` → flag |
| 121 | + intraday-heavy pattern, note that minute-level backtest would be better. |
| 122 | +- If `symbols_count <= 3` → concentration risk; ask if they want a sector- |
| 123 | + diversification check. |
| 124 | + |
| 125 | +## Follow-up dialogue |
| 126 | + |
| 127 | +After the initial report, users typically ask: |
| 128 | +- **Time-slice**: "3 月份表现怎么样" → re-call with `filter_expr="2026-03-01 to 2026-03-31"`. |
| 129 | +- **Symbol deep-dive**: "茅台这只赚了多少" → `filter_expr="symbol=600519.SH"`. |
| 130 | +- **Market split**: "港股和美股分开看" → two calls, `market=hk` and `market=us`. |
| 131 | +- **Hypothetical** ("如果我严格止损 -5%") → Phase 4b feature; for now tell the |
| 132 | + user this is on the roadmap. |
| 133 | + |
| 134 | +Do NOT re-upload — the file path is still valid for subsequent tool calls |
| 135 | +in the same session. |
| 136 | + |
| 137 | +## Error handling |
| 138 | + |
| 139 | +- `File not found` / `Unsupported extension` — ask user to re-upload. |
| 140 | +- `Unrecognized trade journal format` — share the detected columns back to |
| 141 | + the user and ask them to rename the key columns to: `datetime, symbol, |
| 142 | + side, quantity, price, amount, fee` (generic fallback). |
| 143 | +- `No trade records parsed` — likely empty file or header-only; ask user to |
| 144 | + confirm the export contains actual fills. |
| 145 | + |
| 146 | +## Behavior diagnostics (shape) |
| 147 | + |
| 148 | +Under `result["behavior"]`: |
| 149 | + |
| 150 | +```json |
| 151 | +{ |
| 152 | + "disposition_effect": { |
| 153 | + "severity": "high", |
| 154 | + "ratio_loss_to_win_hold": 1.69, |
| 155 | + "avg_winner_hold_days": 7.4, |
| 156 | + "avg_loser_hold_days": 12.5, |
| 157 | + "evidence": "Losing roundtrips held 12.5d vs winning 7.4d (ratio 1.69). Classic disposition pattern." |
| 158 | + }, |
| 159 | + "overtrading": { |
| 160 | + "severity": "high", |
| 161 | + "busy_day_avg_pnl": -2632, |
| 162 | + "quiet_day_avg_pnl": 759, |
| 163 | + "evidence": "On busy days (≥3 trades) avg PnL -2632; on quiet days (≤1) avg PnL +759. High activity hurts returns." |
| 164 | + }, |
| 165 | + "chasing_momentum": { |
| 166 | + "severity": "medium", |
| 167 | + "chase_ratio": 0.5, |
| 168 | + "buys_evaluated": 4, |
| 169 | + "evidence": "2/4 buys (50%) came after a >3% price run-up in the same symbol. Some chasing tendency." |
| 170 | + }, |
| 171 | + "anchoring": { |
| 172 | + "severity": "high", |
| 173 | + "anchored_symbol_ratio": 0.83, |
| 174 | + "symbols_evaluated": 6, |
| 175 | + "anchored_symbols": [...], |
| 176 | + "evidence": "5/6 frequently-traded symbols stayed in a narrow price band (CV<5%). Strong anchoring." |
| 177 | + } |
| 178 | +} |
| 179 | +``` |
| 180 | + |
| 181 | +### Detection logic (for user-facing explanation) |
| 182 | + |
| 183 | +| Bias | Metric | Medium | High | |
| 184 | +|------|--------|--------|------| |
| 185 | +| **Disposition effect** | avg_loser_hold / avg_winner_hold | ≥ 1.2 | ≥ 1.5 | |
| 186 | +| **Overtrading** | (quiet − busy) / \|quiet\| day-PnL gap | ≥ 0.3 | ≥ 1.0 | |
| 187 | +| **Chasing** | fraction of buys after 3-trade rolling +3% move | ≥ 40% | ≥ 60% | |
| 188 | +| **Anchoring** | fraction of ≥5-trade symbols with price CV < 5% | ≥ 33% | ≥ 66% | |
| 189 | + |
| 190 | +### Report section (Chinese) |
| 191 | + |
| 192 | +``` |
| 193 | +## 行为偏差诊断 |
| 194 | +
|
| 195 | +| 偏差 | 严重程度 | 核心证据 | |
| 196 | +|------|----------|----------| |
| 197 | +| 处置效应 | {high/medium/low} | {evidence} | |
| 198 | +| 过度交易 | {...} | {...} | |
| 199 | +| 追涨杀跌 | {...} | {...} | |
| 200 | +| 锚定效应 | {...} | {...} | |
| 201 | +
|
| 202 | +**改进建议**(根据检测到的 high/medium 项生成): |
| 203 | +- 处置效应 high → 写死止损(例如 -8%),盈利持仓不要过早兑现 |
| 204 | +- 过度交易 high → 每日交易次数 <= N 的硬约束 |
| 205 | +- 追涨杀跌 high → 改买回调而不是新高,设置"涨幅 X% 以上当日不追"规则 |
| 206 | +- 锚定效应 high → 扩宽价格带,不要死守某个"心理价" |
| 207 | +``` |
| 208 | + |
| 209 | +## Phase 4c preview (not yet implemented) |
| 210 | + |
| 211 | +Strategy extraction → SignalEngine code gen → auto-backtest lands in Phase 4c. |
| 212 | +When the user asks for it, respond honestly and offer the behavior diagnostics |
| 213 | +instead (they're live). |
0 commit comments