交易之路 — 完整实施规范

基于陈凯 (Chen Kai),交易之路 (Path to Trading) (2019)


目录

  1. 概述
  2. 交易者发展的五个阶段
  3. [交易系统设计 — 完整框架](#3-交易系统设计 — 完整框架)
  4. 中国市场选择
  5. A股技术分析工具箱
  6. 趋势跟踪方法论
  7. 均值回归策略
  8. 多时间框架分析
  9. 仓位调整和资金管理
  10. 风险控制框架
  11. 交易心理和情绪管理
  12. 回测和系统验证
  13. 交易日志
  14. 行为纪律
  15. 常见错误
  16. 完整交易生命周期示例
  17. 实施伪代码
  18. 关键原则

1. 概述

1.1 核心论点

陈凯的交易之路绘制了从新手散户到专业、系统化交易者的完整旅程。与许多专注于单一技术或秘密指标的中国交易书籍不同,陈凯认为交易成功源于五个支柱的整合:市场理解、完整的交易系统、有纪律的风险管理、心理成熟和持续的自我完善。缺少任何一个支柱最终都会摧毁交易者的账户。

本书扎根于中国市场的现实 — A股的T+1结算规则、10%涨跌停限制、散户主导地位、中国期货市场的独特行为,以及决定策略如何从西方教科书适应的监管环境。

1.2 本书适合人群

陈凯为三类读者撰写:

1.3 核心哲学

交易不是关于预测;而是关于概率和过程。市场总是做不可预测的事情。交易者的工作不是准确判断方向,而是构建一个系统,在这个系统中,做对了能获得比做错了损失更多的东西,然后绝对一致地执行该系统。

陈凯反复强调:交易是一场修行 — "Trading is a practice of self-cultivation." 技术技能可能只占长期成功的30%。其余70%是心理纪律、情绪管理,以及在每种本能尖叫着偏离规则时遵循规则的能力。


2. 交易者发展的五个阶段

2.1 第一阶段 — 无意识的无能 (Unconscious Incompetence)

初学者不知道他所不知道的。特征包括:

2.2 第二阶段 — 有意识的无能 (Conscious Incompetence)

在重大亏损后(通常为资本的30-50%),交易者意识到有些根本错误。特征包括:

2.3 第三阶段 — 顿悟时刻 (The Aha Moment)

交易者有了突破性认识 — 通常不是关于技术,而是关于游戏的本质。常见认识包括:

2.4 第四阶段 — 有意识的有能 (Conscious Competence)

交易者有一个可行的系统并理解其工作原理。这个阶段的挑战:

2.5 第五阶段 — 无意识的有能 (Unconscious Competence)

执行变得自动。交易者不再争论是否遵循系统;这样做就像呼吸一样自然。特征包括:


3. 交易系统设计 — 完整框架

3.1 六个组成部分

陈凯将完整交易系统定义为能够绝对具体地回答六个问题的系统。缺少任何一个的系统都是不完整的,在压力下会失败。

组成部分 它回答的问题 示例
市场选择 (品种选择) 我交易什么? 沪深300成分股中日均成交量 > 5000万人民币的股票
方向偏见 (方向判断) 我是做多、做空还是两者? 仅在周线MA20 > MA60时做多(上升趋势)
入场信号 (入场信号) 我何时精确入场? 价格以成交量 > 1.5倍均值收于20日高点之上
出场信号 (出场信号) 我何时精确出场 — 盈利和亏损? 止损:入场价下方2x ATR。目标:3x ATR跟踪止损
仓位调整 (仓位管理) 这笔交易我承担多少风险? 每笔交易风险账户权益的1%
交易管理 (交易管理) 入场和出场之间我如何处理交易? 在1R盈利时加仓;永不逆势加仓

3.2 重要性层次

陈凯按对长期盈利贡献的顺序排列组成部分:

  1. 仓位调整(结果的40%)— 即使是平庸的系统在出色的资金管理下也能盈利;即使是好系统在糟糕的仓位调整下也能摧毁账户。
  2. 出场策略(结果的25%)— 你如何出场决定了你是捕捉趋势还是回吐所有收益。
  3. 入场信号(结果的15%)— 重要,但不如大多数初学者认为的那么重要。
  4. 方向偏见(结果的10%)— 顺着主要趋势交易提供固有优势。
  5. 市场选择(结果的5%)— 某些品种在结构上更适合某些策略。
  6. 交易管理(结果的5%)— 向盈利者加仓、分批出场的调整规则。

3.3 系统一致性

每个组成部分必须在哲学上一致。将趋势跟踪入场与均值回归出场配对会产生混乱和不一致。陈凯提供了一致性测试:

混合两种哲学的元素是交易系统失败的最常见原因。


4. 中国市场选择

4.1 A股 (A股)

结构特征:

对系统设计的影响:

4.2 中国期货 (期货)

结构特征:

对系统设计的影响:

4.3 期权 (期权)

结构特征:

对系统设计的影响:

4.4 陈凯的建议

初学者:从A股开始。T+1约束实际上有助于防止冲动日内交易。涨跌停限制单日最大损失。在股票上实现持续盈利后至少一年再转向期货。


5. A股技术分析工具箱

5.1 移动平均线 (均线系统)

陈凯认为移动平均线是最重要的技术工具,因为它们是客观的、明确的,直接代表重要的事情:市场参与者在给定时期内支付的平均价格。

A股关键移动平均线:

均线周期 功能 常用中文术语
5日 非常短期趋势,激进时机 攻击线 (Attack Line)
10日 短期趋势 操盘线 (Trading Line)
20日 中期趋势 辅助线 (Support Line)
60日 中期趋势,机构参考 生命线 (Lifeline)
120日 半年趋势,牛熊分界 决策线 (Decision Line)
250日 年度趋势,长期方向 趋势线 (Trend Line)

基于均线的信号:

A股特定调整: 60日均线是最受关注的机构参考线。交易在60日均线上方的股票处于"牛市 territory";下方的处于"熊市 territory"。这条线在上升趋势中经常充当支撑,在下降趋势中充当阻力,因为机构算法参考它。

5.2 MACD (指数平滑异同移动平均线)

标准设置:MACD(12, 26, 9)。

A股背景下的关键信号:

5.3 RSI (相对强弱指标)

标准设置:日线RSI(14),短期RSI(6)。

陈凯的A股 RSI框架:

5.4 布林带 (布林带)

标准设置:BB(20, 2)。

在A股中的应用:

5.5 组合指标 — 越少越好

陈凯的关键规则:永远不要同时使用超过三个指标。 指标的目的是过滤噪音,不是添加噪音。他推荐的组合:


6. 趋势跟踪方法论

6.1 核心原则

在陈凯的框架中,趋势跟踪基于一个简单观察:市场大约30%的时间处于强劲趋势,70%处于震荡、无趋势区间。 趋势跟随者在70%期间接受亏损,以换取30%期间捕获大波动。

6.2 趋势识别

客观地使用两个标准定义趋势:

  1. 价格结构:更高的高点和更高的低点(上升趋势)或更低的高点和更低的低点(下降趋势)。
  2. 移动平均线排列:MA5 > MA20 > MA60(看涨);MA5 < MA20 < MA60(看跌)。

两个条件必须同时满足。显示更高高点但移动平均线纠缠的市场尚未处于确认的趋势中。

6.3 趋势跟踪入场规则

主要入场 — 突破 (突破入场):

次要入场 — 回撤 (回调入场):

6.4 趋势跟踪出场规则

止损 (止损):

跟踪止损 (移动止损):

目标 (止盈):

6.5 A股特定注意事项


7. 均值回归策略

7.1 核心原则

均值回归是趋势跟踪的补充策略。它利用了价格在显著偏离其均值后往往迅速恢复到该均值的观察。

7.2 何时使用均值回归

陈凯明确警告:不要在强劲趋势中尝试均值回归。 反向交易趋势是快速摧毁资本的最快方式。

7.3 均值回归入场规则

买入设置 (做多条件):

  1. 价格触及或跌至下布林带 (20, 2) 下方。
  2. RSI(14)跌破30(或RSI(6)跌破20)。
  3. 形成看涨K线反转形态:锤子线、看涨吞没、或晨星。
  4. 反转蜡烛线的成交量至少为前一根蜡烛线的1.2倍(显示买家进场)。
  5. 股票高于其250日均线(只在结构性上升趋势中买入超卖 — 避免在真实下降趋势中"接飞刀")。

卖出设置 (做空条件,用于期货或退出多头仓位):

  1. 价格触及或穿越上布林带 (20, 2) 上方。
  2. RSI(14)升至70以上(或RSI(6)升至80以上)。
  3. 形成看跌反转K线形态:射击之星、看跌吞没、或黄昏星。
  4. 反转蜡烛线成交量扩张。

7.4 均值回归出场规则


8. 多时间框架分析

8.1 三重过滤 (三重过滤)

改编自亚历山大·埃尔德的概念,陈凯将三时间框架方法应用于A股交易:

屏幕 时间框架 目的 工具
屏幕1(战略) 周线 确定主要趋势方向 MA60,MACD零轴
屏幕2(战术) 日线 识别设置并确认条件 布林带,RSI,成交量
屏幕3(执行) 60分钟 时机精确入场和出场 价格行为,MA5/MA10交叉

8.2 参与规则

8.3 时间框架对齐

当所有三个时间框架一致时,最有利可图的交易发生。陈凯称之为共振

当时间框架冲突时(例如,周线看涨但日线看跌),正确行动是等待。在模糊条件下强制交易违反了在条件清晰时才交易的原则。


9. 仓位调整和资金管理

9.1 生存基础

陈凯称仓位调整为"交易中最重要和最被忽视的方面。" 胜率60%、奖励风险比2:1的系统仍然可能摧毁账户,如果每笔交易风险20%资本的话。相反,胜率40%的系统如果每笔交易只风险1%可以稳定积累财富。

9.2 固定比例法 (固定比例法)

核心规则:每笔交易风险当前账户权益的固定百分比。

仓位 = (账户权益 × 风险百分比) / (入场价 - 止损价)

推荐风险百分比:

交易者级别 每笔交易风险 最大同时风险
初学者 0.5% 3%总计
中级 1.0% 6%总计
高级 2.0% 10%总计

示例:账户权益 = 500,000人民币。每笔交易风险 = 1% = 5,000。入场合 = 25.00。止损价 = 23.50。每份风险 = 1.50。仓位 = 5,000 / 1.50 = 3,333股。取整至A股最接近手数(100股)= 3,300股。所需资本 = 3,300 × 25.00 = 82,500人民币。

9.3 凯利公式 (凯利公式) — 理论与实践

凯利最优赌注调整公式:

f = (bp - q) / b

其中f = 资本比例,b = 盈亏比,p = 盈利概率,q = 亏损概率。

陈凯解释全凯利对实际交易来说太激进。他推荐四分之一凯利或半凯利以考虑:

9.4 分批建仓和分批出场

向盈利者加仓 (加仓):

分批出场 (分批出场):

9.5 相关性调整仓位

永远不要同时持有超过3个高度相关的仓位。中国银行股(例如工商银行、建设银行、中国银行、农业银行)几乎同步波动。以每笔1%风险持有4只银行股不是4%风险 — 实际上是对银行板块的单一4%赌注。


10. 风险控制框架

10.1 三个风险级别

级别 范围 最大损失 触发时的行动
交易风险 单笔持仓 权益的1-2% 自动执行止损
日风险 一天内所有交易 权益的3% 当天停止交易
回撤风险 滚动峰值到谷值 峰值权益的15% 仓位减半50%;在20%时停止交易2周

10.2 熔断协议

当账户回撤达到10%时,实施以下措施:

  1. 将仓位调整减少50%。 如果通常每笔交易风险1%,减少到0.5%。
  2. 将最大同时持仓数减少50%。 如果通常持有5个仓位,减少到2-3个。
  3. 要求所有交易通过额外过滤器。 在入场任何新交易前,周线趋势必须确认看涨(不仅是日线)。

当账户回撤达到15%时:

  1. 平仓所有持仓。
  2. 至少停止5个交易日。
  3. 回顾交易日志以确定回撤是系统性(市场环境已改变)还是行为性(交易者偏离系统)。

当账户回撤达到20%时:

  1. 至少停止2周。
  2. 模拟交易系统以确认它仍然有效后再返回。
  3. 返回时以正常仓位的25%开始,逐步增加。

10.3 A股缺口风险管理

由于A股受T+1约束,交易者无法在同日入场的当天退出持仓。这创造了独特的隔夜缺口风险。缓解策略:


11. 交易心理和情绪管理

11.1 交易的情绪周期

陈凯描述每个交易者都会经历的反复情绪周期:

兴奋(新车)→ 焦虑(回撤)→ 恐惧(止损触发)→
沮丧(连续亏损)→ 报复(下一笔超额交易)→
否认(移除止损)→ 投降(恐慌性卖出)→ 抑郁 →
决心(更多研究)→ 平静(新系统)→ 兴奋(新车)→ ...

打破这个周期需要意识、日志和覆盖情绪的规则。

11.2 四个情绪敌人

恐惧 (恐惧):

贪婪 (贪婪):

希望 (希望):

后悔 (后悔):

11.3 培养情绪分离

陈凯的实际建议:

  1. 交易小到你不关心。 如果亏损引起情绪干扰,仓位太大了。
  2. 在交易日志中追踪情绪。 记录入场时、交易期间和出场时的情绪状态。随着时间的推移,模式会出现。
  3. 预先承诺决策。 在市场开盘前写下你的计划。在交易时段,执行计划 — 不做新决策。
  4. 身体练习。 运动、冥想和充足睡眠通过减少情绪反应直接改善交易表现。
  5. 休息。 每连续20个交易日后休息2-3天。每次回撤超过10%后至少休息5天。

12. 回测和系统验证

12.1 为何回测?

回测有一个目的:确定系统是否有真正的统计优势还是过去利润归因于运气。未在统计显著样本上回测的系统是赌博,不是策略。

12.2 回测要求

12.3 评估的关键指标

指标 可接受范围 理想范围
胜率 > 35%(趋势)/ > 55%(回归) > 45%(趋势)/ > 65%(回归)
利润因子 > 1.5 > 2.0
平均盈利/平均亏损 > 2.0(趋势)/ > 0.8(回归) > 3.0(趋势)/ > 1.2(回归)
最大回撤 < 25% < 15%
年化夏普比率 > 0.8 > 1.5
连续亏损次数 < 10 < 7
恢复因子(净利润 / 最大DD) > 3.0 > 5.0

12.4 避免过度拟合 (过度拟合)

过度拟合是回测中最大的危险。陈凯的规则:

  1. 参数稳健性测试:系统在一定范围的参数值下应该盈利,而不仅仅是一个"优化"设置。如果MA(20)有效但MA(18)和MA(22)失败,系统就过度拟合了。
  2. 样本外测试:将数据分成两半。在前半优化,在后半测试。如果性能急剧下降,系统就过度拟合了。
  3. walk-forward分析:在滚动窗口上持续重新优化并在下一时期测试。这更准确地模拟实时交易。
  4. 更少的参数:每个额外参数都是过度拟合的机会。具有2-3个参数的系统几乎总是比具有8-10个参数的系统更稳健。
  5. 先逻辑后数据:系统应该基于合理的市场原理(趋势持续、均值回归等),而不是数据挖掘的异常。

13. 交易日志

13.1 为何日志?

交易日志是交易者的镜子。没有它,自我评估基于记忆,而记忆是有选择性和有偏的。交易者记得最好和最差的交易,但忘记了决定长期结果的普通多数。

13.2 记录内容

每笔交易数据:

字段 示例
日期/时间 2019-03-15 14:45
品种 600519(贵州茅台)
方向 做多
入场价 780.00
止损 748.00
目标 20日均线跟踪止损
仓位 200股
资本风险 6,400人民币(权益的0.8%)
理由 周线上升趋势,日线回撤至MA20,RSI从45反弹
入场时情绪状态 平静,对设置有信心
出场价 825.00
出场日期 2019-04-02
盈亏 +9,000人民币(+1.12R)
教训 持有初始回撤;系统按设计工作

每周回顾: 总结盈亏统计、最大盈利、最大亏损、任何规则违规、观察到的情绪模式。

每月回顾: 计算运行夏普比率、回撤、利润因子。将实际表现与回测期望比较。识别任何环境变化(市场状态变化)是否影响表现。

13.3 如何使用日志


14. 行为纪律

14.1 10条纪律规则

  1. 永远不要在预先确定止损的情况下入场交易。 无例外。
  2. 永远不要将止损远离入场移动。 你可以收紧它,永远不要放宽它。
  3. 永远不要向亏损仓位加仓。 逆势加仓是账户毁灭的最快路径。
  4. 永远不要将单笔交易风险超过账户权益的2%。
  5. 永远不要同时持有超过5个不相关持仓(对于100万以下账户)。
  6. 始终执行系统的信号。 因为恐惧或discretion跳过信号会破坏统计优势。
  7. 永远不为恢复亏损而交易。 报复交易加剧回撤。
  8. 每周回顾交易日志。 回顾一致性产生执行一致性。
  9. 连续三次止损后休息。 不要在第二天交易。回顾日志以确定亏损是正常方差还是市场状态变化的迹象。
  10. 接受亏损交易是业务成本。 45%胜率意味着每100笔交易有55笔亏损。每笔亏损是对统计优势的投资,不是失败。

14.2 盘前程序

陈凯规定特定的盘前程序:

  1. 回顾隔夜新闻和全球市场(15分钟):美国市场、香港预开盘、大宗商品价格、政策公告。
  2. 检查现有持仓(10分钟):是否有止损可能在开盘时被触发?是否有持仓接近目标?
  3. 扫描新设置(20分钟):运行满足入场条件的股票屏幕。准备不超过5个候选标的的观察清单。
  4. 写计划(10分钟):对于每个候选标的,写:入场价、止损、仓位、目标。对于现有持仓,写:今天的调整水平或出场条件。
  5. 等待开盘(5分钟):开盘后前15分钟不行动(9:30-9:45)。开盘竞拍产生人为波动。

15. 常见错误

15.1 十三个致命错误

# 错误 为何致命
1 无止损 单个灾难性亏损可能抹去数月收益
2 逆势加仓 好钱追坏钱;随着论点恶化,仓位增加
3 超额仓位 即使正确的交易如果太大也会造成毁灭性回撤
4 无计划交易 没有预定框架时,每个决策都是情绪化的
5 系统跳转 在正常回撤期间放弃有效系统;从不给优势展现的机会
6 指标过载 更多指标产生更多矛盾,导致瘫痪或 cherry-picking
7 忽略趋势 在下降趋势中买"便宜"股票;在上升趋势中做空"昂贵"股票
8 追涨 (追涨停) 在10%涨跌停时买入股票期望继续;高风险,流动性差的出场
9 满仓操作 (满仓操作) 把100%资本放在一笔交易或一个板块;没有安全边际
10 根据消息交易 他人的分析不是你的优势;你不会知道他们何时改变主意
11 忽略交易成本 A股频繁交易(印花税 + 佣金)迅速侵蚀回报
12 忽视宏观环境 交易个股时不关注市场整体状况(例如央行收紧)
13 拒绝休息 倦怠降低决策质量;休息是风险管理工具

16. 完整交易生命周期示例

16.1 设置:A股市场做多交易

日期:2019年3月13日,星期三

品种:000858(五粮液)

账户权益:800,000人民币。每笔交易风险:1% = 8,000人民币。

16.2 屏幕1 — 周线分析

16.3 屏幕2 — 日线分析

16.4 屏幕3 — 60分钟执行

16.5 入场计算

16.6 交易管理

16.7 结果汇总

指标
总利润 27,480人民币
资本回报率 27,480 / 8,000 = 3.44R
持仓期 18个交易日
最大不利偏移 -1,080人民币(第1天日内低点72.90)
最大有利偏移 +40,680人民币(峰值84.50)
捕获比率 27,480 / 40,680 = 67.5%的波动

17. 实施伪代码

17.1 交易系统框架

class TradingSystem:
    config:
        risk_per_trade = 0.01          # 权益的1%
        max_concurrent_positions = 5
        max_daily_loss = 0.03          # 权益的3%
        max_drawdown_threshold = 0.15  # 从峰值下跌15%
        atr_period = 14
        ma_fast = 20
        ma_slow = 60
        rsi_period = 14
        bb_period = 20
        bb_std = 2.0

    state:
        account_equity = initial_capital
        peak_equity = initial_capital
        open_positions = []
        daily_pnl = 0.0
        is_halted = false

    function on_daily_close(market_data):
        if is_halted:
            check_halt_conditions()
            return

        update_equity()
        check_circuit_breakers()

        if daily_pnl <= -max_daily_loss * account_equity:
            log("日损失限额达到。今天不进行新交易。")
            return

        # 屏幕1:周线趋势过滤器
        weekly_trend = assess_weekly_trend(market_data)

        # 管理现有持仓
        for position in open_positions:
            manage_position(position, market_data)

        # 如果有容量则扫描新入场
        if len(open_positions) < max_concurrent_positions:
            candidates = scan_for_setups(market_data, weekly_trend)
            for candidate in candidates:
                if passes_correlation_filter(candidate, open_positions):
                    execute_entry(candidate)

    function assess_weekly_trend(data):
        weekly_ma20 = moving_average(data.weekly_close, 20)
        weekly_ma60 = moving_average(data.weekly_close, 60)
        weekly_macd = macd(data.weekly_close, 12, 26, 9)

        if weekly_ma20 > weekly_ma60 and weekly_macd.histogram > 0:
            return BULLISH
        elif weekly_ma20 < weekly_ma60 and weekly_macd.histogram < 0:
            return BEARISH
        else:
            return NEUTRAL

    function scan_for_setups(data, weekly_trend):
        setups = []
        for stock in universe:
            if weekly_trend == BULLISH:
                if is_trend_pullback_buy(stock, data):
                    setups.append(create_trade_plan(stock, LONG, "PULLBACK"))
                elif is_breakout_buy(stock, data):
                    setups.append(create_trade_plan(stock, LONG, "BREAKOUT"))
            elif weekly_trend == BEARISH:
                # A股:离场;期货:寻找做空
                pass
            else:
                if is_mean_reversion_buy(stock, data):
                    setups.append(create_trade_plan(stock, LONG, "REVERSION"))
        return setups

    function is_trend_pullback_buy(stock, data):
        close = data.daily_close[stock]
        ma20 = moving_average(close, 20)
        ma60 = moving_average(close, 60)
        rsi = compute_rsi(close, rsi_period)
        volume = data.daily_volume[stock]
        avg_volume = moving_average(volume, 20)

        conditions:
            close[-1] > ma60[-1]                    # 高于60日均线
            ma20[-1] > ma60[-1]                      # 均线排列看涨
            close[-1] <= ma20[-1] * 1.02             # 价格接近20日均线
            close[-2] > ma20[-2] or close[-3] > ma20[-3]  # 最近回撤
            rsi[-1] > 40 and rsi[-1] < 60            # RSI在中性区域
            volume[-1] < avg_volume[-1]              # 回撤时成交量下降

        return all(conditions)

    function is_breakout_buy(stock, data):
        close = data.daily_close[stock]
        high_20 = max(close[-21:-1])                 # 20日最高收盘价
        volume = data.daily_volume[stock]
        avg_volume = moving_average(volume, 20)
        ma60 = moving_average(close, 60)

        conditions:
            close[-1] > high_20                      # 收盘突破
            close[-1] > ma60[-1]                     # 高于60日均线
            volume[-1] > avg_volume[-1] * 1.5        # 成交量确认

        return all(conditions)

    function is_mean_reversion_buy(stock, data):
        close = data.daily_close[stock]
        bb = bollinger_bands(close, bb_period, bb_std)
        rsi = compute_rsi(close, rsi_period)
        ma250 = moving_average(close, 250)

        conditions:
            close[-1] <= bb.lower[-1]                # 在或低于下轨
            rsi[-1] < 30                             # 超卖
            close[-1] > ma250[-1]                    # 高于250日均线(结构性上升趋势)
            is_bullish_reversal_candle(data, stock)  # 反转形态

        return all(conditions)

    function create_trade_plan(stock, direction, strategy):
        atr = compute_atr(stock, atr_period)
        entry_price = current_price(stock)

        if strategy == "PULLBACK" or strategy == "BREAKOUT":
            stop_loss = entry_price - 2.0 * atr
            stop_loss = max(stop_loss, entry_price * 0.92)  # 最大8%止损
        elif strategy == "REVERSION":
            stop_loss = entry_price - 1.5 * atr
            target = moving_average(stock.close, 20)[-1]    # 均值目标

        risk_per_share = entry_price - stop_loss
        shares = floor((account_equity * risk_per_trade) / risk_per_share)
        shares = round_to_lot(shares, 100)                  # A股手数

        return TradePlan(stock, direction, strategy,
                         entry_price, stop_loss, shares, atr)

    function manage_position(position, data):
        current = data.daily_close[position.stock][-1]

        # 检查止损
        if current <= position.stop_loss:
            execute_exit(position, current, "STOP_LOSS")
            return

        # 更新趋势交易的跟踪止损
        if position.strategy in ["PULLBACK", "BREAKOUT"]:
            highest_since_entry = max(closes since position.entry_date)
            new_trail = highest_since_entry - 2.0 * position.atr

            if new_trail > position.stop_loss:
                position.stop_loss = new_trail
                log(f"跟踪止损更新至 {new_trail}")

            # 在2R时分批出场
            profit_r = (current - position.entry_price) / position.initial_risk
            if profit_r >= 2.0 and not position.scaled_out_1:
                exit_shares = position.shares // 3
                execute_partial_exit(position, exit_shares, current, "SCALE_2R")
                position.scaled_out_1 = true

            # 在4R时分批出场
            if profit_r >= 4.0 and not position.scaled_out_2:
                exit_shares = position.shares // 3
                execute_partial_exit(position, exit_shares, current, "SCALE_4R")
                position.scaled_out_2 = true

        # 均值回归交易的时间止损
        if position.strategy == "REVERSION":
            days_held = trading_days_since(position.entry_date)
            if days_held >= 5:
                execute_exit(position, current, "TIME_STOP")
                return
            if current >= position.target:
                execute_exit(position, current, "TARGET_HIT")
                return

17.2 风险管理器

class RiskManager:
    state:
        peak_equity
        current_equity
        daily_loss
        consecutive_losses = 0
        size_multiplier = 1.0

    function check_circuit_breakers():
        drawdown = (peak_equity - current_equity) / peak_equity

        if drawdown >= 0.20:
            halt_trading(duration_days=10)
            size_multiplier = 0.25
            alert("严重:20%回撤。停止交易10天。")

        elif drawdown >= 0.15:
            halt_trading(duration_days=5)
            size_multiplier = 0.50
            alert("警告:15%回撤。停止交易5天。")

        elif drawdown >= 0.10:
            size_multiplier = 0.50
            alert("注意:10%回撤。仓位减半。")

        else:
            size_multiplier = 1.0

    function check_daily_limit():
        if daily_loss >= current_equity * 0.03:
            return HALT_TODAY
        return CONTINUE

    function check_consecutive_losses(trade_result):
        if trade_result.is_loss:
            consecutive_losses += 1
        else:
            consecutive_losses = 0

        if consecutive_losses >= 3:
            alert("3次连续亏损。强制休息1天。")
            return HALT_TOMORROW

    function adjusted_position_size(base_size):
        return floor(base_size * size_multiplier)

    function check_correlation(new_stock, existing_positions):
        for position in existing_positions:
            corr = correlation(new_stock.returns_60d, position.stock.returns_60d)
            if corr > 0.70:
                return REJECT  # 过于相关
        sector_count = count_by_sector(existing_positions, new_stock.sector)
        if sector_count >= 2:
            return REJECT  # 每板块最多2个
        return ACCEPT

    function update_peak():
        if current_equity > peak_equity:
            peak_equity = current_equity

17.3 交易日志系统

class TradeJournal:
    storage: database or spreadsheet

    function record_entry(trade):
        entry = {
            id: generate_id(),
            date: today(),
            time: now(),
            stock: trade.stock,
            stock_name: trade.stock_name,
            direction: trade.direction,
            strategy: trade.strategy,
            entry_price: trade.entry_price,
            stop_loss: trade.stop_loss,
            target: trade.target,
            shares: trade.shares,
            capital_risked: trade.risk_amount,
            risk_pct: trade.risk_amount / account_equity,
            rationale: trade.rationale,       # 文本:为什么这笔交易?
            weekly_trend: trade.weekly_trend,
            daily_setup: trade.daily_setup,
            emotional_state: prompt_user("评估你的情绪状态 1-5"),
            confidence: prompt_user("评估你的信心 1-5"),
            screenshot: capture_chart(trade.stock)
        }
        storage.insert(entry)

    function record_exit(trade_id, exit_data):
        update = {
            exit_date: today(),
            exit_price: exit_data.price,
            exit_reason: exit_data.reason,  # STOP_LOSS, TARGET, TRAIL, TIME, MANUAL
            pnl_rmb: exit_data.pnl,
            pnl_r: exit_data.pnl / original_risk,
            holding_days: exit_data.days_held,
            max_adverse_excursion: exit_data.mae,
            max_favorable_excursion: exit_data.mfe,
            capture_ratio: exit_data.pnl / exit_data.mfe,
            emotional_state_exit: prompt_user("评估你的情绪状态 1-5"),
            followed_rules: prompt_user("你是否遵守了所有规则? Y/N"),
            lessons: prompt_user("这笔交易的主要教训是什么?")
        }
        storage.update(trade_id, update)

    function weekly_review():
        trades = get_trades_this_week()
        report = {
            total_trades: len(trades),
            winners: count(t for t in trades if t.pnl > 0),
            losers: count(t for t in trades if t.pnl <= 0),
            win_rate: winners / total_trades,
            total_pnl: sum(t.pnl for t in trades),
            average_r: mean(t.pnl_r for t in trades),
            largest_win: max(t.pnl for t in trades),
            largest_loss: min(t.pnl for t in trades),
            rule_violations: count(t for t in trades if not t.followed_rules),
            avg_emotional_state: mean(t.emotional_state for t in trades)
        }
        print_report(report)

(文件已截断,原文共1034行)


实施规范编译自陈凯,交易之路。本文件是用于实际应用的系统化提炼,不替代阅读原作。