- 金融科技
- 数据分析
- 后端
- AI 应用
【免费下载链接】jesse
An advanced crypto trading bot written in Python
规则显著性检验(Rule Significance Testing,简称 RST)是 Jesse 框架内置的一种统计诊断手段:它在不实际下单的前提下运行一次“纯信号回测”,记录策略在每个已收盘 K 线上的should_long()/should_short()信号,然后在去除市场趋势(去漂移)后对零中心化的“下一根 K 线规则收益”序列执行平稳自助法(stationary bootstrap),最终给出入场信号是否存在真实边际优势的 p 值。本文以 jesse/mcp/resources/significance_test.md 为骨架,结合 Jesse 仓库的 MCP 工具层、模式运行器与研究算法源码,完整讲解 RST 的适用场景、结果解读、MCP 工具接口、标准工作流与常见错误处理,使读者能够通过 Agent / MCP 客户端独立完成"信号验证 → 决策 → 记录结论"的闭环。
什么是规则显著性检验:原理解读
RST 要回答的问题非常具体:某个入场规则是否具备“下一根 K 线”的预测能力,还是其观察到的收益只是偶然。它与传统回测有三个本质区别:
- 只记录信号,不下任何订单。策略被完整实例化(与正常回测完全一致),但订单提交与撮合全部被跳过;
- 以“规则收益”为统计对象。每根 K 线,信号
+1/-1/0与“下一根去漂移后的对数收益”相乘,得到一个规则收益序列; - 用平稳自助法构造零假设分布。零假设 H0 是“规则的期望下一根去漂移收益不为正”,p 值 = 模拟均值 ≥ 观测均值的比例。
从源码看,rule_significance_test()分为两阶段(见 jesse/research/rule_significance_testing/rule_significance.py):
- 阶段一:信号收集(串行)。通过
run_signal_only_backtest()复用 Jesse 正常回测的蜡烛引擎与时间戳重放计划,但关闭订单执行;在每个已完成的路由 K 线上调用策略的_execute_for_signal_test(),只运行before() / should_long() / should_short() / after()(见 jesse/research/rule_significance_testing/simulator.py)。simulator.py中明确注释:order_service.update_active_orders()与execute_simulated_market_orders()被有意省略——没有订单提交,自然没有订单需要处理。 - 阶段二:自助模拟(并行批处理)。
run_bootstrap_test()以几何分布随机块长(默认均值 10 根)对零中心化后的规则收益序列做平稳重采样,构建零假设下的模拟均值分布,p_value = fraction of simulated means ≥ the observed mean(见 jesse/research/rule_significance_testing/bootstrap.py)。
去漂移(detrending)是关键细节:在计算规则收益前,会先减去整个窗口的均值对数收益,这样即使行情处于单边趋势,没有边际优势的规则期望收益也会归零(见rule_significance.py中mean_log_return = log_returns.mean()与detrended = log_returns - mean_log_return)。中性 K 线(信号为 0)贡献 0 收益,但仍计入观测数。
另外,在通过 MCP 触发时,运行器会以fee=0、杠杆 1、起始资金 10000 的"纯信号"配置构造实验(见 jesse/modes/significance_test_mode/SignificanceTestRunner.py),因为手续费、余额与杠杆不影响这种纯信号计算。
何时使用 RST:它是诊断,不是必经步骤
原文档明确指出:只有用户主动要求时才运行 RST。它是可选的诊断工具,不是编写、回测或改进策略前的必需步骤。典型触发场景:
- 用户问"这个入场信号到底行不行?"、"验证一下这个信号"、"跑一个显著性检验" → 将信号包装成一个最小的"仅入场"策略(如果没有现成的话),在一个有意义的日期窗口上做 RST,并报告 p 值;
- 用户有一个结果平庸的完整策略,想判断入场信号本身弱(而不是出场逻辑弱);
- 用户主动要求验证某个交易假设。
两条重要边界:
- 不要在用户没有要求时擅自运行 RST;
- 不要因为 RST 的结果而中断策略工作——它只评估"下一根 K 线"的入场边际,不代表对完整策略或多根 K 线持仓行为的裁决。
解读结果:p 值的三档判读与必报指标
原文档给出了明确的判读表:
p_value | 含义 |
|---|---|
< 0.05 | 存在统计显著的"下一根 K 线"入场边际证据 |
0.05 – 0.10 | 边界情况。把数字呈现给用户,标记为尚无定论,可考虑扩大日期窗口或提高n_simulations |
> 0.10 | 没有可靠的"下一根 K 线"入场边际。这不是对完整策略或多根 K 线持仓行为的裁决 |
在 jesse/mcp/tools/significance_test.py 的工具文档字符串中,MCP 层对 > 0.10 的描述更强硬:视为 HARD STOP(与随机无异),不应默默继续完整回测。但永远要把 p 值本身完整、如实汇报给用户,由用户做最终决策。
无论结果如何,都必须向用户报告以下五个指标(这也正是results中保存的全部内容,见SignificanceTestRunner.py的safe_result):
observed_mean—— 规则的下一根 K 线平均对数收益;annualized_return—— 按实际经过的日历时间年化后的收益;p_value—— 显著性;n_simulations—— 实际完成的自助模拟次数;n_observations—— 去 NaN 后参与统计的 K 线数量。
关于annualized_return的实现,可参考 jesse/research/rule_significance_testing/common.py:它通过_elapsed_annualization_factor()用实际时间跨度(observation_count * 365 * 86_400_000 / elapsed_ms)年化,而非推断交易时段。
MCP 工具参考:完整接口清单
RST 通过 Jesse MCP 服务器暴露了 8 个工具(注册逻辑见 jesse/mcp/tools/significance_test.py,其服务实现见 jesse/mcp/tools/services/significance_test.py)。这套工具面刻意镜像了 backtest 的 draft / run / poll 工作流,方便 Agent 复用已知模式。
create_significance_test_draft() —— 创建草稿会话
创建一个可后续运行的草稿会话。参数及默认值(与源码中@mcp.tool()签名一致):
| 参数 | 类型 / 默认值 | 说明 |
|---|---|---|
exchange | str,默认"Binance Perpetual Futures" | 交易所名称 |
routes | JSON 字符串数组,必须恰好包含一个路由对象 | 形如[{"exchange":"...","strategy":"...","symbol":"...","timeframe":"..."}] |
data_routes | JSON 字符串数组,默认"[]" | 纯数据路由,可任意数量 |
start_date,finish_date | YYYY-MM-DD | 检验窗口 |
n_simulations | int,默认2000,建议2000+ | 自助模拟次数,越多 p 值越稳定 |
random_seed | 可选 int | 固定随机种子以保证可复现性 |
title,description | 可选 | 不传则自动生成 |
strategy_summary,hypothesis,rationale | 可选 | 用于填充 Markdown 描述 |
返回值示例:
{ "status": "success", "session_id": "<uuid>", "draft_state": { "form": {...}, "results": {...} }, "notes": { "title": ..., "description": ..., "strategy_code_keys": [...], "strategy_codes_captured": 1 }, "dashboard_url": "...", "message": "Significance test draft created with ID: <uuid>" }源码层面的几个行为值得注意(见services/significance_test.py):
- 草稿会校验
routes/data_routes必须是合法 JSON 数组,且len(routes_list) != 1时直接报错:Rule Significance Test requires exactly one trading route.; - 创建时自动生成标题(
MCP Rule Significance Test: <Strategy> on <Symbol> <Timeframe>)与包含策略、假设、理由、周期、交易所、模拟次数、随机种子等信息的 Markdown 描述; - 创建草稿的同时会从
strategies/<StrategyName>/__init__.py读取策略代码快照(_collect_strategy_codes()),以便后续追溯"当初测试的到底是哪份代码"。
update_significance_test_draft(session_id, state)
用新的 JSON 字符串state整体替换已有草稿的state(表单 + 结果)。采用与update_backtest_draft相同的"读-改-写"模式:
get_significance_test_session(session_id)取出当前状态;- 修改
state.form中需要调整的字段; - 调用
update_significance_test_draft(session_id, json.dumps(current_state))。
update_significance_test_notes(session_id, title?, description?, strategy_codes?)
在检验结束后更新标题 / 描述 / 策略代码快照。典型用途是记录结论,例如:
update_significance_test_notes(sid, description="p_value=0.012 → edge confirmed.")strategy_codes需为 JSON 对象字符串,键为"<exchange>-<symbol>"(源码会对非 dict 的strategy_codes返回错误)。
get_significance_test_session(session_id)
获取会话完整详情,包括status与(完成后的)results。响应结构(原文档示例):
{ "data": { "session": { "id": "<uuid>", "status": "finished", "state": { "form": {...}, "results": {...} }, "results": { "observed_mean": 0.0021, "annualized_return": 0.53, "p_value": 0.012, "n_simulations": 2000, "n_observations": 84 } } }, "error": null, "message": "Significance test session retrieved successfully" }注意会话模型(jesse/models/SignificanceTestSession.py)中除了status、state、results,还包含title、description、strategy_codes、chart_path(检验图 PNG 路径)、exception/traceback(失败诊断)等字段;results存的是 JSON 序列化的安全结果(原始 numpy 数组simulated_means不会入库,见SignificanceTestRunner.py中相关注释)。
get_significance_test_sessions(limit?, offset?, title_search?, status_filter?, date_filter?)
列出会话(最新在前)。limit默认 50,offset分页偏移;title_search对标题做不区分大小写的子串匹配;status_filter取值:draft、running、finished、stopped、terminated;date_filter取值:7_days、30_days、90_days。
run_significance_test(session_id)
触发即返回(fire-and-poll)。服务器接受请求(HTTP 202)时立即返回{ "status": "started", "session_id": ... },然后需要每隔几秒轮询get_significance_test_session直到status == "finished"(或stopped/terminated)。该工具在 MCP 层带有@gated(weight=CREDIT_WEIGHTS["run_significance_test"])装饰器,是 8 个工具中唯一消耗配额的操作(默认权重为 1,可通过环境变量MCP_CREDIT_WEIGHT_SIGNIFICANCE_TEST覆盖,见 jesse/mcp/usage_limits.py)。
启动前服务层会再次校验:会话必须已存在、state.form必须存在、routes必须恰好 1 条;HTTP 409 表示该会话已在运行或已完成,需要新建草稿而不是复用 ID。
cancel_significance_test(session_id)
取消一个正在运行的检验。服务层发送POST /significance-test/cancel,HTTP 202 表示取消请求已被接受。运行器内部通过_raise_if_cancelled()在活动执行路径中检查取消状态并抛出Termination(见SignificanceTestRunner.py)。
purge_significance_test_sessions(days_old?)
删除旧的检验会话。如果省略days_old,将删除全部会话(不可逆)。删除成功后返回deleted_count。
标准工作流:从草稿到结论的完整代码
原文档给出了可直接套用的完整 Python 工作流,在 MCP 环境中可完整运行(结合write_strategy等配套工具):
# 1. 确保候选策略存在于磁盘(strategies/<StrategyName>/__init__.py) write_strategy("RSIOversoldEntry", code=minimal_signal_only_code) # 2. 暂存检验 draft = create_significance_test_draft( exchange="Binance Perpetual Futures", routes='[{"exchange":"Binance Perpetual Futures","strategy":"RSIOversoldEntry","symbol":"BTC-USDT","timeframe":"4h"}]', start_date="2022-01-01", finish_date="2024-01-01", n_simulations=2000, hypothesis="Buying BTC 4h when RSI(14) < 30 produces above-random forward returns.", ) sid = draft["session_id"] # 3. 触发 run_significance_test(sid) # 4. 轮询直到结束 while True: s = get_significance_test_session(sid) status = s["data"]["session"]["status"] if status in ("finished", "stopped", "terminated"): break time.sleep(3) # 5. 检查并记录结论 session = s["data"]["session"] if status == "finished": r = session["results"] edge = "confirmed" if r["p_value"] < 0.05 else "not confirmed" update_significance_test_notes( sid, description=f"p_value={r['p_value']:.3f} → edge {edge}.", )工作流中的每个环节都能在源码中找到对应实现:
- 信号策略只需实现
should_long() / should_short()。测试用例 tests/test_rule_significance_testing.py 中的NoiseSignal与SuperTrendSignal两个策略给出了典型形态:前者发出与价格无关的随机信号(用于检验 H0 下 p 值应偏高),后者用 Jesse 的ta.supertrend()趋势信号做正向对照;两者的go_long() / go_short()均留空——印证了"纯信号、不下单"的执行方式; - 运行期状态流转由 jesse/modes/significance_test_mode/init.py 中的
run()负责:设置significance-test交易模式、router.initiate()、validate_routes()、加载 K 线(含预热 K 线)、实例化SignificanceTestRunner并执行;测试 tests/test_significance_test_session.py 覆盖了会话状态与结果存取逻辑; - 进度与结果呈现:运行器每 0.5 秒节流发布进度条,完成后调用
plot_significance_test()生成主题化(light / dark)的 bootstrap 分布直方图保存到storage/significance-test-charts/(绘图实现见 jesse/research/rule_significance_testing/plots.py),图中以红色阴影标出 ≥ 观测均值的拒绝区域,并标注显著性星级(p ≤ 0.001三星、≤ 0.01二星、≤ 0.05一星、≤ 0.10波浪线、> 0.10打叉)。
约束与常见错误排查
以下是原文档列出的四条硬约束与对应排查方法:
- 必须恰好一条交易路由——控制器(MCP 服务层)与运行器(
significance_test_mode/run()与rule_significance_test())都会拒绝 0 条或多条路由。请检查routesJSON 数组的元素个数; - 策略必须已存在于磁盘——
strategies/<StrategyName>/__init__.py必须存在,否则草稿无法捕获策略代码、运行期路由无法实例化策略。先调用create_strategy()/write_strategy创建策略再创建草稿; - 缺少 K 线——如果日期窗口内没有 K 线,运行器会报错。需要先执行
import_candles(),且建议在start_date前约 2 个月开始导入(用于满足预热 K 线需求;significance_test_mode/run()中关于缺 K 线的错误消息也提示需要start_date之前约warmup_candles_num根预热 K 线)。此外,Jesse 的rule_significance_test()对少于MIN_OBSERVATIONS(30 根)的观测会发出结果可能不可靠的警告(见common.py); - 运行时报 409 冲突——说明该 ID 对应的会话不是 draft 状态(已运行或已完成)。不要复用 ID,直接创建新草稿。
小结
规则显著性检验把"这个信号靠不靠谱"从一个主观问题变成了一个可复现的统计问题:Jesse 通过信号专用回测 + 去漂移 + 平稳自助法给出observed_mean、annualized_return、p_value等硬指标,而 MCP 层则提供了 draft / run / poll / notes 的完整生命周期管理。实践中请记住三条铁律:只在用户要求时运行;p 值大于 0.10 不等于策略无效,但也不应默默当它有效;永远把 p 值、模拟次数与观测数如实呈现给用户。
如需进一步深入,可继续阅读 jesse/research/rule_significance_testing/init.py 下的rule_significance.py(算法入口)、bootstrap.py(自助法实现)、simulator.py(信号回测引擎)以及 tests/test_rule_significance_testing.py(正反对照测试)。
- 金融科技
- 数据分析
- 后端
- AI 应用
【免费下载链接】jesse
An advanced crypto trading bot written in Python
相关推荐
Exiled Exchange 2:流放之路2玩家的智能交易决策助手
Exiled Exchange 2:流放之路2玩家的智能交易决策助手 在《流放之路2》的复杂经济体系中,准确判断物品价值是每个玩家面临的共同挑战。Exiled
Win11DisableRoundedCorners终极指南:如何快速禁用Windows 11窗口圆角
Win11DisableRoundedCorners终极指南:如何快速禁用Windows 11窗口圆角 Win11DisableRoundedCorners是一
操作系统逆向工程vit-pytorch模型验证:统计显著性测试
vit pytorch模型验证:统计显著性测试 引言:为什么需要统计显著性测试? 在深度学习模型开发中,我们经常面临一个关键问题: 模型性能的提升是真实的改进,
人工智能计算机视觉深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考