基于 Van K. Tharp,Trade Your Way to Financial Freedom(第二版,2006)
Van K. Tharp,博士,是一位交易教练和心理学家,花了三十多年研究是什么将持续盈利的交易者与其他人区分开来。他本人不是一个主要交易员——他是交易者的研究者。通过他的公司Van Tharp研究所,他辅导了数千名交易员和投资者,涵盖各种市场、时间框架和风格。他的研究涉及广泛的心理画像、系统测试以及对全球顶尖交易员的访谈。
Tharp对交易文献的独特贡献是他坚持认为交易成功主要取决于心理、仓位规模和预期——而不是找到"正确的"入场信号或"正确的"市场。这与绝大多数交易书籍形成鲜明对比,后者专注于入场、指标和模式。
Trade Your Way to Financial Freedom 不是你可以复制的系统。它是一个用于设计、评估和实施你自己的交易系统的框架——适合你的个性、你的目标和你的市场信念。Tharp的核心论点是没有单一的"最佳"系统。只有适合你的系统和不适合你的系统。
本书涵盖:
绝大多数交易者和投资者几乎把所有时间都花在买什么上,而几乎不考虑买多少或何时卖。Tharp认为这种努力分配恰恰是相反的。他的重要性层次:
1. 心理与自我认知 — 占交易成功的60%
2. 仓位规模 — 占交易成功的30%
3. 系统(出场、入场、规则)— 占交易成功的10%
(其中入场是最不重要的组成部分)
这不是精确的数字主张,而是方向性的:大多数交易者忽视的因素恰恰是最重要的。
每个新手交易者都从同样的探索开始:找到几乎每笔交易都赢的系统、预测未来的指标、永不失败的模式。Tharp称之为寻找"圣杯"——他认为这在交易者想象的形式中并不存在。
真正的圣杯不是完美的系统。它是具有正预期值的系统、以适当的仓位规模交易、由心理上准备好的交易者执行。就是这样。没有神奇的指标,没有对公众隐藏的秘密公式。
市场由数百万具有不同时间框架、目标和信息的参与者的聚合行为驱动。没有模型能完美预测这种行为。即使世界上最好的交易系统,通常也有30%到60%之间的胜率。许多高盈利的趋势跟随系统在不到40%的交易中获胜。
关键洞见:你不需要大多数时候都正确。你需要数学在大量交易样本中对你有利。
| 组成部分 | 含义 | 为什么重要 |
|---|---|---|
| 正预期值 | 每美元风险的平均利润 > 0 | 没有这个,任何仓位规模都救不了你 |
| 适当的仓位规模 | 每笔交易正确的投注金额 | 决定你是否能存活以实现优势 |
| 心理适应性 | 按照设计执行系统的能力 | 你不能遵循的系统不是系统 |
Tharp描述了一个引人注目的实验:他设计了一个完全随机入场交易的系统——实际上是抛硬币做多或做空。该系统使用简单的基于波动的跟踪止损进行出场,使用百分比波动仓位规模模型。尽管随机入场,该系统在趋势市场中长期盈利。
重点不是入场无用。而是出场和仓位规模可以从甚至随机的入场中提取利润如果市场有趋势。如果你能用随机入场赚钱,想象一下用正确的出场和仓位规模处理好的入场能做什么。
R代表交易的初始风险——从入场价格到初始止损的美元距离。每笔交易的结果可以表示为这个初始风险的倍数。
R = 入场价格 - 初始止损价格 (做多)
R = 初始止损价格 - 入场价格 (做空)
交易的R倍数 = 利润或损失 / R
R倍数创造了一个通用语言用于比较交易,无论 инструмент、价格水平或账户规模。10美元股票上的2R赢家和500美元股票上的2R赢家代表相同的交易质量相对于所承担的风险。
示例1:一笔赢家交易
入场价格: $50.00
初始止损: $47.00
R(初始风险): $3.00每股
出场价格: $59.00
每股利润: $9.00
R倍数: $9.00 / $3.00 = +3.0R
这笔交易返回了初始风险的3倍。它是一个"3R赢家"。
示例2:一笔输家交易
入场价格: $50.00
初始止损: $47.00
R(初始风险): $3.00每股
出场价格: $46.50 (滑过止损)
每股损失: $3.50
R倍数: -$3.50 / $3.00 = -1.17R
这笔交易损失了初始风险的1.17倍。滑点导致损失大于1R。
示例3:一笔小赢家
入场价格: $50.00
初始止损: $47.00
R(初始风险): $3.00每股
出场价格: $51.80
每股利润: $1.80
R倍数: $1.80 / $3.00 = +0.6R
这笔交易赢了,但返回少于初始风险。它是一个"0.6R赢家"。
一个完整的交易系统产生一个R倍数分布超过许多交易。这个分布是系统的指纹。它告诉你:
一个稳健的系统产生的分布是均值正直立且大正异常值补偿更频繁的小负结果。
| R倍数范围 | 分类 |
|---|---|
| < -1.5R | 大亏损(止损失败、跳空、滑点) |
| -1.0R 到 -1.5R | 正常亏损(预期) |
| -0.5R 到 -1.0R | 小亏损(提前出场、收紧止损) |
| 0 到 +1.0R | 小盈利(盈亏平衡区域) |
| +1.0R 到 +3.0R | 好盈利 |
| +3.0R 到 +10.0R | 大盈利(盈利核心) |
| > +10.0R | 异常盈利(意外收获、趋势跟随 jackpot) |
预期值是所有交易的平均R倍数。它告诉你每笔交易平均每冒险一美元你期望赚多少。
预期值(E)= 平均R倍数
=(所有R倍数的总和)/(交易数量)
等效地,预期值可以分解:
E =(胜率% × 平均赢R)+(亏损率% × 平均亏R)
其中:
胜率 = 获胜交易的概率
亏损率 = 亏损交易的概率(= 1 - 胜率%)
平均赢R = 获胜交易的平均R倍数
平均亏R = 亏损交易的平均R倍数(负数)
一个系统在100笔交易中产生以下结果:
获胜交易: 40(胜率% = 40%)
亏损交易: 60(亏损率% = 60%)
平均赢家: +3.5R
平均输家: -1.0R
预期值 =(0.40 × 3.5)+(0.60 × -1.0)
= 1.40 +(-0.60)
= +0.80R
这意味着:每冒险一美元,你平均期望赚0.80美元。 尽管在60%的交易中亏损,系统高度盈利,因为赢家的规模相对于输家很大。
预期值告诉你:
预期值不告诉你:
没有任何仓位规模模型、资金管理技术或心理纪律可以将负预期值系统变成盈利系统。如果E < 0,你长期会亏损,保证的。损失的速度取决于仓位规模和机会,但方向是固定的。
这就是为什么Tharp坚持:首先确定你系统的预期值,在做任何其他事情之前。
总系统表现是预期值和机会(交易数量)的函数:
预期收益 = 预期值 × 交易数量 × 平均R(美元)
示例:
E = +0.80R
每年交易 = 50
每笔交易R = $500
预期年度收益 = 0.80 × 50 × $500 = $20,000
低预期值但高机会(许多交易)的系统可以胜过具有高预期值但少交易的系统。
Tharp观察到绝大多数交易者从寻找系统开始——任何"有效"的系统。他们从不定义"有效"对他们个人意味着什么。这就像设定旅程而不知道目的地。
像"赚钱"或"跑赢大盘"这样的模糊目标是无用的。Tharp要求交易者具体说明:
每个交易系统都涉及回报和回撤之间的基本权衡。更高的回报需要接受更大的回撤。目标100%年度回报的系统将不可避免地经历30-50%或更大的回撤。目标15%年度回报的系统可以设计成回撤在10%以下。
一般关系(近似):
最大回撤 ≈ 0.5× 到 1.0× 年度回报目标
示例:
目标:50%年度回报
预期最大回撤:25% 到 50%
如果你的最大可容忍回撤是15%,你不应该交易目标60%回报的系统。你的目标约束你的系统设计。
具有相同资本但不同心理画像、时间可用性和收入需求的两个交易者应该交易完全不同的系统。没有"最佳"系统——只有最最适合你的目标和心理的系统。
Tharp作为心理学家的背景影响了他的核心信念:你的交易结果是你心理组成的反映。 每个偏差、每个恐惧、每个验证需求都会通过你的交易表达自己。
| 偏差 | 在交易中的表现方式 | 后果 |
|---|---|---|
| 需要正确 | 拒绝接受亏损、均价下行 | 灾难性亏损 |
| 需要控制 | 过度交易、过度优化、微观管理 | 错失趋势、过度成本 |
| 赌徒谬误 | "连输5次后我该赢了" | 亏损后增加仓位规模 |
| 近因偏差 | 在系统评估中过度加权近期交易 | 在正常回撤期间放弃好系统 |
| 确认偏差 | 寻找支持现有持仓的信息 | 过久持有输家 |
| 锚定 | 固定在入场价格或近期高点 | 非理性的出场决策 |
| 损失厌恶 | 感受损失约2倍于等效收益 | 过早cut winners、过久持有输家 |
| 控制幻觉 | 相信更多分析 = 更多控制结果 | 过度复杂、瘫痪 |
Tharp坚持交易者必须诚实回答:
Tharp识别出一个进程:
Tharp laid out a structured methodology:
Step 1: Define your objectives (return, drawdown, time, capital)
Step 2: Inventory your beliefs about markets
Step 3: Develop a concept (trend-following, mean-reversion, etc.)
Step 4: Design entry signals
Step 5: Design exit strategies (worst-case stop, trailing stop, profit target)
Step 6: Determine position sizing
Step 7: Test the system historically
Step 8: Paper trade or trade very small
Step 9: Evaluate and refine
Step 10: Trade live with appropriate size
在设计任何系统之前,Tharp要求你写下你对市场的信念。例如:
你的系统必须与你的信念一致。如果你认为市场是有效的,你不应该设计趋势跟随系统。如果你认为基本面驱动价格,你不应该交易纯技术系统。信念与系统之间的不一致导致在回撤期间放弃。
每笔交易包括三个阶段:
设置: 必须为真的条件才能考虑交易。
(例如,"股票在其200日移动平均线之上且
ADX > 25 表明强劲趋势。")
入场: 导致你进入仓位的具体触发器。
(例如,"当价格突破20日高点时买入。")
出场: 你离开仓位的条件。
(例如,"初始止损在入场下方3x ATR。
跟踪止损在最高收盘下方3x ATR。
盈利目标:无——让趋势跑。"
Tharp做了一个大多数交易者错过的关键区分:
具有中等设置但中等入场的将胜过具有中等设置但"完美"入场的。
与其他大多数交易书籍相比,Tharp相对较少地讨论入场。他的理由:
| 入场类型 | 描述 | 示例 |
|---|---|---|
| 通道突破 | 价格突破N日高/低价 | 在55日高点买入(海龟风格) |
| 移动平均线交叉 | 快MA交叉慢MA | 10/30 EMA交叉 |
| 波动突破 | 价格从参考点移动超过N × ATR | 如果价格 > 昨日收盘 + 2 × ATR则买入 |
| 视觉模式 | 图表模式的主观识别 | 杯柄、旗形、上升三角形 |
| 基本面触发 | 盈利惊喜、收入beat、指引上调 | 在>20%盈利惊喜时买入 |
| 基于指标 | RSI、MACD、随机等 | 当RSI从30以下上穿时买入 |
虽然入场本身不太重要,但决定何时寻找入场的过滤器非常重要:
入场 exactly serves one function: 让你在一个可以定义有意义的初始止损的位置进入。 如果你能定义一个明确的止损——一个你知道你错了的水平——入场已经完成了它的工作。其他一切取决于你的出场和仓位规模。
出场决定:
Tharp认为出场是交易系统优势创造或摧毁的地方。
初始止损定义1R——如果交易立即对你不利,你愿意损失的最大金额。它必须在你入场交易之前设置,并且应该基于市场结构,而不是基于你愿意损失多少钱。
设置初始止损的方法:
| 方法 | 公式 | 示例 |
|---|---|---|
| 基于ATR | 入场 -(N × ATR) | 入场$50,ATR$2,N=3 → 止损在$44 |
| 基于百分比 | 入场 ×(1 - P%) | 入场$50,P=8% → 止损在$46 |
| 基于支撑 | 在最近支撑水平下方 | 支撑在$46.50 → 止损在$46.00 |
| 波动通道 | 在下方Keltner/Bollinger通道下方 | 在2.5 ATR通道下方 |
| 基于时间 | 如果N根 bars后无利润则出场 | 如果10天后无利润则出场 |
Tharp的首选:基于ATR的止损,因为它们自动适应工具的波动性。波动股票的3x ATR止损将比平静股票更宽,保持噪声触发止损的概率大致恒定。
一旦交易朝你有利的方向移动,跟踪止损移动到锁定利润同时给趋势呼吸空间。跟踪止损永远不应向后移动(朝向入场)。
跟踪止损方法:
1. ATR跟踪止损:
止损 = 最高收盘 -(N × ATR)
(当价格创新高时向上移动;永不向下)
2. 百分比跟踪止损:
止损 = 最高收盘 ×(1 - P%)
3. 移动平均线跟踪止损:
止损 = N期移动平均线
(当价格收于MA下方时出场)
4. 抛物线SAR:
加速止损,随趋势延伸而收紧
5. 吊灯止损:
止损 = 最高高 -(N × ATR)
(类似于ATR跟踪但从最高高测量)
Tharp通常对趋势跟随系统持怀疑态度,因为它们封顶上行并摧毁驱动盈利的大R倍数赢家。但是,他承认盈利目标可能适用于:
Tharp建议同时使用多种出场类型:
出场逻辑(按顺序评估):
1. 初始止损: 如果价格触及初始止损 → 以-1R出场全部仓位
2. 时间止损: 如果交易N bars后无利润 → 出场(小亏或持平)
3. 跟踪止损: 如果价格触及跟踪止损 → 出场(可变R倍数)
4. 盈利目标: 如果适用,在目标处出场部分或全部仓位
每个出场处理不同的失败模式:
Tharp认为仓位规模是决定你从正预期值系统赚或亏多少钱的唯一最重要因素。具有相同系统和相同入场/出场规则的两个交易者可能仅因仓位规模不同而有截然不同的结果。
最常推荐的模式。 每笔交易风险固定百分比权益。
仓位规模 =(账户权益 × 风险%)/ R每股
其中:
账户权益 = 当前账户价值
风险% = 风险的最大权益百分比(通常0.5%到2%)
R每股 = 入场价格 - 止损价格
示例:
账户权益:$100,000
风险%: 1%
入场价格: $50.00
止损价格: $47.00
R每股: $3.00
美元风险: $100,000 × 0.01 = $1,000
股数: $1,000 / $3.00 = 333股
仓位价值: 333 × $50 = $16,650(权益的16.7%)
特征:
每单位工具波动性风险固定百分比权益。 此模型通过波动性规范化仓位,因此波动工具获得较小仓位,平静工具获得较大仓位。
仓位规模 =(账户权益 × 波动性%)/ ATR每股
其中:
波动性% = 最大每日投资组合波动贡献(通常0.5%到2%)
ATR每股 = 工具的平均真实范围
示例:
账户权益:$100,000
波动性%: 1%
入场价格: $50.00
ATR: $2.00
美元波动预算:$100,000 × 0.01 = $1,000
股数: $1,000 / $2.00 = 500股
仓位价值: 500 × $50 = $25,000(权益的25%)
特征:
仓位规模基于每合约/单位固定利润金额("delta")增加,而不是权益百分比。此模型不是Tharp发明,但在书中讨论。
第N级合约数 = 第N-1级合约数 + 1
当累计利润超过以下时更改级别:
Delta ×(当前合约数 ×(当前合约数 + 1))/ 2
Delta = $5,000的示例:
第1级:1合约(开始)
第2级:2合约(在1合约上盈利$5,000后)
第3级:3合约(在2合约累计盈利$15,000后)
第4级:4合约(在3合约累计盈利$30,000后)
特征:
Tharp自己的贡献。CPR模型在回撤期间有条件地减少仓位规模,在权益增长期间增加,但比简单固定分数更激进。
CPR逻辑:
如果当前权益 > 峰值权益:
风险% = 基础风险% (正常模式)
如果当前权益 < 峰值权益:
回撤% =(峰值 - 当前)/ 峰值
风险% = 基础风险% ×(1 - 回撤%) (回撤期间减少风险)
示例:
基础风险%:2%
峰值权益:$100,000
当前权益:$85,000
回撤%:15%
调整后风险% = 2% ×(1 - 0.15)= 1.70%
美元风险:$85,000 × 0.017 = $1,445
特征:
| 模型 | 最适合 | 风险控制 | 复利 | 复杂性 |
|---|---|---|---|---|
| 固定分数 | 通用、大多数交易者 | 好 | 好 | 低 |
| 百分比波动 | 多工具投资组合 | 好(波动性标准化) | 好 | 中 |
| 固定比率 | 期货交易者、早期账户 | 中等 | 早期激进 | 中 |
| CPR | 资本保存优先 | 优秀 | 恢复较慢 | 中 |
所有Tharp推荐模型共享一个关键属性:它们是反马丁格尔。他们在赢时增加赌注,在输时减少赌注。这与马丁格尔策略(在亏损后加倍)相反,保证最终毁灭。
反马丁格尔(正确):赢 → 赌更多,输 → 赌更少
马丁格尔(致命):赢 → 赌相同,输 → 赌更多
反马丁格尔之所以有效:
- 回撤是自我限制的(更小赌注 = 更慢亏损)
- 增长是复利的(更大赌注 = 更快收益)
- 生存优先于恢复速度
大多数交易者关注预期值(每笔交易的质量)而忽视机会(交易数量)。但总系统表现是两者的乘积:
总表现 = 预期值 × 机会 × 仓位规模
具有+0.30R预期值和每年200笔交易的系统可能胜过具有+0.80R预期值和每年20笔交易的系统,假设类似的仓位规模:
系统A:0.30R × 200交易 = 60R每年
系统B:0.80R × 20交易 = 16R每年
系统A产生近4倍的总R预期值,尽管每笔交易预期值较低。
更高机会(更多交易)通常伴随着成本:
最佳机会水平取决于你的目标、时间可用性和你的市场的交易成本。
不以降低预期值为代价增加机会的合法方式:
Tharp emphatic about a distinction that most of the trading world ignores or conflates:
当行业说"资金管理"时,交易者经常考虑:
这些都不是仓位规模。仓位规模具体回答:鉴于我决定进行这笔交易,带着这个入场和这个止损,我应该买多少股/合约/单位?
在整本书中,Tharp consistently uses "position sizing" rather than "money management" to avoid ambiguity. When he says "position sizing is the most important part of trading," he means specifically the algorithm that determines trade size — not stop placement, not diversification, not leverage.
系统质量数是Tharp评估交易系统整体质量的专有指标。它调整预期值的一致性(标准差)和样本量。
SQN =(平均R倍数 / R倍数的标准差)× sqrt(N)
其中:
平均R倍数 = 预期值
标准差 = R倍数分布的标准差
N = 交易数量(公式中上限为100)
注意:Tharp在公式中将N上限为100,以防止高频系统仅因大量交易计数而产生人为膨胀的SQN值。
预期值 alone does not capture consistency. 两个系统可以有相同的预期值但非常不同的SQN值:
系统A:预期值 = +0.50R,标准差 = 1.0R,N = 100
SQN =(0.50 / 1.0)× sqrt(100)= 0.50 × 10 = 5.0
系统B:预期值 = +0.50R,标准差 = 3.0R,N = 100
SQN =(0.50 / 3.0)× sqrt(100)= 0.167 × 10 = 1.67
系统A和系统B有相同的预期值,但系统A要一致得多。系统A的SQN 5.0反映了一个可靠的、可交易的系统。系统B的SQN 1.67反映了具有相同预期回报但波动剧烈的系统——心理上更难交易,更容易受到回撤影响。
| SQN | 质量 | 可交易性 |
|---|---|---|
| < 1.6 | 差 | 任何仓位规模都难以盈利交易 |
| 1.6 到 1.9 | 低于平均 | 需要非常保守的仓位规模 |
| 2.0 到 2.4 | 平均 | 可用适度仓位规模交易 |
| 2.5 到 2.9 | 好 | 舒适交易;合理的仓位规模 |
| 3.0 到 5.0 | 优秀 | 高信心;可使用更激进的规模 |
| 5.0 到 6.9 | 卓越 | 罕见;允许激进的复利 |
| 7.0+ | 圣杯领域 | 实践中几乎从未见过 |
Tharp认为SQN应该指导你的仓位规模激进性:
更高的SQN = 更一致的系统 = 对仓位规模更有信心 = 更快复利。
Tharp识别交易者最频繁和最具破坏性的错误:
错误1:没有书面交易计划。 没有计划,每个决策都是临时起意。你无法评估未定义的东西。
错误2:使用不适合你个性的系统。 剥头皮系统对全职工作的人无用。长期趋势系统对需要每日行动的人是一种折磨。
错误3:将胜率与盈利性混淆。 在80%的时间内获胜但平均赢家为0.3R、平均输家为-2.0R的系统具有负预期值:(0.80 × 0.3)+(0.20 × -2.0)= 0.24 - 0.40 = -0.16R。
错误4:优化入场而忽视出场。 "完美"入场后跟糟糕出场将产生糟糕结果。中等入场后跟优秀出场将产生良好结果。
错误5:不理解仓位规模。 大多数交易者基于"我能买多少股?"而不是"我应该冒多少风险?"来调整仓位。这些是完全不同的问题。
错误6:不跟踪R倍数。 没有R倍数跟踪,你无法计算预期值、SQN或评估系统质量。你在盲目飞行。
错误7:过度优化(曲线拟合)。 具有47个参数完美拟合历史数据的系统将在真实交易中失败。稳健系统具有很少的参数,在许多市场和时期都有效。
错误8:未考虑成本。 佣金、滑点、价差和市场影响是真实的。成本前+0.10R预期值的系统可能在成本后有负预期值。
错误9:交易太大。 账户爆炸的最常见原因。即使正预期值系统,如果仓位规模太大,也会出现毁灭,因为不可避免的回撤会在优势能够表达之前消灭账户。
错误10:在正常回撤期间放弃系统。 每个系统都有回撤。如果你的最大历史回撤是25%,你应该预期未来25-30%的回撤。在20%回撤点放弃系统意味着你承担了损失但错过了恢复。
错误11:资本不足。 资本不足迫使每笔交易的过度风险(因为佣金等固定成本成为R的更大百分比)并阻止适当的多样化。
错误12:未能进行心理工作。 以上所有错误都有心理根源。不写计划交易者在逃避责任。过度调整仓位的交易者是贪婪的。放弃系统的交易者是急躁的。在你解决心理问题之前,相同的错误会在你尝试的每个系统中重复出现。
系统类型: 趋势跟随于日图
设置过滤器: 股票在200日MA之上,ADX > 20
入场信号: 突破55日高点
初始止损: 入场 - 3 × ATR(20)
跟踪止损: 最高收盘 - 3 × ATR(20)
盈利目标: 无(让赢家跑)
仓位规模: 每笔交易1%风险(固定分数)
账户权益: $100,000
股票:XYZ Corp
当前价格:$48.50
200日MA:$42.00(价格在上 → 设置条件满足)
ADX(14):28(高于20 → 趋势强度确认)
55日高点:$49.00
状态:设置活跃。等待入场触发。
第1天:XYZ收于$49.25 — 突破55日高点$49.00
入场触发
入场价格: $49.25
ATR(20): $1.50
初始止损: $49.25 -(3 × $1.50)= $44.75
R每股: $49.25 - $44.75 = $4.50
仓位规模(1%固定分数):
美元风险: $100,000 × 0.01 = $1,000
股数: $1,000 / $4.50 = 222股
仓位价值: 222 × $49.25 = $10,933.50(权益的10.9%)
第5天: 价格$50.80,ATR $1.55
跟踪止损:$50.80 -(3 × $1.55)= $46.15
活跃止损:MAX($44.75, $46.15)= $46.15(止损上移)
第12天: 价格$54.20,ATR $1.60
跟踪止损:$54.20 -(3 × $1.60)= $49.40
活跃止损:$49.40(现在高于入场 — 交易是无风险的)
第25天: 价格$61.00,ATR $1.70
跟踪止损:$61.00 -(3 × $1.70)= $55.90
活跃止损:$55.90
第33天: 价格$58.50,ATR $1.65
跟踪止损:$58.50 -(3 × $1.65)= $53.55
活跃止损:$55.90(跟踪止损永不向下移动)
第38天: 价格下跌至$55.80 — 在$55.90触及跟踪止损
出场触发
出场价格: $55.90(近似 — 可能滑至$55.80)
使用出场: $55.80(考虑滑点)
每股利润: $55.80 - $49.25 = $6.55
R每股: $4.50
R倍数: $6.55 / $4.50 = +1.46R
总利润: 222股 × $6.55 = $1,454.10
占权益百分比: 1.45%
交易 入场 出场 R倍数
1 $49.25 $55.80 +1.46R
2 $32.10 $30.20 -0.95R
3 $78.50 $75.00 -1.02R
4 $21.40 $19.80 -1.10R
5 $55.00 $54.10 -0.92R
6 $44.20 $41.50 -1.05R
7 $67.80 $83.40 +3.12R
8 $38.00 $36.10 -0.98R
9 $92.50 $88.75 -1.01R
10 $15.60 $14.80 -0.97R
11 $43.00 $55.90 +4.50R
12 $71.20 $69.50 -0.88R
13 $28.40 $26.90 -1.06R
14 $56.80 $74.20 +5.82R
15 $33.50 $32.00 -0.97R
16 $89.00 $86.20 -1.03R
17 $47.60 $62.40 +7.24R
18 $62.00 $60.10 -0.95R
19 $25.80 $24.50 -1.00R
20 $41.30 $39.80 -0.98R
赢家: 5笔中20笔(25%胜率)
输家: 15笔中20笔(75%亏损率)
R倍数总和:+1.46 +(-0.95)+(-1.02)+(-1.10)+(-0.92)+
(-1.05)+ 3.12 +(-0.98)+(-1.01)+(-0.97)+ 4.50 +(-0.88)+
(-1.06)+ 5.82 +(-0.97)+(-1.03)+ 7.24 +(-0.95)+(-1.00)+
(-0.98)= +8.27R
预期值: 8.27 / 20 = +0.41R每笔交易
尽管只赢了25%的交易,此系统是稳固盈利的。
5个赢家(平均+4.43R)压倒了15个输家(平均-0.99R)。
平均R倍数: +0.41R
R的标准差: 2.39R(因少数大赢家而大)
N: 20
SQN =(0.41 / 2.39)× sqrt(20)
= 0.172 × 4.47
= 0.77
SQN = 0.77(差——但这在只有20笔交易时是预期的。
如果分布保持,100笔交易:
SQN = 0.172 × 10 = 1.72,低于平均但可交易。)
这说明了为什么Tharp强调需要足够的样本量。二十笔交易不足以评估趋势跟随系统。
class ExpectancyCalculator:
"""
从交易列表计算预期值和相关统计。
每笔交易必须包含:entry_price, exit_price, stop_price, direction.
"""
def __init__(self):
self.trades = []
def add_trade(self, entry_price, exit_price, stop_price, direction="long"):
"""
记录完成的交易。
direction: "long" or "short"
"""
if direction == "long":
r_per_unit = entry_price - stop_price
profit_per_unit = exit_price - entry_price
else: # short
r_per_unit = stop_price - entry_price
profit_per_unit = entry_price - exit_price
if r_per_unit <= 0:
raise ValueError("R必须为正。检查止损放置。")
r_multiple = profit_per_unit / r_per_unit
self.trades.append({
"entry": entry_price,
"exit": exit_price,
"stop": stop_price,
"direction": direction,
"r_per_unit": r_per_unit,
"profit_per_unit": profit_per_unit,
"r_multiple": r_multiple
})
def expectancy(self):
"""所有交易的平均R倍数。"""
if not self.trades:
return 0.0
r_multiples = [t["r_multiple"] for t in self.trades]
return sum(r_multiples) / len(r_multiples)
def win_rate(self):
"""正R倍数交易的百分比。"""
if not self.trades:
return 0.0
winners = sum(1 for t in self.trades if t["r_multiple"] > 0)
return winners / len(self.trades)
def average_winner(self):
"""赢家交易的平均R倍数。"""
winners = [t["r_multiple"] for t in self.trades if t["r_multiple"] > 0]
return sum(winners) / len(winners) if winners else 0.0
def average_loser(self):
"""输家交易的平均R倍数。"""
losers = [t["r_multiple"] for t in self.trades if t["r_multiple"] <= 0]
return sum(losers) / len(losers) if losers else 0.0
def expectancy_decomposed(self):
"""将预期值显示为win% × avg_win + loss% × avg_loss。"""
w = self.win_rate()
aw = self.average_winner()
al = self.average_loser()
return {
"win_rate": w,
"loss_rate": 1 - w,
"avg_winner_r": aw,
"avg_loser_r": al,
"expectancy": (w * aw) + ((1 - w) * al)
}
def r_multiple_distribution(self):
"""返回所有R倍数的排序列表。"""
return sorted([t["r_multiple"] for t in self.trades])
def report(self):
"""打印完整的预期值报告。"""
n = len(self.trades)
if n == 0:
return "No trades recorded."
e = self.expectancy()
wr = self.win_rate()
aw = self.average_winner()
al = self.average_loser()
r_multiples = [t["r_multiple"] for t in self.trades]
return {
"total_trades": n,
"winners": sum(1 for r in r_multiples if r > 0),
"losers": sum(1 for r in r_multiples if r <= 0),
"win_rate": round(wr * 100, 1),
"avg_winner_r": round(aw, 2),
"avg_loser_r": round(al, 2),
"expectancy_r": round(e, 2),
"total_r": round(sum(r_multiples), 2),
"largest_winner": round(max(r_multiples), 2),
"largest_loser": round(min(r_multiples), 2),
"std_dev_r": round(std_dev(r_multiples), 2)
}
def std_dev(values):
"""总体标准差。"""
n = len(values)
if n < 2:
return 0.0
mean = sum(values) / n
variance = sum((x - mean) ** 2 for x in values) / (n - 1)
return variance ** 0.5
class PositionSizer:
"""
实现Tharp的多种仓位规模模型。
"""
def __init__(self, account_equity):
self.equity = account_equity
self.peak_equity = account_equity
def update_equity(self, new_equity):
"""每笔交易后调用以更新权益和峰值。"""
self.equity = new_equity
if new_equity > self.peak_equity:
self.peak_equity = new_equity
# --- 模型1:固定分数(百分比风险)---
def fixed_fractional(self, risk_percent, entry_price, stop_price):
"""
每笔交易风险固定百分比权益。
参数:
risk_percent: 例如0.01表示1%
entry_price: 计划入场价格
stop_price: 计划止损价格
返回:
包含股数、美元风险、仓位价值、R每股的字典
"""
r_per_share = abs(entry_price - stop_price)
if r_per_share == 0:
raise ValueError("入场和止损不能是同一价格。")
dollar_risk = self.equity * risk_percent
shares = int(dollar_risk / r_per_share) # 向下取整
return {
"model": "fixed_fractional",
"shares": shares,
"dollar_risk": round(shares * r_per_share, 2),
"position_value": round(shares * entry_price, 2),
"pct_of_equity": round((shares * entry_price / self.equity) * 100, 1),
"r_per_share": round(r_per_share, 2),
"risk_pct_actual": round((shares * r_per_share / self.equity) * 100, 2)
}
# --- 模型2:百分比波动 ---
def percent_volatility(self, volatility_percent, entry_price, atr):
"""
调整仓位使得每个仓位对投资组合波动性的贡献大致相等。
参数:
volatility_percent: 目标每日波动贡献(例如0.01)
entry_price: 计划入场价格
atr: 工具的平均真实范围
"""
if atr <= 0:
raise ValueError("ATR必须为正。")
dollar_volatility_budget = self.equity * volatility_percent
shares = int(dollar_volatility_budget / atr)
return {
"model": "percent_volatility",
"shares": shares,
"position_value": round(shares * entry_price, 2),
"pct_of_equity": round((shares * entry_price / self.equity) * 100, 1),
"daily_volatility_dollars": round(shares * atr, 2),
"daily_volatility_pct": round((shares * atr / self.equity) * 100, 2)
}
# --- 模型3:CPR(条件仓位减少)---
def cpr(self, base_risk_percent, entry_price, stop_price):
"""
在回撤期间按比例减少风险百分比。
参数:
base_risk_percent: 权益高位时的正常风险%
entry_price: 计划入场价格
stop_price: 计划止损价格
"""
drawdown_pct = 0.0
if self.equity < self.peak_equity:
drawdown_pct = (self.peak_equity - self.equity) / self.peak_equity
adjusted_risk_pct = base_risk_percent * (1 - drawdown_pct)
r_per_share = abs(entry_price - stop_price)
if r_per_share == 0:
raise ValueError("入场和止损不能是同一价格。")
dollar_risk = self.equity * adjusted_risk_pct
shares = int(dollar_risk / r_per_share)
return {
"model": "cpr",
"shares": shares,
"base_risk_pct": round(base_risk_percent * 100, 2),
"adjusted_risk_pct": round(adjusted_risk_pct * 100, 2),
"drawdown_pct": round(drawdown_pct * 100, 2),
"dollar_risk": round(shares * r_per_share, 2),
"position_value": round(shares * entry_price, 2),
"r_per_share": round(r_per_share, 2)
}
# --- 比较 ---
def compare_all(self, risk_pct, vol_pct, entry_price, stop_price, atr):
"""运行所有三个模型并并排比较。"""
return {
"fixed_fractional": self.fixed_fractional(risk_pct, entry_price, stop_price),
"percent_volatility": self.percent_volatility(vol_pct, entry_price, atr),
"cpr": self.cpr(risk_pct, entry_price, stop_price)
}
class SQNTracker:
"""
在滚动交易窗口上跟踪系统质量数。
"""
SQN_RATINGS = [
(1.6, "差 — 难以盈利交易"),
(2.0, "低于平均 — 需要保守规模"),
(2.5, "平均 — 可用中等规模交易"),
(3.0, "好 — 舒适交易"),
(5.0, "优秀 — 允许激进规模"),
(7.0, "卓越 — 罕见质量"),
(float('inf'), "圣杯 — 实践中几乎从未见过")
]
def __init__(self, max_n=100):
"""
参数:
max_n: SQN公式中N的上限(Tharp使用100)。
"""
self.r_multiples = []
self.max_n = max_n
def add_r_multiple(self, r_multiple):
"""添加完成的交易的R倍数。"""
self.r_multiples.append(r_multiple)
def add_trades_from_calculator(self, calculator):
"""从ExpectancyCalculator实例导入交易。"""
for trade in calculator.trades:
self.r_multiples.append(trade["r_multiple"])
def sqn(self):
"""
计算系统质量数。
"""
n = len(self.r_multiples)
if n < 2:
return 0.0
# 将n上限为max_n
n_capped = min(n, self.max_n)
mean_r = sum(self.r_multiples) / n
std_dev_r = self.std_dev(self.r_multiples)
if std_dev_r == 0:
return 0.0
sqn = (mean_r / std_dev_r) * (n_capped ** 0.5)
return sqn
def std_dev(self, values):
"""样本标准差。"""
n = len(values)
if n < 2:
return 0.0
mean = sum(values) / n
variance = sum((x - mean) ** 2 for x in values) / (n - 1)
return variance ** 0.5
def rating(self):
"""返回SQN的分类评级。"""
sqn_val = self.sqn()
for threshold, description in self.SQN_RATINGS:
if sqn_val < threshold:
return {
"sqn": round(sqn_val, 2),
"rating": description
}
return {
"sqn": round(sqn_val, 2),
"rating": "圣杯"
}
"交易圣杯不是找到完美系统的过程。它是一个具有正预期值的系统、以适当的仓位规模交易、由心理上准备好的交易者执行。就是这样。"
"你需要知道的不是你将做什么,而是如果事情没有按预期发展你将做什么。"
"交易的三个最重要的事情是:1. 心理 2. 仓位规模 3. 入场。入场是最不重要的。"
"如果你的系统有负预期值,你将赔钱。没有什么能改变这一点。"
"在交易中,你知道某事是错误的和你做某事是不同的。你必须有一个系统来确保你做你知道的事情。"
"交易者失败的两个主要原因:他们交易错误的系统,或者他们交易正确的系统但使用了错误的仓位规模。"
"你的系统质量数(SQN)告诉你系统的一致性。你希望SQN高于2.0才能舒适交易。"
"固定分数仓位规模在回撤期间自动减少风险敞口,在盈利期间自动增加。这是正确的。"
"每笔交易都是独特的,但交易结果是由你执行的大量交易决定的。不要被个体交易的结果所困扰。"
"最危险的想法是'这次不同了。'"
"交易的目的是通过一致地执行一个正预期值系统来积累财富。不是通过预测下一步市场将做什么。"
"你需要担心的不是亏损的交易,而是当交易对你不利时你做什么。"
"大多数交易者花太多时间寻找'完美'入场,几乎没有时间开发适当的出场和仓位规模策略。"
"成功的交易不是找到一个会上涨的股票。这是关于开发一个系统并一致地执行它。"
"如果你的系统期望每R赚0.40,但你每笔交易只赚0.20,问题不在于你的系统。你的仓位规模可能太大。"
"交易是概率游戏。不是关于正确或错误。是关于当你的优势存在时执行。"
"你不能控制市场将做什么。但你可以控制你将做什么。专注于你能控制的。"