为什么要做这件事
一直有个模糊的感觉:临时起意的交易,胜率明显低于按计划执行的交易。但"感觉"这东西在交易里最不值钱,于是我把 214 笔成交记录导出来,用 Python 跑了一遍。
结论比想象中更极端:
| 计划内卖出 | 96 | 6.2 | 58% | +2.1% |
| 临时起意 | 47 | 1.4 | 21% | -3.4% |
胜率差 37 个百分点,单笔盈亏差 5.5 个百分点。
数据准备
导出成交记录,最少需要这些字段:
import pandas as pd
cols = ['code', 'buy_date', 'sell_date', 'buy_price', 'sell_price',
'shares', 'planned'] # planned: 卖出是否符合事前计划
df = pd.read_csv('trades.csv', parse_dates=['buy_date', 'sell_date'])
```
## 核心指标计算
```python
df['ret'] = (df.sell_price – df.buy_price) / df.buy_price
df['hold'] = (df.sell_date – df.buy_date).dt.days
df['win'] = df.ret > 0
def summary(g):
return pd.Series({
'笔数': len(g),
'平均持仓': round(g.hold.mean(), 1),
'胜率': f'{g.win.mean()*100:.0f}%',
'平均每笔': f'{g.ret.mean()*100:+.1f}%',
'盈亏比': round(
g.loc[g.win, 'ret'].mean() / abs(g.loc[~g.win, 'ret'].mean()), 2)
})
print(df.groupby('planned').apply(summary, include_groups=False))
include_groups=False 是 pandas 2.2+ 的要求,不加会告警。
一个反直觉的发现
我把"临时起意"的交易再按持仓时长切一刀:
imp = df[~df.planned]
imp.groupby(pd.cut(imp.hold, [0, 1, 3, 7, 100]))['win'].agg(['mean', 'count'])
持仓不足 1 天的那部分,胜率只有 14%,而其中"当天买入当天卖出"的,接近一半是被分时图吓出来的。
换句话说:不是你的判断变差了,是决策场景变差了。
把它变成可执行的东西
复盘完我改了三处流程,都是工程问题,不是心态问题:
# 每天复盘只输出这一行,就够了
print(f"规则内交易占比: {df.planned.mean()*100:.0f}% "
f"规则内胜率: {df[df.planned].win.mean()*100:.0f}% "
f"违规胜率: {df[~df.planned].win.mean()*100:.0f}%")
```
## 一点想法
这套分析的真正价值不在于算出 58% 和 21%,而在于把"我最近状态不好"这种无法证伪的说法,换成了一个可以每周跟踪的数字:**规则内交易占比**。
从 68% 提升到 85%,我用了大概六周。期间学到的技术分析一点没变,收益结构变了。
–––
数据为个人交易记录,代码仅作方法论演示,不构成任何投资建议。


