记录一次止盈参数的调优(2026-07-13)

止盈设得太高,本质上是把「不想太早下车」写进了参数里

17 号页的 5 个仓位挂了 12.9 小时,一笔平仓都没有。看了一眼持仓就有人问:持仓这么久还没操作,止盈是不是太多了。这一问,引出来的不只是止盈那一个数字。


12.9 小时,0 笔平仓

先把当时的持仓摆出来:

币种 方向 入场价 现价 浮盈 距止盈 距止损
BTC SHORT $64,045 $63,725 +0.5% 还差 4.5% 2.5%
ETH LONG $1,807 $1,819 +0.6% 还差 4.3% 2.6%
SOL SHORT $77.14 $77.04 +0.1% 还差 4.9% 2.1%
ZEC LONG $523.8 $533.9 +1.9% 还差 3.0% 3.8%
XRP SHORT $1.10 $1.09 +1.1% 还差 4.4% 3.0%

持仓 12.9 小时,0 笔平仓记录,账户余额 $4,437(另外 $5,563 锁在仓位里)。

5% 止盈对主流币意味着什么

数据摊开之后,结论其实很清楚:5% 对主流币太高了。

  • BTC 12.9 小时才动了 0.5%。按这个速率,走到 5% 要 10 天。
  • 止盈/止损比是 5%/2% = 2.5:1,账面上不难看,但主流币波动率低,价格根本走不到 5%。
  • 移动止盈也形同虚设——只在浮盈 3%–5% 之间才激活,可价格几乎到不了那个区间。

本质问题是:BTC/ETH/SOL/BNB 这类主流币日波动率通常只有 1%–3%,把止盈设在 5%,等于要求连续 2–3 天的单边行情。在震荡市里,它几乎不可能触发。

改了四处,还要回头改旧仓

改的是 maincoin_paper.py:

  1. 新开仓止盈 **5% → 3%**(params["take_profit"] = 0.03)
  2. 兜底百分比止盈 **5% → 3%**(没有预设 TP 时走的 fallback,第 346 行)
  3. 移动止盈激活门槛 **3% → 2%**(浮盈 2% 就开始保护,回撤到 1% 平)
  4. 新增时间衰减平仓:持仓超 48 小时且浮盈 < 1%,自动平仓释放资金

改完代码还漏了一处:已经挂着的 5 个持仓,止盈价还是按旧的 5% 算的。又把它们的止盈价逐个更新成 3%(比如 BTC $60,842 → $62,124)。

改完之后,退出逻辑的优先级是:

  1. 止损(-2%)
  2. 止盈(+3%)
  3. 信号反转
  4. 移动止盈(浮盈 2% → 回撤到 1% 平)
  5. 时间衰减(> 48h 且浮盈 < 1% 平)

更隐蔽的问题:平仓之后开不出新仓

止盈只是表症。重启之后盯着日志看,发现另一个更要命的事:平仓之后,系统开不出新仓。

日志里有个细节:

1
2
3
2026-07-13 09:41:48,684 信号: SHORT BTC/USDT whale_tracking conf=86% age=12.9h
...
2026-07-13 09:41:52,772 扫描完成: 信号10 平仓0 持仓5

信号是有的,但每一条的 age 都是 12.9 小时,会被「信号过期 > 4h 就跳过」这条规则全部拦下。

根因是:mc_precompute.py 根本没在跑 → mc_signals_latest 表里的信号 36 小时没刷新 → 开仓时全被判过期。

修法是把信号刷新收进主循环:在 maincoin_paper.py 里加了 refresh_signals(),每 4 小时自动重算 14 个策略,首次启动立即刷新。为避免循环引用,里面用延迟导入调 mc_precompute。

这样一来,交易循环不再依赖一个「记得手动启动」的外部进程——而那个依赖,正是这次故障的全部原因。

顺带补上的几道闸

同一天还顺手收了几处:

  • 4 小时信号过期检测:开仓只用实时价和新鲜信号,旧信号不再参与
  • 连续 3 次亏损保护:同一币种连亏 3 次就暂停它
  • 开仓价改用实时价:之前入场价会用到信号表里的旧价格
  • 止损改用开仓时预设的价格:避免跳空时实际亏损超出预期
  • 全项目适配新版 Streamlit API,把 use_container_width 换成 width 参数

重启,以及第一批结果

重启 mc_paper_loop 的过程中还闹了个小插曲:后台收到一条旧进程的退出通知(exit code 1),一度以为新代码有问题,其实那只是之前被 kill 掉的进程在收尾。确认新进程正常循环后就没再管它。

重启后 5 个新仓开了出来(BTC SHORT / ETH LONG / SOL LONG / OPN LONG / ZEC LONG),止盈都是 3%,信号 age=0.0h(全新的)。历史交易 5 笔,胜率 60%。

最后

那天的收获,也分三层。

最表面的是那个数字:止盈从 5% 改成 3%。单看这一条,像一次普通调参。

中间一层,是「参数要匹配标的的波动率」。同一个 5%,放在高波动的标的上是合理的,放在主流币上就是把仓位焊死在震荡里。参数没有绝对好坏,只有和标的是否匹配——判断依据不是「我想赚多少」,而是「这个标的通常能走多远」。

最里面一层,是那个「平仓后开不出新仓」的根因。止盈调到哪儿都白搭,只要信号源早就断了。这让我意识到:一个自动化系统最脆弱的地方,往往不是策略逻辑,而是那些「假设别人会按时启动」的隐性依赖。 把它内置进主循环,比写任何一条策略都更值。