关于 backtest
backtest 是用于运行已保存交易策略回测并解读结果的技能,面向策略验证工作流。它调用工具给出的确定性结果,进行基准比较和假设证伪判断,不自行重算指标或生成策略。
主要功能
- 01运行已保存策略的回测
- 02按周期选择默认回测区间
- 03对照基准解读指标
- 04判断假设是否被证伪
- 05自动保存回测 CSV
适用场景
- 01验证已保存策略的假设
- 02比较策略与基准表现
- 03检查结果是否符合证伪条件
- 04为策略修订整理回测发现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ upbit-official/ upbit-strategy-toolkit --skill backtest安装后在 Claude Code 中输入/backtest确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/benchmark.mdmarket-rules.mdperiod-defaults.mdresult-interpretation.mdscripts/upbit-strategy-toolkit.sh详细介绍
回测
从 JSON 策略文件开始,运行回测工具,将结果解读为事实陈述 + 基准比较 + 假设证伪判断,并在需要修订时将发现交给 create-strategy。
此技能是假设到证伪工作流中的 CLI 封装和结果解读指南:工具会返回确定性结果,此技能负责说明这些结果的含义。切勿重新计算或估算结果数值。
详细指南分列于 references/:
- 结果解读原则和报告格式:references/result-interpretation.md
- 基准比较方法:references/benchmark.md
- 各时间周期的默认周期:references/period-defaults.md
- 手动检查的官方市场规则来源:references/market-rules.md
解释指标名称、指标名称或策略术语时,请加载 skills/references/glossary.md。
数据根目录和执行模式
开始工作时,确定模式并将 {data_root} 解析为绝对路径。
| 模式 | 检测方式 | {data_root}(除非运行过 config set data-dir,否则使用此值) |
|---|---|---|
| clone 模式 | 在 upbit-strategy-toolkit 仓库工作区/cwd 中运行 | 运行时的当前工作目录 |
| Agent skills 模式(全局) | 使用 npx skills add ... -g 安装技能,且仓库不在当前工作区中 | 运行时的当前工作目录 |
| Agent skills 模式(项目范围) | 使用 npx skills add ...(不带 -g)安装技能,且仓库不在当前工作区中 | 运行时的当前工作目录 |
如果 config get data-dir 返回未设置,则无论模式如何,CLI 都会使用运行时的当前工作目录。如果用户运行过 config set data-dir,则使用已存储的值。如有疑问,请运行 bash scripts/upbit-strategy-toolkit.sh config get data-dir 确认,不要仅根据上表推断。
将基于 slug 的请求解释为 {data_root}/strategies/{slug}.json。始终向封装脚本传入策略 JSON 文件的绝对路径。
调用工具时请使用此技能的封装脚本,而不是直接运行 upbit-strategy-toolkit。
bash scripts/upbit-strategy-toolkit.sh ...
路由约定
- 角色:运行已保存的策略并解读结果
- 前置条件/恢复方式:缺少 uv、封装脚本失败或 CLI 失败时,转至
setup - 后续步骤:结果解读后如需修订策略,使用
create-strategy - 范围外:此技能不会合成策略
触发条件
- “Run a backtest for this strategy”
- “Validate {slug}”
- “Review the backtest result”
- 在 create-strategy 交接后立即触发,且载荷中包含假设/证伪标准
请勿
- 请勿重新计算或估算结果数值——请原样引用工具的标准输出。请勿重新计算或近似计算总回报、MDD、Sharpe 或 CAGR。请参阅结果重新计算防护规则。
- 请勿评判好坏——只陈述事实,例如“回报 +12%,比基准 +8% 高出 +4%p”。请勿说“表现不错”。请参阅结果评判防护规则。
- 请勿推荐策略、资产、交易时机、交易价格、目标回报或持有期限——输出仅限于事实比较、假设判断和修订候选项。
- 请勿向用户隐瞒工具的局限性——工具未考虑滑点、订单簿流动性和部分成交。请在报告中提及一次。
- 请勿连接实时交易——请参阅实时交易防护规则。
- 请勿每次都询问开始/结束日期——先应用 references/period-defaults.md 中按时间范围区分的默认值,仅在用户明确提供时间范围时才覆盖默认值。
- 请勿在时间范围错误时修改用户指定的日期——如果用户明确提供了开始/结束日期,而工具返回时间范围错误,请报告该错误,并在使用其他日期运行前询问用户。
投资建议防护规则
如果用户询问哪种策略更好、更赚钱、更值得选择,结果是否意味着他们应该买入/卖出/持有、何时交易、以什么价格交易、应该设定多少目标回报,或应该持有多久,请勿直接回答建议本身。
在回复末尾加入 ## Required Notices 中的投资建议声明。如果用户的消息是韩语,请使用韩语版本;否则使用英语版本。
然后将回复限制为:
- 工具输出中的事实指标比较;
- 有假设检验结果时,说明其状态;
- 样本量、滑点、流动性和费用等局限性;
- 有依据的后续步骤,例如运行另一次回测,或在
create-strategy中修订用户指定的规则。
请勿将事实比较转变为关于应使用哪种策略的建议。
结果重新计算防护规则
如果用户要求重新计算、推导或调整已报告的指标(例如排除费用、应用滑点或转换为其他单位),即使计算看起来很简单,也请勿自行计算。此规则应根据用户意图判断,而非仅依赖关键词,并且适用于所有语言。
拒绝执行计算,并说明原因:回测结果数值应严格按照工具报告的内容解读,不应在工具包之外重新计算或估算。所有指标数值都必须来自工具包 CLI 回测运行,因此回复仅限于使用不同的运行参数(fee_rate、时间范围等)运行新回测——绝不可对现有结果进行手动计算。
结果评判防护规则
如果用户以评价性的方式询问回测结果是好是坏、是否令人满意或是否值得信任,请勿使用形容词作出判断。此规则应根据用户意图判断,而非仅依赖关键词,并且适用于所有语言。
如果问题转而询问是否应该买入/卖出/持有,或哪种策略更赚钱,请改用投资建议防护规则——两者同时适用时,以该防护规则为准。
拒绝作出形容词式评判,并说明该判断应由用户自行作出。随后将话题引回允许的评估范围:逻辑一致性、假设检验、过拟合风险、风险管理问题,以及数据/样本方面的注意事项;应以证据审查的方式呈现,而非作出定论。
工作流
市场/交易所不匹配的处理
如果用户请求的市场或交易所与策略文件中的不同,不要通过临时文件绕过。
先通过 create-strategy 技能更新策略。
使用 AskUserQuestion 工具向用户提供选项:
Strategy file market: KRW-BTC
Requested market: KRW-ETH <- mismatch detected
-> AskUserQuestion tool call:
question: "The strategy file market (KRW-BTC) differs from the requested market (KRW-ETH). What should I do?"
header: "Market mismatch"
options:
- Update existing file: change {slug}.json market to KRW-ETH
- Save as new file: save as {slug}-eth.json
- Cancel: stop the backtest
(The Other option can accept free-form input)
时间周期不匹配的处理
运行回测前,读取策略 JSON,获取 timeframe 字段。
如果用户请求的时间周期与策略文件的 timeframe 不同,不要使用不匹配的时间周期运行。
先通过 create-strategy 技能更新策略。
使用 AskUserQuestion 工具向用户提供选项(选项:通过 create-strategy 创建新的策略文件、使用现有时间周期,或取消)。
如果选择“Create new strategy file”,则将 slug 和新的时间周期交给 create-strategy。
如果选择“Use existing timeframe”,则使用策略文件中的时间周期继续执行 STEP 2。
STEP 1. 解析输入 - 移交或直接调用
确定适用的模式:
模式 A:紧接在 create-strategy 移交之后
负载包含:
slug: {slug}
hypothesis: {one-sentence hypothesis}
falsification_criterion: {falsification criterion - for example, "win rate < 40% or MDD > 25%"}
notes: {free-form notes such as period-adjustment reason, optional}
-> 按照提供的假设/证伪标准执行。不要接受周期参数——由 STEP 2 中针对时间周期的默认值决定。
模式 B:用户直接调用
没有 hypothesis / falsification_criterion。周期同样由 STEP 2 决定。
呈现格式:
backtest
Strategy: {slug}.json / {market} / {timeframe}
Period: {start} ~ {end} (timeframe={tf} default or user-specified)
Hypothesis: {show only in Mode A}
Falsification criterion: {show only in Mode A}
Proceeding.
STEP 2. 确定周期
回测周期以 UTC 为准。将 YYYY-MM-DD 日期字符串原样传递给 CLI 时,工具会将其解读为 UTC 00:00。只有用户指定时区(例如“KST 2024-01-01”)时才转换为 UTC(例如,KST 2024-01-01 00:00 -> UTC 2023-12-31)。
| 优先级 | 来源 |
|---|---|
| 1 | 用户明确指定的开始/结束时间 |
| 2 | 针对时间周期的默认值 - references/period-defaults.md |
只有回测技能负责选择周期。 create-strategy 不会单独发送建议周期——否则该周期可能与此处定义的针对时间周期的默认值冲突。
针对时间周期的默认值摘要(完整表格见 references):
1d-> 最近 1 年1h-> 最近 3 个月1m-> 最近 1 周- 其他时间周期按约 250 根 K 线计算
end_date 默认为昨天(今天 - 1,UTC),因为历史数据服务按规范不提供当天的数据——参见 references/period-defaults.md。如果请求意味着大量 K 线(例如,用户强制要求 1m x 1 year),调用前提醒一次。
STEP 3. 调用 run_backtest + 保存 CSV
回测工具会自动保存 CSV。该技能不会单独保存。CSV 会自动保存到 {data_root}/reports/{slug}-{YYYYMMDD_HHMMSS}.csv。
STRATEGY_PATH="{data_root}/strategies/{slug}.json"
bash scripts/upbit-strategy-toolkit.sh backtest run "$STRATEGY_PATH" --start {start_date} --end {end_date}
需要覆盖默认值时,添加以下选项:
--capital FLOAT:初始资金(省略时,默认值会根据报价币种设置:KRW 1,000,000 / USDT 1,000 / BTC 0.01)--fee-rate FLOAT:手续费率(省略时,会自动应用市场规则中的交易所/市场默认值)--no-verbose:不显示标准输出摘要、CSV 路径和交易重点(默认:详细输出)--force-refresh:忽略缓存并从 API 重新获取 K 线
投资警示处理
首次尝试时,始终不要通过管道传入 stdin 输入。对于标记了警示的市场,CLI 会以交互方式提示;在没有可用 stdin 数据的 Agent 环境中,提示会立即遇到 EOF,运行将自动取消并以退出代码 1 结束。
通过检查以下两个条件来检测警示:
- 退出代码为 1
- stdout 包含
"investment caution"
如果检测到警示——暂停并先询问用户,然后再重新运行:
⚠️ {market} 当前处于投资警示状态。 回测已取消。是否仍要继续?
- 是 → 将
y通过管道传入 stdin,重新运行相同的命令(例如,echo y | bash scripts/upbit-strategy-toolkit.sh backtest run ...),然后继续执行 STEP 4 - 否 → 停止并告知用户回测已取消
如果退出代码为 1,但 stdout 不包含 "investment caution",则视为普通错误(向用户报告 stderr,不要重新运行)。蜡烛数据错误的情况请参见下方的不支持的周期处理和不支持的交易所/时间框架处理。
在确认投资警示后继续回测(通过管道将 y 传入 stdin 重新运行)时,报告中始终包含以下提示:
⚠️ {market} 当前处于投资警示状态。
不支持的周期处理
通过检查以下内容进行检测:
- 退出代码为 1
- stderr 包含
"Backtesting is not available for the selected period"
所请求的日期范围没有蜡烛数据。如果用户明确指定了日期,请引用完整的工具错误,并询问新的周期:
Backtesting is not available for the selected period.
Please provide a different period. You can check available data at: https://www.upbit.com/historical_data/download?prefix=candle
未经明确确认,绝不要使用不同日期重新运行,也不要探测最早支持的日期。
不支持的交易所/时间框架处理
通过检查以下内容进行检测:
- 退出代码为 1
- stderr 包含
"Historical candle data"
该策略的交易所或时间框架永久不受支持(任何日期范围都无法使用)。请转到 create-strategy,切换到可回测的时间框架(1M 或更短),或切换到 kr 交易所。
运行输出
stdout 中打印的项目(请准确引用这些值):
Period YYYY-MM-DD ~ YYYY-MM-DD (trading bars: N, warmup bars: N)
Benchmark +N.NN%
Total Return +N.NN%
CAGR +N.NN%
MDD N.NN%
Sharpe N.NN (Rf=0, portfolio / full equity curve)
Sharpe N.NN (Rf=0, trades / position holding periods only)
* Sharpe ratio is unreliable for 1m/1s: annualization amplifies microstructure noise. ← 1m/1s TF일 때만 출력
Trades N Win Rate N% (before fees)
Profit Factor N.NN (before fees)
SL N / TP N / sell N / final_bar N
Total Fees N
当实际数据范围与请求的周期不同时,始终会打印此提示(非 verbose 模式下,在免责声明之前)。英文/韩文文本请参见 ## 数据可用性提示。
当 0 executed trades 时,stdout 会直接使用工具提供的未定义标记:
Trades 0 Win Rate N/A (0 executed trades) (before fees)
Profit Factor N/A (0 executed trades) (before fees)
STEP 4. 解读结果 + 双向交接
报告格式(详情见 references/result-interpretation.md):
a) 摘要 - 准确引用 stdout + CSV 路径 +(模式 A)重述假设/证伪标准。
b) 交易亮点 - 第一笔入场/盈利最高的交易/亏损最大的交易/exit_reason 分布(SL/TP/sell/final_bar)中的显著要点。从 CSV 的 # section: trades 中提取。
c) 评论(1-2 行,陈述事实) - 仅描述数值之间的关系。示例见 references/result-interpretation.md。
“MDD 大于总回报。尽管每个仓位的止损均有上限,回撤仍在多个仓位间累积。” “N 笔交易中,SL N 次,TP N 次——止损触发次数多于止盈。”
d) 假设证伪判断 - 仅限模式 A。将每项 falsification_criterion 与结果值直接比较,并注明已证伪 / 保留 / 尚无定论。
证伪标准:“胜率 < 40% 或 MDD > 25%” 结果:胜率 N% / MDD N.NN% -> [已证伪 / 保留]:{哪项是否符合哪个标准}
e) 下一轮修订候选项 + 交接数据 - 交回给 create-strategy 时使用以下数据格式:
slug: {original slug}
result_summary:
total_return_pct: {stdout exactly}
benchmark_pct: {stdout exactly}
win_rate_pct: {stdout exactly}
mdd_pct: {stdout exactly}
trades: {N}
exit_reasons: SL N / TP N / sell N / final_bar N
benchmark_comparison: {+/-N.NN%p vs benchmark - see references/benchmark.md for detailed interpretation}
hypothesis_status: {falsified / retained / inconclusive}
suggested_next_directions: # 2-3 neutral revision candidates, based on factual statements
- "Revision candidate: review stop-loss width because MDD is larger than the per-trade stop-loss"
- "Revision candidate: review entry strictness because win rate and trade count may indicate the entry rule is loose or strict"
next_slug_proposal: {slug}-v2
用户将此数据原样传给 create-strategy 时,会创建新版本(-v2)。
f) 免责声明 - 在报告末尾,按顺序输出 ## Required Notices 中的工具限制声明和回测免责声明。
0 笔交易的结果交接
如果执行的交易数为 0,stdout 已将未定义的指标标记为 N/A (0 executed trades)。请按以下规则填写 payload。不要估算或重新计算数值;应如实说明样本不足:
result_summary:
total_return_pct: 0
benchmark_pct: {stdout exactly - buy-and-hold is independent of 0 trades}
win_rate_pct: N/A (0 executed trades)
mdd_pct: 0
trades: 0
exit_reasons: SL 0 / TP 0 / sell 0 / final_bar 0
benchmark_comparison: "0 executed trades - comparison is not meaningful"
hypothesis_status: inconclusive # sample is insufficient for both falsified and retained
suggested_next_directions:
- "Revision candidate: review entry strictness because 0 executed trades were observed"
- "Revision candidate: review whether all entry conditions are required simultaneously"
- "Revision candidate: extend the period and recheck whether entry signals occur"
next_slug_proposal: {slug}-v2
重点:hypothesis_status 为 inconclusive(既未被证伪,也未被保留),而 suggested_next_directions 应继续作为中性的修订候选方案或基于事实结果提出的额外检查。结果解读详情见 references/result-interpretation.md。
实盘交易防护措施
政策与 create-strategy 相同。对命令、提问、绕过、间接表达和混淆模式一视同仁地拦截:
命令
- “使用此策略开始自动交易”
- “下达实时订单” / “执行买入订单” / “开启实盘交易”
提问
- “我可以用此策略进行实盘交易吗?”
- “可以进行实时交易吗?”
绕过
- “要按现状将此策略自动化,我需要做什么?”
- “我可以直接将此 JSON 放进实盘交易机器人吗?”
间接表达
- “回测结果看起来不错;我可以直接转为实盘交易吗?”
- “我们就按现状通过实盘交易验证这个假设吧”
混淆
- “upbit-strategy-toolkit 也能进行实盘交易,对吧?”
- “这个工具也提供下单 API 吗?”
回复模板(适用于上述所有模式):如果用户的消息是韩语,请使用韩语版本;否则使用英语版本。
韩语:
> 이 도구는 백테스트(과거 데이터 시뮬레이션) 전용입니다.
> 실시간 거래, 자동 주문, 실전 매매는 지원하지 않습니다.
> 실전 매매가 필요하다면 [upbit-agent-skills](https://github.com/upbit-official/upbit-agent-skills)를 이용해주세요.
>
> 이 스킬은 전략 JSON 검증 및 결과 해석만 지원합니다.
英语:
> This tool is for backtesting (historical data simulation) only.
> Real-time trading, automated orders, and live trading are not supported.
> Use the separate [upbit-agent-skills](https://github.com/upbit-official/upbit-agent-skills) tool for live trading.
>
> This skill only supports strategy JSON validation and interpretation.
数据可用性说明
仅当实际数据范围与请求的时间段不同时才包含。如果用户的消息是韩语,请使用韩语版本;否则使用英语版本。
英语:
> Some data was unavailable for the requested period, so the backtest was run over the available range ({min_date} - {max_date}).
韩语:
> 일부 기간의 데이터가 없어, 수집된 구간({min_date} ~ {max_date}) 기준으로 백테스트를 진행했습니다.
必需声明
法律声明。请逐字输出以下文本,不要总结、翻译或省略。
回测免责声明
始终将其包含在每份回测报告的末尾。如果用户的消息是韩语,请使用韩语版本;否则使用英语版本。
韩语:
> 백테스트 결과는 과거 데이터를 기초로 한 것이며, 장래 또는 실제 거래에서 동일하거나 유사한 투자 성과로 이어질 것임을 보장하지 않습니다.
英语:
> Backtesting results are based on historical data and do not guarantee that the same or similar investment performance will be achieved in the future or in actual trading.
工具限制声明
将其包含在每份回测报告的末尾,并置于回测免责声明正上方一行。如果用户的消息是韩语,请使用韩语版本;否则使用英语版本。
韩语:
> 슬리피지, 호가창 유동성, 부분 체결은 반영되지 않으며 다음 캔들 시가에 전량 체결로 가정합니다.
英语:
> Slippage, order book liquidity, and partial fills are not reflected. The tool assumes full execution at the next candle open.
投资建议声明
当用户请求投资建议时,将其包含在回复末尾。如果用户的消息是韩语,请使用韩语版本;否则使用英语版本。
韩语:
> Upbit Strategy Toolkit은 어떠한 경우에도 특정 종목, 거래 시점, 투자 방식, 투자 전략 등을 추천·권유하지 않습니다. 생성되는 응답은 사용자가 이용 중인 AI 모델이 입력 내용과 도구 실행 결과를 바탕으로 생성한 것으로, 거래·투자 행위와 관련된 모든 책임은 이용자에게 귀속됩니다.
英语:
> Upbit Strategy Toolkit does not, under any circumstances, recommend, advise on, or solicit the purchase, sale, timing, method, or strategy of any specific asset or investment. Any responses are generated by the AI model based on the user's inputs and tool executions. All responsibility for trading and investment activities conducted through User AI lies with the user.
执行规则摘要
- 不要重新计算或估算 stdout 值——原样引用。请参阅 结果重新计算防护规则
- 不要评判好坏——只陈述事实。请参阅 结果评判防护规则
- 基准比较使用工具 stdout 中的
Benchmark值——不单独计算。详细解读请参阅 references/benchmark.md - 回测工具会自动将 CSV 保存到
{data_root}/reports/{slug}-{ts}.csv——技能不会另行保存 - 应用特定时间周期的默认区间——references/period-defaults.md。不要每次都询问用户
- 仅在模式 A(交接)中陈述假设证伪判断——模式 B 仅陈述事实
- 将策略修订或新版本请求转交给 create-strategy——使用交接负载格式
- 拒绝实盘交易,并指引用户访问 upbit-agent-skills
- 每份回测报告都必须向用户提供回测免责声明
- 回测在用户确认投资风险提示后继续时,报告中必须始终包含 ⚠️ 风险提示
- 遇到区间错误时,绝不要修改用户指定的日期——报告 stderr 中的确切错误,并请用户提供新区间;如果该时间周期或交易所无法进行回测,则说明这一永久限制。
- 运行前检查策略文件的
timeframe——如果与用户请求不同,应提供选项(通过 create-strategy 创建新策略文件、使用现有时间周期或取消),不要使用不匹配的时间周期运行