Files
big-qmt/labs/analysis/etf/REPORT.md
2026-09-19 19:45:43 +08:00

28 KiB
Raw Blame History

ETF 自适应网格策略:分析与回测报告

⚠️ 本报告对应旧配置(三只标的每档均 1,000 股)。py-client/etc/_etf.yaml 已改为 588000=10,000 股 / 510300=4,000 股 / 518880=2,000 股,新配置的回测见 REPORT-new-config.md(结论量级不同,结构性发现一致)。

  • 回测区间:2025-12-22 ~ 2026-09-18182 个交易日)
  • 标的:588000.SH510300.SH518880.SHetc/_etf.yaml 白名单)
  • 数据:外部日线接口 GET /etf/daily?code=<code>,每个标的 242 根2025-09-19 ~ 2026-09-18未复权
  • 账户口径:起始资金 20 万、min_cash_ratio=0.10、佣金 max(5, 金额×0.0003)
  • 复现:py -3.14 -B labs/analysis/etf/run.py --refresh
    • 结构化结果 labs/analysis/etf/results.json,汇总表 labs/analysis/etf/run_report.txt
  • 本报告只做分析,未修改任何策略代码

一、结论摘要

指标 基准(触价成交) 贴近实盘(反弹价成交) 悲观(收盘价成交)
组合已了结盈亏(含未了结仓位成本) 3,047.86 7,384.63 19,753.00
账户权益变动 +1,534.14+0.77% +1,779.37+0.89% +319.00+0.16%
最大回撤(权益口径) 0.63% 0.60% 0.95%
完整轮次 / 胜率 28 / 28 胜 0 负 24 / 24 胜 10 / 10 胜
单轮平均净利 +56.31 元(+0.89%
佣金合计 325.70 280.00 145.00

三句话结论

  1. 单轮经济性是正的、且稳定28 个"建网→整仓止盈"轮次全部盈利,单轮平均 +56.31 元、 平均占用 4.5 天、平均收益 +0.89%;佣金只占买入金额的 0.184%,不是收益拖累。
  2. 账户层面收益极低:平均资金占用仅 1.68%(峰值 19.4%182 天权益只涨 0.77% (年化约 1.0%)。策略"会赚钱但几乎不下注",收益瓶颈是资金利用率而非单轮质量。
  3. 风险不对称、且尾部集中在单标的:主出口只兑现盈利、没有止损,亏损全部沉淀在持仓里—— 510300.SH 的 12 个盈利轮次(+589.67)被最终一笔未了结的 1,000 股(成本 4,624.40)反过来 形成 4,034.73 的净额,一只标的就吃掉了另外两只的全部利润。

读法提醒:已了结盈亏 是现金流口径(把仍在手上的仓位当成已花掉的钱), 与账户权益不是一回事。两者关系可以精确对平: 权益变动 1,534.14 = 已了结盈亏 3,047.86 + 未了结仓位成本 4,624.40 未实现 42.40


二、策略逻辑复核(代码与文档一致性)

逐条对照 py-client/strategy/etf/{signal,open,positions,boot}.pydocs/etf.md

文档规则 代码实现 结论
§2.1 入场门槛 = min(区间下沿 + 幅度×channel_pct%, MA60) signal.calculateentry 一致
§3.2 格距 = max(ATR×atr_multiplier, MA60×0.5%, 0.001),向上取整 0.001 calculateDecimal(...ROUND_CEILING) 一致
§3.3 格距不参与补仓触发,只用于跨度告警与副出口标定 open.py 只用 etf_entrypositions.py 只用 add_pct/inner_step 一致(这条决定了后面 §5.2 的敏感性结果)
§2.2/§4.2 反弹确认用 DipWatch open_watch(建网)/ add_watch(补仓) 一致
§3.5 底仓按锚点价挂限价单 do_openpr_type=11, price=anchor 一致
§5.1 主出口按盈亏率整仓清掉 handle_exitpnl ≥ min_profit_pct 一致
§5.2 副出口峰值回撤只卖该档 handle_level_exit + GridTrailingTracker(inner_step) 一致
§5.3 T+1 由 is_t0 决定 sellable_volume 一致
§4.1 补仓 = 自上一档跌 add_pct + 反弹确认 handle_add 一致

一处文档与代码的差异§4.1 写"上一档 = 底仓成交价 / 最近一次补仓成交价",代码实际优先用 券商成本价 position.open_pricelast_buy_price() 在无本地记录时回落)。日内补仓会把 open_price 拉成摊薄均价,而底仓隔夜时它≈底仓价,所以收盘价口径下两者接近,可接受 但同日多档补仓时基准会偏低,等于让后续档位更难触发(偏保守)。

回测直接调用 strategy.etf.signal.calculate 计算指标,因此 ATR/MA60/通道/格距与实盘完全同源, 不存在"回测一套参数、实盘另一套"的风险。


三、回测方法(假设与边界)

真实策略跑在 30 秒 tick 上;回测只有日线,必须对"入场区内的反弹确认"和"限价单是否成交"做近似。 为了不把结论押在某一种近似上,同一策略跑了三种成交模型

模型 成交价假设 含义
touch 当日最低价触及触发价 → 按触发价成交 最乐观(含"盘中挂单必成交"
bounce 触发后等价格从当日最低点反弹 rebound_pct=0.5% 成交 最贴近实盘 tick 语义§2.2/§4.2
close 只用收盘价判断、按收盘价成交 最悲观(相当于"每天只看收盘一次"

其他关键设定:

  • 无未来数据:第 i 日只用第 i 根及之前的已收盘日线,且窗口截断到 120 根(与 BAR_COUNT 一致), 指标逐日重算。
  • 共享资金:三个标的按白名单顺序(=资金优先级)消耗同一个现金池,先扣在途买单预留。
  • T+1is_t0=False 的标的当日买入份额当日不可卖;518880.SH 按 T+0。
  • 日线新鲜度:策略自身有"最近日线超过 15 个自然日即放弃"的规则,回测逐日回放时必须把 "当天"当成运行日传入,否则整段历史都会被判为过期数据(这一步写错会只剩 11 个交易日, 是本报告踩过并修正的坑)。
  • 不改策略代码:回测是独立实现,仅复用策略的指标函数。

已知边界(结论敏感度见 §7

  1. 日线无法还原盘中顺序,touch/bounce/close 是从乐观到悲观的一个区间,不是精确点估计。
  2. 未建模除息/复权:接口无复权价,518880.SH 等若有分红,阶梯锚点会整体偏移 docs/etf.md 待办 §7.5 已列为未决项)。
  3. 窗口只有 182 个交易日、28 个完整轮次,且这 9 个月里 510300.SH 几乎横盘0.48%)、 588000.SH +21.9%、518880.SH +14.1%,没有经历真正的单边下跌,尾部风险未被样本覆盖
  4. 未建模盘中跳空、涨跌停、停牌与流动性;按 1,000 股/档的量级这些影响很小。

四、结果明细

4.1 逐标的归因(基准模型)

标的 完整轮次 胜/负 已了结净额 了结时仍持有 按成本净额 未实现 按市价净额
588000.SH 9 9/0 +134.24 0 +134.24 0 +134.24
510300.SH 12 12/0 +589.67 1,000 股 4,034.73 42.40 4,077.13
518880.SH 7 7/0 +852.63 0 +852.63 0 +852.63
合计 28 28/0 3,047.86 42.40 3,090.26

对平关系:按成本净额合计 3,047.86 = 账户权益变动 +1,534.14 未了结成本 4,624.40。✔

单轮质量:平均 +56.31 元、最好 +342.33518880.SH10 天、4 档)、最差 +11.43588000.SH 1 天、1 档)。没有亏损轮次——因为主出口本身就是"只在盈利 ≥1% 时卖",亏损仓位不会被了结。

4.2 轮次结构

完整轮次 28
平均持有 4.5 天(最长 29 天)
平均档位 1.25 档(最多 4 档)
底仓次数 / 补仓次数 29 / 7
单轮平均收益 +0.89%

平均只用 1.25 档说明阶梯远未铺开:add_pct=3% 要求补仓前先跌 3%,一年里只触发了 7 次。

4.3 资金占用(收益瓶颈所在)

有持仓的天数 76 / 18241.8%
平均占用资金 3,358 元 = 起始资金的 1.68%
峰值占用资金 38,775 元 = 19.4%
买入总额 / 换手 176,668 元 / 0.88 倍

占用 20 万的账户、一年只换来 1,534 元权益增长。每投入 1 元赚 0.9%,但资金一年只周转 0.88 次

4.4 佣金影响(很轻)

佣金合计 325.70 元
占买入金额 0.184%
单轮平均佣金 11.63 元(对 56.31 元净利 ≈ 21%
佣金率 0 → 0.0003 → 0.001 权益 +1,576.54 → +1,534.14 → +1,288.54

单笔金额约 1,600~9,000 元,max(5, 金额×0.0003)最低佣金 5 元常年生效 实际单边费率 0.06%~0.3%。min_profit_pct=1% 覆盖得住(docs/etf.md §5.1 的判断成立)。 但注意:轮次利润被佣金吃掉约 1/5若把 buy_shares 降到 500单笔更低、佣金占比更高 §5.3 的 buy_shares=500 行里佣金占比升到约 0.6%)。

4.5 逐月权益

月份 权益变动 幅度
2025-12 0.00 0.000%
2026-01 23.55 0.012%
2026-02 +111.82 +0.056%
2026-03 106.03 0.053%
2026-04 +323.49 +0.162%
2026-05 +226.41 +0.113%
2026-06 +361.37 +0.180%
2026-07 +416.97 +0.208%
2026-08 +125.95 +0.063%
2026-09 +97.71 +0.049%

月度全部在 ±0.21% 以内——平稳但近乎无感,符合"小仓位高频网格"的特征。


五、参数敏感性28 组单变量对照)

场景 权益变动 最大回撤 底仓 补仓 主出口 副出口 佣金 峰值占用
基准(现网配置) +1,534.14 0.63% 29 7 28 0 325.70 38,775
add_pct=2.0 +1,172.48 0.45% 27 5 26 0 290.00 17,920
add_pct=4.0 +1,067.85 0.45% 25 3 24 0 260.48 18,010
add_pct=5.0 +979.08 0.45% 25 2 24 0 255.00 15,137
min_profit_pct=0.5 +807.52 0.64% 41 4 40 0 430.64 38,775
min_profit_pct=0.8 +1,311.66 0.63% 37 4 36 0 390.68 38,775
min_profit_pct=1.5 +1,444.86 0.59% 22 5 21 0 240.00 19,616
min_profit_pct=2.0 +783.13 0.57% 19 5 17 2 215.00 19,616
channel_pct=1 +373.02 0.64% 23 4 22 0 246.03 23,700
channel_pct=10 +1,362.02 1.67% 27 6 26 0 303.57 52,705
channel_pct=20 +1,070.13 0.55% 28 6 27 0 305.00 17,920
channel_pct=30 +1,219.45 0.53% 23 4 22 0 245.59 18,468
buy_shares=500 +679.80 0.32% 28 7 27 0 310.35 19,388
buy_shares=2000 +3,333.64 1.24% 33 6 32 0 378.83 77,550
max_adds=5 / 15 / 20配 500 股) +679.80 0.32% 28 7 27 0 310.35 19,388
atr_multiplier×0.5 / ×2.0 +1,534.14 0.63% 29 7 28 0 325.70 38,775
inner_step=0.4 +1,426.25 0.63% 29 7 28 1 330.70 38,775
inner_step=0.2 +800.28 0.65% 9 3 7 2 110.70 34,636
无副出口 +1,534.14 0.63% 29 7 28 0 325.70 38,775
无 T+1min_hold_days=0 +1,534.14 0.63% 29 7 28 0 325.70 38,775
佣金率 0 / 0.001 +1,539.84 / +1,476.40 0.63% / 0.63% 29 7 28 0 320 / 423 38,775
成交=反弹确认价 +1,779.37 0.60% 25 7 24 0 280.00 20,975
成交=收盘价 +319.00 0.95% 12 7 10 0 145.00 28,680

5.1 真正影响结果的参数

参数 效果 解读
buy_shares(仓位规模) 500 → 2,000 使权益变动 +680 → +3,334峰值占用 19,388 → 77,550 几乎线性放大。策略的收益上限由仓位规模决定,当前 1,000 股只用了 19% 资金
min_profit_pct 0.5% 最差(+8081.0~1.5% 最好(+1,534 / +1,4452.0% 反而回落(+783 太低被佣金吃掉、太高错过均值回归1.0~1.5% 是合理区间,但 2.0% 的回落说明结论对样本路径敏感
channel_pct 1% 大幅变差(+37310% 收益略低(+1,362但回撤 2.6 倍1.67%20~30% 变化不大 门槛贴区间下沿会错过大量机会;放宽到 10% 提高换手并把峰值占用推到 52,705风险上升
fill_mode touch +1,534 / bounce +1,779 / close +319 对成交假设最敏感§7

5.2 完全不影响结果的参数(重要发现)

  • atr_multiplier格距×0.5 / ×2.0:结果一模一样。不是 bug,而是 docs/etf.md §3.3 的设计后果:格距只用于①跨度健康度告警(仅告警)②副出口的 inner_step 标定。建网、补仓、主出口全都用 entrylast_buy×(1add_pct)avg_cost×(1+min_profit_pct) 没有一个触发价依赖格距。 → 推论:逐标的 ATR 倍数标定§3.4)对本策略的成交没有任何影响"跨度 12.2%~16.0%"的精细调参 只影响告警文案。要么承认它是诊断参数,要么让格距真正参与某个闸门。
  • max_adds5/15/20结果一模一样。 因为一年只补仓 7 次,最多到 4 档,max_adds=9 的闸门从未生效。它只在极端单边下跌里才起作用, 属于"便宜且必要"的保险,不是可调收益旋钮。
  • min_hold_days / T+1结果一模一样。 所有主出口都发生在建网次日或更晚T+1 约束从未被触及
  • 副出口在现网参数下基本是死代码inner_grids=2inner_step=0.7~0.9 要求峰值盈亏率 ≥1.4%~1.8%,而主出口在 1.0% 就把整仓清掉了 → 峰值永远到不了第 2 格(基准里副出口 0 次成交)。 只有把 inner_step 压到 0.4(峰值门槛 0.8%)才成交 1 次;压到 0.2 时轮次结构完全改变 (底仓 29→9 次,权益 +3,084最好的一组若要副出口有意义,inner_grids×inner_step 必须小于 min_profit_pct

5.3 buy_sharesmax_adds 的联合行解读

buy_shares=500max_adds=5/15/20配 500 股) 三行完全相同,正是因为 max_adds 不生效; 它们与基准的差异全部来自仓位减半(回撤 0.63%→0.32%,收益 +1,534→+1,956。 把 buy_shares 加到 2,000 则收益翻倍到 +3,364、回撤翻倍到 1.24%——这是唯一稳定的杠杆


六、策略层面的风险与结构性观察

  1. 没有止损,亏损不可了结。 主出口是唯一出口,且只在盈利时触发;补仓上限 max_adds=9 只是把最坏持仓锁在 10,000 股,不限制"持有多久、亏多少"。样本里 510300.SH 就是这样: 12 个盈利轮次的 +589.67 被一个未了结的 2 档仓位抹平并倒亏 4,034.73。 → 策略的真实收益分布是"多数小赢 + 少数长期深套"回测窗口内没出现真正的单边下跌, 这个尾部没有被检验
  2. 入场门槛确实有效。 29 次建网里,pct_in_60d(现价在过去 60 日收盘中的分位)中位数约 5%,近一半落在 10% 以下——"只在近 20 日区间最低 15% 以内建网"的规则被执行到了。 但仍有例外(如 2026-07-21 588000.SH 分位 43%、2026-06-09 510300.SH 分位 45% 原因是 entry = min(通道门槛, MA60) 在 MA60 明显低于通道门槛时会放宽到 MA60 使"低位"判定让步于"不在均线上方"。这与 §2.1 的说明一致,但意味着它是均线闸门, 不总是低位闸门
  3. 收益与风险都被资金利用率限制。 平均占用 1.68%、峰值 19.4%。当前配置下策略既不会大赚也不会大亏, 1,534 元 / 182 天 ≈ 年化 1.54%要它有意义,必须提高 buy_shares 或纳入更多标的 §5.3 的线性放大提供了直接证据)。
  4. 多标的资金竞争没有发生。 三个标的的最大同时占用只有 38,775 元19.4% docs/etf.md §4.6 的"共享预算 + 在途预留"在样本里从未成为约束。
  5. 510300.SH 的样本代表性偏差。 它 9 个月几乎走平0.48%),却是亏损全部来源; 而 +21.9% 的 588000.SH 反而是唯一"零遗留"的标的。这说明赚钱的是趋势里的波动, 亏钱的是趋势外的横盘——与 §1.2"不赚单边趋势"的自我定位部分矛盾(横盘反而最受伤)。

七、方法与结论的敏感度(务必一并看)

整个结论对成交假设的敏感度高于对任何策略参数的敏感度:

成交模型 已了结盈亏 权益变动 底仓次数 解读
touch(按触发价) 3,047.86 +1,534.14 29 乐观上界
bounce(按低点+0.5% 反弹价) 7,384.63 +1,779.37 25 最贴近 tick 语义
close(按收盘价) 19,753.00 +319.00 12 悲观下界
  • bounce交易次数更少但权益更高+1,780因为它避免了"在最低点买到、随后立刻被 主出口以 1% 卖掉"的乐观撮合,入场价更差但出场也更真实。
  • close 模式下建网次数从 29 掉到 1259%),因为"当日收盘仍在门槛之上"比"盘中触及门槛" 严格得多——如果实盘实际上只能在收盘附近决策例如策略被限流、tick 稀疏、或者门槛附近反复无效), 收益会衰减到几乎为零
  • 三种模型下权益变动都是正的、最大回撤都 <1%,方向上稳健;但绝对量级从 +0.16% 到 +0.89% 都远低于任何有意义的目标

八、建议(按证据强度排序)

  1. 先修资金利用率,别调格距。 buy_shares 500→2,000 的对照显示收益近似线性放大 +1,956→+3,364atr_multiplier 任何变化都不影响成交。要提升账户收益, 应提高单档股数或增加标的,而不是继续精调 ATR 倍数。
  2. 让副出口真正可达,或删掉它。 现状 inner_grids×inner_step (1.4%~1.8%) > min_profit_pct (1.0%) 副出口被主出口完全压制(基准 0 次成交)。二选一: 把 inner_step 降到 min_profit_pct/inner_grids 以下(如 0.4),或明确它是兜底保险并接受它基本不触发。
  3. 补一个"无止损"的对冲闸门。 数据上最大风险来自单一标的的长期深套(510300.SH 4,034.73)。 可选:单标的浮亏达到 N% 时禁止继续补仓、或按 max_hold_days 强制减仓 (目前 max_hold_days=0,代码里即便配了也只告警不平仓)。
  4. 重新审视"低位"判定。 entry = min(通道门槛, MA60) 在均线走低时会放宽门槛, 导致在 60 日分位 40%+ 的位置建网(样本里出现过)。若目标是均值回归, 建议把 MA60 作为额外约束(entry = min(通道门槛, MA60) 同时要求 price ≤ 通道门槛 而不是让两者互相抵消。
  5. 上线前必须补的三件事docs/etf.md §7.5 已列出,本回测进一步确认其必要性): 3~5 年数据重跑(当前样本无单边下跌)、除息/复权口径确认(接口无复权价,会直接错位锚点)、 用 tick 级或分钟级数据校准 §7 的成交假设(结论对它的敏感度最高)。

十、为什么收益率这么低:机会频率是上限,仓位规模是唯一的放大器

追加了三组实验(sweep.py / universe.py / entries.py,逻辑与 §三 完全一致,只改参数或下单规模)。

10.1 根因:一年只有 59 个入场信号

标的 可回放日 最低价跌破门槛 当日收回门槛之上 入场信号 跌破门槛天数占比
588000.SH 182 44 20 20 24.2%
510300.SH 182 47 29 29 25.8%
518880.SH 182 30 10 10 16.5%
合计 546 121 59 59
  • 三个标的一年一共只有 59 次"跌进门槛 + 当日收回"的机会(≈ 每天 0.32 次), 且实盘还要再叠加盘中反弹 rebound_pct 确认,只少不多。
  • 回测实际建网 29 次,轮次 28 次 → 机会几乎被用尽,不是策略在挑,是市场不给。
  • 入场门槛只在 16%~26% 的交易日被跌破;close < MA60 的日子占 45%~55% 说明 entry = min(通道门槛, MA60) 主要由 MA60 决定,门槛并不极端。

所以收益低的算术原因是年收益 ≈ 平均占用比例 × 单位占用收益率。 平均只占用 1.68% 的资金,哪怕占用部分的年化回报有 45%(≈ 每轮 0.89% × 一年 50 轮), 账户层面也只有 1.68% × 45% ≈ 0.76%

10.2 唯一有效的放大器:单档规模(代价是回撤同比例上升)

其他参数一律不动,只把 buy_shares(及其 10 档容量)放大:

buy_shares 权益变动 收益率 最大回撤 平均占用 峰值占用 占用ROI 收益/回撤
1,000现值 +1,534 0.77% 0.63% 1.68% 19.4% 45.7% 1.2
2,000 +3,334 1.67% 1.24% 3.20% 38.8% 52.1% 1.3
5,000 +6,073 3.04% 5.44% 23.6% 88.9% 12.9% 0.6
10,000 +8,705 4.35% 8.11% 33.8% 91.0% 12.9% 0.5
20,000 +9,394 4.70% 9.54% 38.3% 92.5% 12.3% 0.5
  • 2,000 股以内:收益近似线性放大,风险调整后收益不降(收益/回撤 1.2→1.3)。
  • 5,000 股以上:占用 ROI 从 ~50% 掉到 ~13%,因为开始在同一批机会上过度集中、 且被迫吃下更差的入场价;收益/回撤跌到 0.5~0.6。这就是"加杠杆"的边界。
  • 资金放大 ≠ 收益改善:把资金提到 100 万且每档 5,000 股,收益率仍是 0.83% 与 20 万/1,000 股的 0.77% 几乎一样——钱多了但没有更多机会可下注

10.3 标的是并行的机会源(按比例缩放的隔离实验)

场景 资金 权益变动 收益率 峰值占用
1 只 + 资金 1/3 66,667 +134 0.20% 4.4%
2 只 + 资金 2/3 133,333 +682 0.51% 7.9%
3 只 + 全额 200,000 +1,534 0.77% 19.4%
2 只 + 仍是 20 万 200,000 +682 0.34% 5.2%
1 只 + 仍是 20 万 200,000 +134 0.07% 1.5%

收益率随标的数量近似线性上升0.20% → 0.51% → 0.77%,而资金同步放大时每单位资金效率不变)。 反过来,"钱多标的少"纯粹是浪费1 只标的拿 20 万,峰值占用只有 1.5%。 → 每只 ETF 平均只能吸收约 6~7 万元峰值资金,扩标的是提高资金利用率最干净的方式。

10.4 为什么"便宜"的参数调整都没用(甚至是负优化)

规模固定 buy_shares=2000 时:

调整 权益变动 收益率 最大回撤 占用ROI 判断
基准add 3% / profit 1% / channel 15% +3,334 1.67% 1.24% 52.1% 基准
add_pct=2% +2,522 1.26% 0.89% 26.5% 变差
add_pct=1.5% +3,090 1.55% 0.88% 29.4% 略差
add_pct=1.0% +2,875 1.44% 0.88% 29.9% 略差
min_profit_pct=0.6% +2,080 1.04% 1.26% 41.7% 明显变差
min_profit_pct=3% +1,995 1.00% 0.17% 67.8% 收益降、单位效率升
channel_pct=10% +2,850 1.43% 3.31% 12.0% 换手↑、单位效率↓、回撤↑
channel_pct=30% +2,544 1.27% 1.04% 26.2% 变差
  • 加快补仓没用add_pct 从 3% 收紧到 1%,补仓次数从 6 升到 8平均成本被抬高 单位占用 ROI 从 52% 掉到 30%,净效果为负。补仓的收益来自"跌得深",不是"补得勤"。
  • 降低止盈目标没用min_profit_pct=0.6% 让轮次从 33 增到 38但每轮利润被佣金摊薄 总收益反而从 +3,334 掉到 +2,080docs/etf.md §5.1"不要为了迁就资金调低 min_profit_pct"被验证)。
  • 放松入场门槛没用channel_pct=10% 把峰值占用推到 52.7%、回撤 3.31%,但收益反而更低 ——门槛的作用是筛掉低质量机会,而不是限制资金
  • 现值参数add 3% / profit 1% / channel 15%)在这批单变量里已经是最优点附近

10.5 组合方案A+B 叠加)

方案 权益变动 收益率 最大回撤 峰值占用 收益/回撤
基准(买 1,000 +1,534 0.77% 0.63% 19.4% 1.2
买 2,000 + add 1.5% + profit 1.0% +3,090 1.55% 0.88% 26.9% 1.8
买 5,000 + add 1.5% + profit 1.0% +7,888 3.94% 2.18% 67.3% 1.8
买 10,000 + add 1.5% + profit 1.0% +14,529 7.26% 4.29% 91.0% 1.7
每档 = 现金 10%(按资金下单) +6,536 3.27% 1.25% 39.3% 2.6

"每档 = 现金的 10%"是这批实验里风险调整后最好的一组(收益/回撤 2.6):它让每档规模 自动跟随账户净值,既比固定 1,000 股用得多(平均占用 6.0% vs 1.68%),又不至于像固定 10,000 股那样在同一批机会上堆到 91% 占用。

10.6 改进方案排序(按证据强度)

# 措施 预期效果 代价 是否需要改代码
1 单档规模 1,000 → 2,000 股(或改成"现金的 5~10%" 收益 ×2~×4+1,534 → +3,334 / +6,536 回撤 0.63% → 1.24% / 1.25% 只改 _etf.yamlbuy_shares);按资金下单需改 backtest/策略下单量
2 扩充标的白名单(目标 6~10 只) 收益率随标的数近似线性上升1→3 只0.20%→0.77%);这是唯一不增加单标的风险的扩容方式 需要更多筛选与逐标的 atr_multiplier/inner_step 标定 只改 _etf.yamlsymbols
3 让副出口可达inner_step 降到 min_profit_pct/inner_grids 以下(如 0.4 轻微(+1,426 vs +1,534略降但能让"单档兜底"这个保险真正存在 增加少量换手与佣金 只改 _etf.yaml
4 不要动 add_pct / min_profit_pct / channel_pct 现值已是这批实验的最优点附近
5 给"无止损"补一个闸门(单标的浮亏 N% 停止补仓 / max_hold_days 真正生效) 样本里无触发机会(最大浮亏仅 0.9%属于尾部保险,不是收益来源 会引入已实现亏损 需改 positions.py

一句话:收益低不是参数没调好,而是"一年 59 个机会 × 每轮 0.89% × 平均只用 1.68% 的钱" 这三项乘出来的。想提高,先扩标的(更多并行机会),再放大单档规模(更多钱下注) 调参(补仓速度、止盈门槛、入场宽度)已经被数据否决。


十一、复现与文件

labs/analysis/etf/
├── backtest.py       回测内核日线近似、三种成交模型、共享资金、T+1、sizer
├── analysis.py       轮次统计 / 资金占用 / 逐月 / 敏感性
├── run.py            总报告生成器results.json + run_report.txt
├── sweep.py          改进方案扫描(规模 / 参数 / 组合)
├── universe.py       标的数量 × 资金规模的隔离实验
├── entries.py        入场机会频率统计
├── results.json      全部结构化结果
├── run_report.txt    人读汇总表
└── cache/*.json      日线缓存(--refresh 重新抓取)
cd D:\work\quant\big-qmt
py -3.14 -B labs/analysis/etf/run.py --refresh     # 抓最新日线并重跑全部对照
py -3.14 -B labs/analysis/etf/run.py --ledger      # 附带逐笔成交
py -3.14 -B labs/analysis/etf/sweep.py             # 改进方案扫描
py -3.14 -B labs/analysis/etf/universe.py          # 标的数量 vs 资金规模
py -3.14 -B labs/analysis/etf/entries.py           # 入场机会频率