news 2026/10/20 23:41:52

从模糊需求到RSI量化风控闭环:状态机与回测实战记录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从模糊需求到RSI量化风控闭环:状态机与回测实战记录

“能不能做个指标,把风险挡住?”这是我接手这个项目时,需求方给出的全部信息。没有明确策略逻辑,没有预期收益,甚至没有说清“挡住”是指止损、减仓还只是提示。项目代号就叫“RSI-Kekkai”,Kekkai在日语里是“结界”的意思——需求方想要的,是一个能守住账户回撤的屏障。

从一句模糊需求到最终跑通回测、完成参数验证、接入模拟盘环境,整个过程花了三周。这篇博文想完整记录这段经历:我是怎么把“挡住风险”翻译成RSI指标规则的,怎么设计“结界”的工程结构,又是怎么让它变成一个可验证、可被追问、可迭代的量化闭环。如果你也接过这种“一句话需求”,或者正在设计自己的趋势/震荡判别边界,这篇文章应该对你有用。

1. 那句模糊需求背后,其实藏着三个待解的问题

1.1 原话、潜台词与真正的问题

需求方的原话是:“最近行情上下乱跳,能不能搞个东西,跌多了提醒我,至少别再深套了。”

这句话拆开看,有三个层次。第一层是“跌多了提醒我”,这指向超卖识别;第二层是“别再深套”,这指向止损或仓位控制;第三层是“上下乱跳”,这说明需求方默认当前市场处于震荡而非单边趋势。三者叠加,RSI(相对强弱指标)几乎是天然答案——它本身就是衡量涨跌动能强弱、标注超买超卖区的经典指标。

但仅仅确认用RSI还远远不够。真正的问题是:当RSI进入超卖区,系统要做什么动作?是弹一个提示让用户自己决定,还是自动降低仓位?提示的阈值是标准的30,还是要根据不同品种调?如果行情继续下跌,RSI持续钝化在超卖区,系统怎么避免反复发出错误的“到底了”信号?这三个问题不解决,需求就依然是模糊的。

1.2 把业务语言翻译成规则语言

和需求方来回对了三轮之后,我把需求收敛成三条可验证的规则:

  • 当RSI(14)低于30时,视为进入“结界警戒区”,系统输出减仓信号;
  • 当RSI(14)从30以下回升至35以上时,视为“结界解除”,系统输出恢复仓位信号;
  • 若RSI在低于15的极值区停留超过3根K线,强制触发一次仓位复查流程,不自动加仓。

这三条规则看起来简单,但每一条都对应着需求背后的潜台词。“回升至35才解除”是为了避免在30附近反复横跳产生大量无效信号;“极值区停留超过3根K线”是为了应对RSI钝化——这是RSI策略最容易出问题的环节。

这一轮澄清花的时间不长,但价值极高。需求方看到这三条规则时,立刻提出了一个问题:“那如果它一直钝化怎么办?”这说明他真的理解了方案边界——这就是从模糊需求走向可验证闭环的第一步:不是翻译需求,而是把需求逼成一个可以被证伪的系统。

2. “结界”的工程化拆解:为什么RSI适合做屏障,以及它的三个致命短板

2.1 为什么选RSI而不是MACD或布林带

做风控屏障,最重要的是对“极端状态”的反应速度和可解释性。RSI天然满足这两点:它的取值范围固定,落在0到100之间,天然是一个“有无越界”的判定器;它的计算方式决定了它对近期价格变化敏感,比MACD的两条线更快反映动能反转。

相比之下,MACD的边界是动态变化的——金叉死叉的参考线本身在移动,作为“边界”来用,缺少一个稳定锚点;布林带虽然也能给出通道边界,但它的上下轨是统计带宽,当行情单边加速时带宽会迅速扩大,出现“价格越跌、下轨越远离价格”的尴尬情况,根本挡不住下跌。

RSI的固定区间、固定阈值,让“破界”和“回归”这两个动作有了明确定义。这也是“Kekkai”这个概念能落地的原因——结界必须先有边界,边界必须稳定。

2.2 RSI计算的细节,以及一个常被忽略的参数陷阱

RSI的标准计算方式不复杂:取N周期内的涨幅平均值与跌幅平均值,算出相对强弱值,再映射到0到100区间。

N = 14 up = 涨幅中大于0的部分的均值(N周期) down = 跌幅中大于0的部分的均值(N周期) RS = up / down RSI = 100 - 100 / (1 + RS)

实操中有一个细节极其关键:跌跌幅的均值计算,有的库用SMA(简单移动平均),有的用Wilder平滑法。两者在长周期的RSI数值上差异不大,但在短周期上,Wilder平滑会让RSI变化更平缓,减少跳变。

我最终选用了Wilder平滑法,原因单纯:它让RSI曲线更稳,边界突破次数少了,误报率明显下降。

但真正让我在测试中差点翻车的是另一个问题——RSI的计算窗口。很多人默认用14,因为这是最经典的取值,但它不是万能的。我拿某只日线级别走势测试时,14周期的RSI经常跌到20以下,导致“结界警戒区”频繁触发,信号多到没法用。后来换用21周期,信号频率立刻降下来了。

参数选择没有标准答案,但有一个原则:让“边界内波动”覆盖掉噪音,让“破界”只留给真正的极端行情。阈值和周期必须匹配你观察的品种波动特性,不能拿来就用。

2.3 钝化、钝化、还是钝化

RSI做风控屏障,最怕的是钝化。钝化是指价格持续单边下跌,RSI长期趴在超卖区,信号一直显示“超卖、该反弹了”,但价格还在跌。这时候如果系统机械地执行“进入超卖就买入/加仓”,就是灾难。

我设计的应对方式是引入“结界状态机”。这个状态机有四个状态:

  • 安全区:RSI在30以上,不触发任何动作;
  • 警戒区:RSI跌破30,记录入场信号,但只提示不操作;
  • 极值区:RSI跌破15,且停留超过3根K线,强制触发仓位复查流程;
  • 回归确认:RSI回升到35以上,且连续2根K线站稳,才解除警戒。

这个状态机的核心思路是:把RSI从“单一信号源”降级为“状态判定器”。我不再依赖RSI每一次穿越阈值都产生交易动作,而是依赖它在不同区间的停留状态来调整系统行为。钝化阶段系统不会反复给矛盾信号,而是锁定在极值区,直到出现真正的反转确认。

3. 从指标到闭环:数据层、信号层、验证层的完整实现

3.1 数据层:清洗K线时踩的坑

项目第一步是准备行情数据。我用的是某交易平台的分钟线数据来做参数调试,日线数据做回测验证。这里有个典型的坑:不同数据源的K线时间戳对齐方式不同,有的是K线开始时间,有的是K线结束时间。如果混用,RSI计算会出现偏移一根K线的问题,信号整体错位。

我用了一个最简单的办法统一处理:清洗时强制把时间戳归一化为“K线开始时间”,并把数据按时间序列升序排列,遇到重复时间戳直接去重。这些操作看起来基础,但直接影响RSI计算的正确性。

清洗脚本长这样:

def clean_kline(df): df = df.sort_values("timestamp") df = df.drop_duplicates(subset="timestamp", keep="last") df["rs_basis"] = df["close"].diff() return df

3.2 信号层:状态机的代码实现

核心逻辑就是上面说的四状态状态机。实际写下来,比预想中要简洁:

def kekkai_state(rsi_value, prev_state, hold_count): # 状态递进:安全 -> 警戒 -> 极值 -> 回归确认 if rsi_value < 15: current_state = "extreme" elif rsi_value < 30: current_state = "alert" elif rsi_value > 35: current_state = "safe" else: # 30到35之间,维持上一状态,避免频繁切换 current_state = prev_state if current_state == "extreme": hold_count += 1 if hold_count >= 3: trigger_action("仓位复查") elif current_state == "alert": hold_count = 0 return current_state, hold_count

这段代码里有一个关键设计——“30到35之间维持上一状态”。这就是所谓的“滞回区间”,用工程术语说叫hysteresis。它避免了RSI在30附近来回穿越时,系统不断在安全区和警戒区之间反复切换,产生大量无效信号。

3.3 验证层:怎么让“可验证”三个字落地

闭环的最终闭环,是验证。验证不是跑一次回测看收益率曲线就完了,而是要让每一步都能被追问、被复现。我给这个项目搭了三层验证:

第一层是信号正确性验证。随机抽取20个历史时间点,人工确认历史价格走势,核对系统在这些时间点输出的信号是否符合规则。这步慢,但能抓出代码逻辑和数据对齐问题。

第二层是参数敏感性验证。把RSI周期从14改为13、16、21,把阈值从30改为25、28、32,观察信号数量和收益率变化。好的策略应该对参数微调不敏感。如果换个参数结果就剧烈变化,那说明策略逻辑本身是在“过度拟合”历史数据,而不是在捕捉真实规律。

第三层是样本外验证。拿前80%的数据做参数调试,后20%数据用来做最终验证,后者完全不参与参数选择过程。样本外表现才接近真实水平。

这三层验证跑完,项目才算真正达到了“可验证的闭环”。没有这个过程,策略就只是“看起来能赚钱的曲线”而已。

4. 回测结果怎么看:一个反直觉的真相和两条铁的纪律

4.1 别盯着收益率曲线,先看最大回撤和信号胜率

第一次跑完回测,收益率曲线很漂亮,年化收益亮眼。如果只看收益率,这个项目当场就能验收。但我把最大回撤拉出来一看,心里凉了半截——回撤几乎全部集中在RSI钝化区间,策略在震荡行情下表现尚可,在单边下跌行情中形同虚设。

这其实暴露了一个本质问题:RSI本质上是动量指标,“钝化”是它的天然盲区。任何以RSI为核心的风控系统,都必须接受一个事实:在极端单边行情中,它能做的是止损,而不是预测反转。

因此我调整了回测考核指标,优先看三组数据:最大回撤是否被控制在阈值以内、信号胜率是否稳定在合理区间、单笔止损是否能覆盖RSI钝化期的连续亏损。收益率排在这三者之后。

4.2 纪律一:先有止损逻辑,再谈信号逻辑

很多人在设计RSI策略时,先想的是“RSI低于30我就买”,这是典型的信号驱动思路。但做风控屏障,思路必须反过来:先定义什么情况下无条件撤退,再定义什么情况下可以进场。

我给这个项目加的底线规则是:如果收盘价跌破此前20个交易日的最低价,无论RSI处于什么区域,强制清仓该标的的信号。这条规则完全不依赖RSI,它的作用是防止RSI钝化期出现极端损失。

4.3 纪律二:信号必须可回溯、可审计

项目第一次上线模拟盘时,出现过一次信号延迟问题——系统在盘中触发了警戒信号,但需求方盘后复盘时完全找不到对应的历史标记。排查下来,是信号记录表中只保存了最新状态,没有保存每个信号产生的完整上下文。

修复方法是:每产生一个信号,强制记录这个信号发生时RSI的取值、当时价格的相对位置、行情数据源时间戳、以及触发规则编号。这样每一个“结界动作”都能被回溯。

5. 从“能跑”到“敢用”:模拟盘阶段的三次修正

5.1 修正在盘中发现的时间偏差

接入模拟盘后,第一个问题是信号时间与预期不符。系统发出警戒信号的时间,比需求方主观感受的“危险时刻”晚了大约两小时。查下来,问题出在RSI计算时用了未复权的收盘价,而数据源在盘中推送的是实时价,两者在除权除息日会产生明显偏差。

修正方案是对数据源做前复权处理,同时在计算RSI时明确使用复权价。这个坑在回测阶段完全体现不出来,因为回测数据已经过处理,但实时数据不会。

5.2 修正二:模拟盘和回测的最大差异,是延迟和滑点

回测可以假设信号产生的同时就按收盘价成交,但模拟盘必须面对现实:信号产生后,人工确认、下单、成交之间有时间差。在快市环境下,这个时间差足以让实际成交价偏离信号价好几个档位。

我给信号加了一个“确认延迟”参数,默认设为5分钟,在回测中也加入同样的延迟假设,让测试环境更接近真实。这步修正直接过滤掉了很多在纯回测中看起来不错、其实无法稳定实现的策略变体。

5.3 修正三:把“提示”升级成“动作”,才算闭环

项目前两周,系统只会输出提示信号,实际操作由需求方自行判断。结果需求方因为最初几天行情反弹了,连续两次忽略警戒信号。直到一次深度回调吃了亏,他才回来说:“提示没用,得让它直接控制仓位。”

这是整个项目中最重要的一次需求变更。我把“提示型系统”升级为“动作型系统”:当警戒区信号触发时,系统自动计算当前持仓的建议减仓比例,并输出可直接执行的指令;只有当需求方人工确认后,系统才恢复安全区状态。

这一步让“RSI-Kekkai”从一个“看板”变成了“半自动风控装置”。从用户反馈来看,这个变更比之前所有功能叠加起来都更有价值。

6. 项目复盘:三个判断和两个遗憾

6.1 判断一:状态机比报警器更接近真实需求

最初版的设计就是简单的“跌破30报警”,做成之后发现没人重视它。原因很简单:报警器只会说“危险”,但不说“怎么办”。状态机的价值不在于更智能,而在于它给出了行为路径——进了警戒区该做什么,进了极值区该做什么,什么时候解除警戒。它把“风险感知”变成了“风险管理”。

6.2 判断二:模糊需求不可怕,怕的是没人把它逼成可证伪的问题

这个项目的前两天,我们几乎没有写代码。所有时间都花在把“挡住风险”变成“跌破30提示、回升35解除、极值区停留3根复查”这样的具体规则上。一旦规则具象化,后面的开发就只是执行了。

6.3 遗憾一:没有在实盘单边行情中经受真正考验

项目验证期结束时,市场整体处于震荡格局,“结界”最害怕的钝化场景只出现过一次,且持续时间很短。它还没有经历过连续多日阴跌的极限测试。这是一个未完成的验证项,后续如果遇到类似的行情,我会把完整的复盘记录补上。

6.4 遗憾二:没有做多标的组合层面的屏障协同

目前每个标的的“结界”是独立运作的,但一个账户同时持有多只标的时,真正的风险是系统性共振——所有标的同时进入警戒区。现在系统没有在组合层面做“总警戒”判定。这是我下一版最想补上的功能:当持仓中超过40%的标的进入警戒区时,触发组合级风控动作。

7. 给后来者的三句话

第一句,做量化风控,永远先把防守逻辑写在进攻逻辑前面。RSI能告诉你哪里是墙,但先要决定好撞墙之后怎么活着回来。

第二句,任何指标都需要状态化,不要指望单次穿越能代表全部含义。RSI钝化是常态,不是异常,系统设计要围绕常态运转,而不是围绕理想情况设计。

第三句,多花时间在数据清洗和信号回溯上。整个项目中让我最狼狈的,不是策略逻辑,而是除权日的价格偏移和不同数据源之间的时间戳对齐。

这个项目最后交付的是一个能跑、能查、能调整的半自动风控闭环。它不完美,但在“从模糊需求到可验证闭环”这件事上,该走的路径都走通了。如果你正在做类似的事,希望这篇记录能帮你少踩几个坑——尤其是那个除权价格的坑,真的太隐蔽了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 23:40:35

网络欺骗实验入门:ARP与DNS欺骗原理及实操

1. 网络欺骗实验到底在做什么第一次听到“网络欺骗实验”这个词&#xff0c;很多人脑子里冒出来的画面可能是黑客电影里那种敲几行代码就能把整个机房搞瘫的场景。实际上&#xff0c;网络欺骗实验是一个在网络安全教学和攻防演练中非常经典的项目类型&#xff0c;它的核心目标不…

作者头像 李华
网站建设 2026/10/20 23:40:13

QRBiLSTM区间预测实战:MATLAB分位数回归与BiLSTM时序不确定性建模

简介&#xff1a;这份资源面向需要在MATLAB中实现时间序列区间预测的学习者与研究人员&#xff0c;聚焦QRBiLSTM双向长短期记忆神经网络与分位数回归的结合应用&#xff0c;可用于风速、负荷、功率等场景的区间预测建模。资源包共5个文件&#xff0c;包含4个m程序文件与1个xlsx…

作者头像 李华
网站建设 2026/10/20 23:38:55

创业合规:从戈壁徒步到财税实战的底层逻辑

122公里戈壁徒步和35年财税修行&#xff0c;这两件事放在一起&#xff0c;听起来有点跨界&#xff0c;但它们确实在我身上重叠成了同一种判断力。从戈壁回来后&#xff0c;我越来越确信一件事&#xff1a;做财税合规&#xff0c;跟徒步穿越戈壁是同一个逻辑——你不需要跑得最快…

作者头像 李华
网站建设 2026/10/20 23:38:49

印刷报价系统参数配置与计算逻辑拆解:从纸张到工序的完整复现

简介&#xff1a;印刷企业报价系统是一套面向印刷行业中小企业的业务管理软件&#xff0c;重点解决报价效率低、客户与材料信息分散等实际问题&#xff0c;适合初入行业的从业者或需要快速搭建报价流程的技术人员参考使用。资源包共118个文件&#xff0c;约57.85MB&#xff0c;…

作者头像 李华
网站建设 2026/10/20 23:38:45

LISREL验证性因素分析完整教程:从模型设定到拟合解读

简介&#xff1a;面向社会科学、心理学及教育学领域需要运用结构方程模型的研究者&#xff0c;这份PPT系统讲解LISREL软件进行验证性因素分析的完整流程。内容涵盖准确性与简洁性的权衡思路、观测变量相关矩阵的输入方式、因子负荷与误差方差的参数估计&#xff0c;以及NNFI、C…

作者头像 李华
网站建设 2026/10/20 23:37:43

Java家庭财务管理系统APP毕设全解析:架构、数据库与答辩要点

1. 项目定位&#xff1a;这是个什么样的毕设选题家庭财务管理系统放在计算机毕业设计里&#xff0c;属于“看起来很常见&#xff0c;但要做好并不容易”的经典选题。它既是移动应用开发题&#xff0c;又是信息管理系统题&#xff0c;还带了一点数据分析的味道。换句话说&#x…

作者头像 李华