深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

基础入门

【vectorbt 系列 第5讲】构造卖出信号

本讲在已有价格、均线和买入信号的基础上,补出一列最小卖出信号,并把买卖条件放回同一张表里并排检查。目标是让入门者真正得到一套可入场、可离场的最小规则表达,为下一讲回测入口做好准备。

2026-04-23 智铨研究 阅读时长 7 分钟

目录

  1. 本节目标
  2. 为什么卖出信号值得单独一讲
  3. 沿用第 4 讲已有买入信号的工作表
  4. 四步构造最小卖出信号
  5. 先把规则口径说清楚
  6. 把规则写成布尔列
  7. 把价格、均线、买卖信号一起打印
  8. 单独筛出True的卖出样本
  9. 确认卖出信号已经可用
  10. 新列已经存在
  11. 新列是布尔含义
  12. 买入和卖出至少能分成两类位置
  13. 卖出样本能被单独拉出来检查
  14. 为什么卖出信号看起来“不好看”
  15. 卖出信号很多
  16. 卖出信号很少
  17. 某些行买入和卖出都为False
  18. 前几行卖出信号没有解释力
  19. 哪些情况仍然算本讲完成
  20. 写一个最小卖出信号函数
  21. 买卖信号是同一条逻辑线的两端
  22. 本讲对下一讲回测入口意味着什么
  23. 完成标准
  24. 系列衔接
  25. 风险揭示与免责声明

【vectorbt 系列 第5讲】构造卖出信号

1. 本节目标

第 5 讲要做的事情很直接:在已经有 closema_5buy_signal 的工作表上,再补出一列最小卖出信号 sell_signal。如果第 4 讲解决的是“什么时候考虑入场”,那这一讲解决的就是“什么时候考虑离场”。

学完这一讲后,你可以直接完成下面几件事:

  1. 用一句清楚的话定义卖出规则。
  2. 把这条规则写成一列布尔值。
  3. 把买入和卖出放在同一张表里并排检查。

对入门者来说,这一步很关键,因为从这里开始,你手里的表已经不只是“价格 + 指标”,而是具备了最基础的入场和出场条件。

2. 为什么卖出信号值得单独一讲

很多新手在刚接触回测时,会把注意力全部放在“怎么买”,忽略“怎么卖”。但对任何一套最小策略来说,卖出条件不是附属品,而是策略能否真正闭环的另一半。没有卖出信号,你顶多只有一列会不断提示“这里看起来能进场”的布尔值;一旦补上卖出信号,你才开始具备“什么时候退出”的规则表达。

第 5 讲单独拎出来讲,还有一个现实原因:如果你把买入、卖出、回测入口全挤在一讲里,新手很容易混淆三层东西:

  1. 规则到底写对没有。
  2. 信号位置和价格关系是否合理。
  3. 最终回测结果是不是由信号本身造成的。

所以第 5 讲的正确节奏是,先把卖出这一层独立写清楚,再往回测入口推进。

3. 沿用第 4 讲已有买入信号的工作表

signal_df = signal_df.copy()
print(signal_df[['date', 'close', 'ma_5', 'buy_signal']].head(12))

当前这张表里至少应该已经有:

如果 buy_signal 还没稳住,第 5 讲就不该往下赶。因为卖出信号最好的练习方式,就是和买入信号并排看。

4. 四步构造最小卖出信号

这一讲和上一讲是镜像关系:规则仍然尽量简单,重点是把离场条件也变成能检查、能复用的一列布尔值。

5. 先把规则口径说清楚

本讲采用和第 4 讲镜像的一条规则:当收盘价小于 5 日均线时,认为满足卖出条件。它不意味着这就是最优规则,只是为了让你先得到一条和买入规则完全对称、容易验证的离场条件。

6. 把规则写成布尔列

signal_df['sell_signal'] = signal_df['close'] < signal_df['ma_5']

这一行做完以后,你就有了第二列核心信号。此时最重要的变化不是代码长度,而是你的工作表已经同时具备“可入场”和“可离场”两类条件。

7. 把价格、均线、买卖信号一起打印

print(signal_df[['date', 'close', 'ma_5', 'buy_signal', 'sell_signal']].head(15))

一定不要只看 sell_signal 这一列。第 5 讲的重点是看相互关系,而不是孤立看一个真假值。你应该能从同一张表上同时看到:价格在哪些位置高于均线,哪些位置低于均线。

8. 单独筛出True的卖出样本

sell_rows = signal_df[signal_df['sell_signal']]
print(sell_rows[['date', 'close', 'ma_5']].head())

这样做的好处和第 4 讲完全一致:它会把命中的样本点直接拉出来,让你更快判断规则是不是在你预期的位置被触发。

9. 确认卖出信号已经可用

验证卖出信号时,重点要看它能否和买入信号一起把样本分出不同位置,而不是只看数量多不多。

10. 新列已经存在

assert 'sell_signal' in signal_df.columns

11. 新列是布尔含义

assert signal_df['sell_signal'].dtype == bool or str(signal_df['sell_signal'].dtype) == 'bool'

12. 买入和卖出至少能分成两类位置

print(signal_df[['close', 'ma_5', 'buy_signal', 'sell_signal']].head(12))

你至少应该看见,close > ma_5close < ma_5 会把样本分到不同位置上,而不是所有行都长得一样。

13. 卖出样本能被单独拉出来检查

print(signal_df[signal_df['sell_signal']][['date', 'close', 'ma_5']].head())

14. 为什么卖出信号看起来“不好看”

卖出信号看起来“不好看”很常见,因为它会直接暴露样本强弱和规则边界。

15. 卖出信号很多

这不一定是错。若样本中有一段持续走弱,close < ma_5 很可能会连续成立很多行。第 5 讲不追求“数量好看”,只追求“规则表达正确”。

16. 卖出信号很少

也不一定错。如果样本整体偏强,价格大部分时间都压在均线上方,那么卖出信号自然会少。关键不是数量,而是它是否出现在符合你直觉的位置。

17. 某些行买入和卖出都为False

这是完全可能的。比如当价格恰好等于均线时,若你使用的是严格的大于和小于,它就不会被归到任一侧。这不是 bug,而是规则边界的一部分。

18. 前几行卖出信号没有解释力

和买入信号一样,前几行如果 ma_5 还是空值,那么 sell_signal 也没有太强解释意义。这说明第 3 讲的均线窗口逻辑仍然在发挥作用。

19. 哪些情况仍然算本讲完成

  1. 你可以用 <,也可以用 <=,只要自己清楚规则口径。
  2. 买卖信号数量不对称,不算失败。
  3. 当前不要求处理“同一行既能买又能卖”的复杂边界,第 5 讲只先建立最简单的两列信号。
  4. 你不必在本讲就讨论收益率和资金曲线,当前只把卖出规则表达完整即可。

20. 写一个最小卖出信号函数

import pandas as pd

def add_sell_signal(df: pd.DataFrame) -> pd.DataFrame:
    out = df.copy()
    out['sell_signal'] = out['close'] < out['ma_5']
    return out

signal_df = add_sell_signal(signal_df)
print(signal_df[['date', 'close', 'ma_5', 'buy_signal', 'sell_signal']].head(15))

这段函数和上一讲的买入信号函数一起,已经足够构成一套最小策略信号层。

21. 买卖信号是同一条逻辑线的两端

你可以把第 4 讲和第 5 讲理解成一件事的两个面。第 4 讲告诉你,价格高于均线时如何定义“考虑进场”;第 5 讲则告诉你,价格低于均线时如何定义“考虑离场”。两讲单独拆开,是为了让你把每一边都看清;合在一起看,你就会发现,这其实已经是一套极小但完整的规则系统。

这也是为什么第 5 讲最推荐的检查方式,是把 closema_5buy_signalsell_signal 一次性打印出来。你要看的不是哪一列单独是否漂亮,而是整张表是否在表达一套一致的规则。

22. 本讲对下一讲回测入口意味着什么

到第 5 讲结束时,你手里终于具备了跑第一轮回测所需的最关键输入:一列买入条件和一列卖出条件。下一讲之所以能自然过渡到“跑第一轮向量化回测”,正是因为这两列已经存在。也就是说,第 6 讲并不是无中生有地新增一套复杂逻辑,而只是把你现在这张表交给 vectorbt 的回测入口去解释。

23. 完成标准

如果你现在已经能稳定得到一列 sell_signal,并能把它和 buy_signal 一起放在同一张表里解释,那第 5 讲就已经完成了它的任务。

24. 系列衔接

本讲是《vectorbt回测入门短课》的第 5/8 讲,当前主题是《构造卖出信号》。

上一讲:第 4 讲《构造买入信号》。

下一讲:第 6 讲《跑第一轮向量化回测》。

后续安排:第 7 讲《查看收益回撤和交易次数》;第 8 讲《比较5日和10日窗口》。

25. 风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。