从想法到伪代码:策略描述的标准格式

结论先行:把交易想法写成可测试的伪代码:定义标的池、入场规则、出场规则、仓位、风控。标准格式能在写代码前暴露逻辑漏洞。
策略编写 阅读 13 分钟 2026-08-12

把策略想法写成代码之前,先用入场、出场、仓位、过滤四段式把它写成没有歧义的伪代码。判断标准只有一条:把这段描述交给三个不同的人去实现,三份代码的回测结果必须一致。做不到,就说明描述还不够精确。

本文要点

  • 四段式是策略描述的最小完备结构:入场、出场、仓位、过滤,缺一段就无法实现。
  • 「突破后买入」不是策略描述,因为突破的窗口、幅度、确认方式和成交时点全都未定义。
  • 每个条件都必须写清用哪根 K 线的哪个字段,以及在哪根 K 线成交。
  • 出场必须包含止损、止盈和时间退出三类,只写止盈的策略无法上实盘。
  • 先写伪代码再写代码,能在成本最低的阶段发现逻辑漏洞。

为什么必须先写伪代码

跳过伪代码直接写 Python,看起来省了一步,实际上代价很高。问题出在你会在写代码的过程中即兴做决定——止损用固定百分比还是 ATR 倍数、信号在收盘确认还是盘中触发、同时出现多个信号怎么处理。这些决定散落在代码各处,你自己都记不清做了什么假设,回测结果自然无法解释。

伪代码的作用是把所有决定集中到一个地方、用自然语言显式写出来。它不需要能运行,但必须能被无歧义地翻译。这带来三个直接好处。

第一,逻辑漏洞暴露得早。写伪代码时你会发现「价格回落就平仓」根本没定义回落多少,而这个问题在代码里可能表现为一个随手写下的 0.02,永远没人再审视。第二,交给 AI 生成代码时命中率大幅提高,因为模型不需要猜你的意图。第三,回测结果异常时,你有一份权威的规格说明可以逐条核对代码是否忠实实现。

一个实用的验收标准:把伪代码发给三个人,让他们各自实现并跑同一份数据,三份回测结果应当完全一致。出现差异的地方,就是你的描述有歧义的地方。自己检验时可以隔一周再读一遍自己的伪代码,看能不能只按字面意思实现出来。

第一段:入场——什么条件下建仓

入场段要回答四件事:用什么数据、什么条件触发、在哪个时点成交、方向是多还是空。四件事缺一件,代码就会有多种写法。

最常见的问题是时点不明。「20 日均线上穿 60 日均线时买入」这句话有三种实现:用第 t 根收盘价确认交叉、第 t 根收盘价成交(含未来函数,因为收盘价确定时该 K 线已结束);用第 t 根确认、第 t+1 根开盘成交(正确);盘中实时判断交叉、立即成交(需要 tick 数据,且交叉可能来回反复)。三种写法的回测收益可能差出一倍。

第二个问题是条件本身没有量化。「突破前期高点」——前期是多少根 K 线?突破需要超过多少幅度才算,还是碰到就算?收盘价突破还是最高价突破?需要连续几根确认?每个未回答的问题都是一个自由参数,而未定义的自由参数会在实现时被随意填上。

第三个问题是重复入场规则缺失。条件持续满足时是每根 K 线都加仓,还是只在条件首次满足的那一根开仓?这决定了策略是单笔还是金字塔加仓,性质完全不同。

  • 数据来源:哪个交易对、哪个周期、用 open / high / low / close / volume 的哪个字段。
  • 触发条件:用完整的比较式写出,所有窗口长度和阈值都填具体数字。
  • 确认时点:在第 t 根 K 线收盘后判断(默认写法)。
  • 成交时点与价格:第 t+1 根开盘价成交,或第 t+1 根以限价单挂在某价位。
  • 重复处理:条件首次满足才开仓,已有持仓时忽略新信号。

第二段:出场——三类退出必须都写

出场是新手写得最草率的一段,通常只写了「达到目标就卖」。完整的出场必须覆盖三类,缺任何一类都会在某种行情下卡死。

止损:亏损到什么程度必须无条件离场。写法上要指明基准(入场价、还是最近的波动区间)、幅度(固定百分比、ATR 倍数、还是某个结构位)、以及判断字段。用最低价判断止损和用收盘价判断止损差别很大:前者会被盘中插针扫掉,后者可能当天亏损远超设定值。两种都可以,但必须明确选哪种,因为回测和实盘要一致。

止盈或跟踪退出:固定止盈简单但会切断趋势;跟踪止损能吃到大段行情但会回吐一部分利润。跟踪止损要写清从哪个点开始跟踪、回撤多少触发。

时间退出:持仓超过 N 根 K 线仍未触发止损止盈时强制平仓。这一条最常被漏掉,但它很重要——没有时间退出的策略会出现持仓被无限期占用的情况,资金效率极低,而且回测里可能有一笔持仓横跨半年,严重扭曲统计结果。

四段式常见缺失项清单
段落必须写明的项漏掉的后果
入场数据字段、条件数值、确认时点、成交时点、重复处理同一描述出现多种实现,回测结果差数倍
出场止损、止盈或跟踪、时间退出、判断字段缺时间退出会出现持仓被无限期占用
仓位单笔规模口径、单标的上限、总敞口上限多信号同时触发时意外满仓
过滤流动性、波动率、市场状态、回撤停机线策略失效期继续消耗资金
成本手续费率、滑点、是否含资金费率高频策略回测由盈转亏
假设杠杆、方向限制、成交量假设半年后无法复现当初的简化条件
止损条件必须在伪代码里写成无条件执行,不能带任何「除非」。实盘中最常见的亏损放大路径是:触发止损时觉得马上要反弹,手动取消一次,之后亏损扩大到无法接受。规则一旦写下就不再讨论,这是量化区别于主观交易的核心。涉及杠杆时更需严格,因为强制平仓会先于你的止损被触发。

第三段:仓位——每次投入多少

仓位段决定同样的信号能带来多少收益和多大回撤。它至少要回答:单笔投入多少、最多同时持有几个仓位、总敞口上限是多少。

三种常见写法各有适用场景。固定金额最简单,每笔投入固定的数额,适合初期验证逻辑,缺点是不随账户规模调整。固定比例是每笔投入账户权益的固定百分比,天然具备复利与缩量效果,是最常用的做法。固定风险更严谨:先定好单笔最大亏损占权益的比例(比如 1%),再根据止损距离反推仓位大小,止损越远仓位越小,使每笔交易的风险敞口一致。

还要写清总敞口约束。多标的策略里,如果每个标的都按 20% 仓位建仓,同时触发五个信号就满仓了,而这些标的在极端行情下往往同涨同跌,实际风险远高于分散预期。伪代码里要明确总敞口上限,以及超限时是拒绝新信号还是按比例缩减。

第四段:过滤——什么时候不做

过滤段是四段里最容易被省略、但对实盘结果影响最直接的一段。它规定在什么条件下即使入场信号满足也不开仓。

常用的过滤维度包括:流动性过滤(成交额低于阈值不做,避免滑点吞掉利润)、波动率过滤(波动过低时趋势策略容易反复被打,波动过高时止损容易被瞬间击穿)、市场状态过滤(趋势策略在横盘期停止交易)、时间过滤(避开重大数据公布或结算时点)、风控级过滤(账户回撤超过阈值时全局停止开新仓)。

最后一条尤其重要。回撤停机线是把风控写进策略而不是留在心里的唯一方式:当权益从峰值回落超过设定比例时,停止一切新开仓,只允许平仓。它不会提高收益,但能防止策略在失效期继续消耗资金。指标层面的取舍可以参考四个核心指标那篇。

模糊描述与精确描述对照
模糊写法问题所在精确写法
突破后买入窗口、幅度、字段、时点全未定义第 t 根收盘价 > 前 20 根 high 的最大值 × 1.001,第 t+1 根开盘市价买入
成交量放大时入场放大相对于什么、多少倍未定义第 t 根 volume > 前 50 根 volume 均值 × 1.5
回落就止损回落基准与幅度未定义收盘价 < 入场价 × 0.97 时,下一根开盘平仓
趋势明确时做多趋势无操作定义收盘价 > 200 周期均线,且该均线近 20 周期斜率为正
适当控制仓位无任何数值单笔风险 = 权益 × 1%,仓位 = 单笔风险 ÷ 止损距离
行情不好就休息不好无定义权益自峰值回撤 > 15% 时停止开新仓,仅允许平仓
流动性够的币才做够无阈值过去 24 小时成交额 > 5000 万 USDT
写伪代码时有个自查动作很有效:把每一句里的形容词和副词圈出来。适当、明显、足够、较大、快速——这些词后面一定藏着一个没填的数字。全部替换成具体数值后,伪代码基本就可用了。

完整的四段式模板

下面是一份可以直接复制修改的模板,用一条趋势跟随策略填充。注意每一行都可以被唯一地翻译成代码,没有需要读者猜测的地方。

STRATEGY: 20/60 均线趋势跟随(单标的、仅做多、无杠杆)

DATA:
  symbol   = "BTCUSDT"
  interval = "1h"
  fields   = [open, high, low, close, volume]   # 索引为 UTC 开盘时间
  注:所有特征只使用第 t 根及更早的数据;成交发生在第 t+1 根开盘。

INDICATORS:
  ma_fast[t] = mean(close[t-19 .. t])           # 20 周期
  ma_slow[t] = mean(close[t-59 .. t])           # 60 周期
  atr[t]     = mean(true_range[t-13 .. t])      # 14 周期 ATR
  vol_ma[t]  = mean(volume[t-49 .. t])          # 50 周期成交量均值

# ---------- 1. FILTER:先判断今天是否允许交易 ----------
FILTER:
  f1 = volume[t] > vol_ma[t] * 1.2              # 流动性/参与度
  f2 = atr[t] / close[t] > 0.005                # 波动率下限,太死不做
  f3 = atr[t] / close[t] < 0.060                # 波动率上限,太疯不做
  f4 = equity_drawdown[t] < 0.15                # 权益回撤未超 15%
  allow_entry = f1 AND f2 AND f3 AND f4

# ---------- 2. ENTRY:入场 ----------
ENTRY (long):
  cond_cross = ma_fast[t] > ma_slow[t] AND ma_fast[t-1] <= ma_slow[t-1]
  IF cond_cross AND allow_entry AND position == 0:
      在第 t+1 根 open 以市价买入 size(见 SIZING)
      记录 entry_price = 第 t+1 根 open
      记录 stop_price  = entry_price - 2.0 * atr[t]
      记录 peak_price  = entry_price
      记录 bars_held   = 0
  # 条件持续满足不加仓:已有持仓时忽略新信号

# ---------- 3. SIZING:仓位 ----------
SIZING:
  risk_per_trade = equity[t] * 0.01             # 单笔最大风险 1% 权益
  stop_distance  = 2.0 * atr[t]
  size           = risk_per_trade / stop_distance
  size           = min(size, equity[t] * 0.30 / close[t])   # 单标的敞口上限 30%
  # 多标的场景追加:sum(所有持仓名义价值) <= equity * 0.60

# ---------- 4. EXIT:出场(三类,按优先级依次判断) ----------
EXIT:
  bars_held = bars_held + 1
  peak_price = max(peak_price, close[t])

  e1 STOP_LOSS:  IF close[t] <= stop_price
  e2 TRAILING:   IF close[t] <= peak_price - 3.0 * atr[t] AND close[t] > entry_price
  e3 SIGNAL_OUT: IF ma_fast[t] < ma_slow[t]
  e4 TIME_OUT:   IF bars_held >= 240                       # 约 10 天未走出趋势

  IF e1 OR e2 OR e3 OR e4:
      在第 t+1 根 open 以市价全部平仓
      清空 entry_price / stop_price / peak_price / bars_held
  # 止损无条件执行,不存在任何例外分支

COSTS (回测必须设置,不可省略):
  taker_fee = 0.0005 (单边)
  slippage  = 0.0005 (单边,按成交额计)

ASSUMPTIONS (显式记录,便于日后核对):
  - 不使用杠杆,不做空
  - 忽略资金费率(现货标的)
  - 假设第 t+1 根开盘价可全额成交(大额资金需重估)

这份模板里有几个刻意的设计。过滤段放在最前面,因为它是否决权,先判断能省掉后面的计算。成交时点在每一处都显式写出,这是防未来函数最有效的手段。成本参数写进规格,避免回测时忘了加。假设单独成段,因为半年后你回头看时,最想知道的就是当初做了哪些简化。

写完模板之后再交给 AI 生成实现代码,效率和正确率都会明显高于直接口述需求。具体的提示写法见用大模型写策略代码的正确提示方式,实现层面的向量化陷阱见向量化 vs 逐 K 线,完整学习路径在量化学院

pseudocode

常见问题

伪代码要写到多细才够?

标准是可被唯一翻译。具体检验方法:通读一遍,把所有形容词、副词和没有数值的条件标出来,全部替换成具体数字和明确字段;再确认每个条件用了哪根 K 线的哪个字段、成交发生在哪根 K 线。都做到了就够细了,再细就变成写代码了。

四段的顺序可以调整吗?

描述顺序不重要,但执行顺序有讲究。代码里建议先算过滤(否决权最高,能提前跳过),再判出场(已有持仓优先处理),最后判入场。把入场放在出场之前容易出现同一根 K 线先平后开的重复交易,回测里表现为交易次数异常偏多。

策略只有做多逻辑,需要写做空段吗?

不需要,但要在假设段里显式写明「不做空」。显式记录限制条件和写下规则同样重要,否则日后你或别人读这份规格时,会不确定做空是被排除了还是忘了写。

写好伪代码后回测结果不理想,先改哪一段?

先不要改参数。按顺序核对:成交时点是否有未来函数、成本是否已计入、交易笔数是否足够多。三项确认无误后,优先检查出场段和过滤段,这两段对结果的影响通常大于入场条件的参数微调。反复微调入场参数是过拟合的主要来源,回测数字为历史数据,不构成收益承诺。

风险提示:量化交易同样存在亏损风险。本站所有策略、信号、收益数据均为历史回测数据,不构成收益承诺,也不构成投资建议。加密货币波动剧烈,请先用小资金验证,并遵守所在地法律法规。
📚 参考来源
Google AI 优化指南(2026-06更新)

developers.google.com/search/docs/fundamentals/ai-optimization-guide — Google官方对生成式AI搜索优化的指引。

SE Ranking AI引用研究

seranking.com/blog/ai-search-research/ — AI答案引用来源研究(44%引用来自页面前30%)。

量化分析维基百科

en.wikipedia.org/wiki/Quantitative_analysis_(finance) — 量化分析的基础定义与学术脉络。