Hi,👋 we have updated the app and fixed multiple bugs. We are lacking funds, request to free user not to use Adblock. Ads are non intrusive. 😊

@puff_2002: 恭喜我突破2000粉,上点干货🎉。今天扭亏为盈,Happy ...

@puff_2002
10 views Mar 20, 2026
Advertisement
1
恭喜我突破2000粉,上点干货🎉。今天扭亏为盈,Happy Hunting,发完我就要去快乐的逛拼多多买买买啦,留言明天回~
Media image
2
上一篇介绍了布林带的基本概念、相关参数和常见策略:,今天来写一下量化实践中的实战技巧。去年我确实靠这个策略赚到了一些钱,需要再次说明“道”永远比“术”更重要。一味照搬参数是很愚蠢的行为,重要的是学习如何科学进行策略研发和调优的全流程。
3
今天的思路是如何手把手带大家优化一个基础策略,因为篇幅原因,一些基础的东西就略过不讲,以思路分享为主,相信动手能力强的跑一遍就悟出来了。
4
## 策略思路:布林带收缩形态下的均值回归
5
上一篇讲过:如果布林带宽度长期过窄那就是挤压形态,挤压形态意味着波动率低且市场方向不明确,如果此时交易量也不大,那么可以放心的来一把剥头皮。其实就是我们认为在这个状态下价格趋于均值回归,也就是向中轨靠拢。
6
根据我的手动经验,先给一个非常粗糙的合约交易策略思路:
7
• 入场:窄带 + 触及上下轨 → 做均值回归(触上轨做空,触下轨做多)
8
• 止盈:价格到中轨
9
• 止损: 一旦突破(出带)立刻止损
10
## 统计验证
11
接下来我们先统计一下布林带在窄带(暂定小于20%分位)的情况,我们看一下统计结果,20%的时间是处于挤压状态的,说明我们的出手机会还是不少的。
12
K线:5分钟
13
统计周期:2025.3.9-2026.3.19
14
币对:BTC/USDT
15
数据源:Binance
16
Media image
17
Media image
18
## 策略回测:
19
接下来我们拿着我们粗糙的策略开始回测一下,与布林带对应的回测图表和指标我整理了一下,再次说明,做量化一定要学会根据策略调整各个参数,有些策略需要多看一些指标和图,就是《孙子兵法》里说的“兵无常势,水无常形。”:
20
Media image
21
Media image
22
接下来我们跑一下我们最粗糙的策略来看看效果。说明一下初始资金10万美元,手续费取0.018%(Binance Future Maker的无VIP费率)。
23
初次回测效果
24
恭喜我,成功制造了一个亏钱策略:
25
Media image
26
Media image
27
先别急,我们看一下数据,找找问题出在哪里。
28
• 策略大多数时间都在频繁交易,而且每一笔持仓时间很短(平均只有19分钟)。这种节奏很容易被市场里的“噪音波动”影响,也就是价格的随机小波动,经常刚进场就被打掉。
29
• 由于交易次数多,手续费占到了将近16.8%,对整体收益影响非常大。简单来说,就算策略本身不太亏,也会被手续费慢慢“吃掉”。
30
• 在布林带收窄的时候,市场并没有像预期那样稳定地来回震荡,反而经常出现“假突破”或者直接启动趋势行情。也就是说,本来想做反弹,但市场却往一个方向走了。
31
接下来我们针对这三个问题进行优化,目前的思路是:
32
降低交易频率,提高入场质量:不要一触及布林带就交易,必须增加确认,同时减少交易次数,避免在小波动里反复进出被“噪音”洗掉。(引入ATR过滤)
33
提高单笔收益,覆盖手续费:当前利润空间太小但交易太频繁,导致手续费侵蚀严重。我们要减少交易次数,同时适当拉大止盈空间(百分位止盈),让每一笔交易有足够利润去覆盖成本。
34
区分市场状态,避免在挤压阶段做反弹:布林带收窄并不等于适合均值回归,反而更容易出现突破行情。应在极窄带时停止做反弹,或切换为突破策略,只在明确震荡区间中使用均值回归。
35
整理成具体的量化思路就是这样:
36
```

# === 1. 指标计算 ===
bb_mid = SMA(close, 20)
bb_std = STD(close, 20)
bb_upper = bb_mid + 2 * bb_std
bb_lower = bb_mid - 2 * bb_std

bandwidth = (bb_upper - bb_lower) / bb_mid * 100
atr = ATR(14)

# 带宽阈值
squeeze_threshold_extreme = bandwidth_percentile(10) # 极窄带,直接不做
squeeze_threshold_normal = bandwidth_percentile(20) # 普通窄带,可作为观察区间

# ATR过滤
atr_min_threshold = ATR_percentile(30) # ATR太低说明波动太小,容易被噪音洗掉

# 百分位止盈
tp_percentile_long = historical_positive_excursion_percentile(60)
tp_percentile_short = historical_negative_excursion_percentile(60)

# 交易冷却
cooldown_bars = 5

# 状态变量
position = NONE
last_exit_bar = -999


# === 2. 市场状态识别 ===
# 只在非极窄带时考虑交易
if bandwidth <= squeeze_threshold_extreme:
allow_trade_regime = False
else:
allow_trade_regime = True

# 趋势 / 震荡过滤(示意,可替换成ADX、均线斜率、高低点结构)
if abs(slope(bb_mid, 5)) < slope_threshold:
trend_state = "RANGE"
else:
trend_state = "TREND"


# === 3. 入场确认逻辑 ===
# 做多确认:触及下轨后出现反转
long_reversal_confirm =
(low <= bb_lower) and
(close > open) and
(lower_shadow > body_size)

# 做空确认:触及上轨后出现反转
short_reversal_confirm =
(high >= bb_upper) and
(close < open) and
(upper_shadow > body_size)


# === 4. 交易频率控制 ===
can_trade =
(position == NONE) and
(current_bar - last_exit_bar >= cooldown_bars) and
(atr >= atr_min_threshold) and
(allow_trade_regime == True) and
(trend_state == "RANGE")


# === 5. 入场逻辑 ===
if can_trade:

# 做多:下轨附近 + 反转确认
if long_reversal_confirm:
entry_price = close
stop_loss = low - 0.5 * atr

# 分批止盈:提高单笔收益
take_profit_1 = bb_mid
take_profit_2 = entry_price + tp_percentile_long

open_long()

# 做空:上轨附近 + 反转确认
elif short_reversal_confirm:
entry_price = close
stop_loss = high + 0.5 * atr

take_profit_1 = bb_mid
take_profit_2 = entry_price - tp_percentile_short

open_short()


# === 6. 持仓管理 ===
if position == LONG:

# 第一目标:中轨,先止盈一部分
if close >= take_profit_1 and not tp1_hit:
close_partial(50%)
tp1_hit = True

# 第二目标:百分位止盈
if close >= take_profit_2:
close_all()
last_exit_bar = current_bar

# 止损
if close <= stop_loss:
close_all()
last_exit_bar = current_bar


if position == SHORT:

if close <= take_profit_1 and not tp1_hit:
close_partial(50%)
tp1_hit = True

if close <= take_profit_2:
close_all()
last_exit_bar = current_bar

if close >= stop_loss:
close_all()
last_exit_bar = current_bar


# === 7. 风险控制 ===
# 连续亏损后暂停交易,避免噪音环境连续打脸
if consecutive_losses >= 3:
suspend_trading_for(20 bars)
```
37
跑出来看看效果:
38
Media image
39
这一版已经明显比之前好多了,交易次数大幅减少,手续费也降下来了,整体从之前的持续亏损,变成现在基本打平。回撤也控制住了,后半段还能慢慢修复,说明策略已经开始“有点靠谱了”,不再是纯亏钱模型。
40
但是还存在一些问题:
41
盈亏比太低(赚小亏大):虽然胜率挺高,但每次赚得不多,一旦遇到几笔亏损,很容易把之前赚的吐回去
42
还有少数大亏单:偶尔会出现一笔比较大的亏损,对整体影响很大
43
还有一些低质量交易:虽然已经减少很多,但在某些带宽区间里,还是在做一些“不太该做的单子”
44
优化的策略:
45
提升盈亏比:不只吃中轨,可以分批止盈,让一部分仓位去吃更远的空间
46
控制单笔最大亏损:加一个“硬止损”,避免再出现那种特别大的亏损
47
继续筛选更好的交易区间:把效果不好的带宽区间再过滤掉,只在“最容易赚钱”的那一段做
48
整理成量化思路:
49
```
# =========================================
# 新增优化1:提升盈亏比(分批止盈 + 扩展利润)
# =========================================

# 原有中轨止盈基础上,增加远端止盈
take_profit_2 = bb_upper # 做多:看向上轨
take_profit_2 = bb_lower # 做空:看向下轨

take_profit_3 = entry_price + 1.5 * atr # 做多延伸利润
take_profit_3 = entry_price - 1.5 * atr # 做空延伸利润

# 分批止盈结构
if position == LONG:
if close >= bb_mid and not tp1_hit:
close_partial(30%)
tp1_hit = True

if close >= take_profit_2 and not tp2_hit:
close_partial(40%)
tp2_hit = True

if close >= take_profit_3:
close_all()

if position == SHORT:
if close <= bb_mid and not tp1_hit:
close_partial(30%)
tp1_hit = True

if close <= take_profit_2 and not tp2_hit:
close_partial(40%)
tp2_hit = True

if close <= take_profit_3:
close_all()


# =========================================
# 新增优化2:限制单笔最大亏损(尾部风险控制)
# =========================================

max_loss_threshold = 1.5 * atr

if position == LONG:
if (entry_price - close) > max_loss_threshold:
close_all() # 强制止损

if position == SHORT:
if (close - entry_price) > max_loss_threshold:
close_all()


# =========================================
# 新增优化3:带宽区间过滤(只做最优区间)
# =========================================

# 带宽分段
bandwidth_low = bandwidth_percentile(10)
bandwidth_high = bandwidth_percentile(60)

# 只允许在中等带宽交易
if bandwidth < bandwidth_low:
allow_trade = False # 太窄,不做

elif bandwidth > bandwidth_high:
allow_trade = False # 太宽,减少噪音

else:
allow_trade = True # 最优区间

# 在主逻辑中加入
can_trade = can_trade and allow_trade


# =========================================
# 新增优化4:过滤低收益交易(避免手续费白做)
# =========================================

min_expected_profit = fee * 3

expected_profit_long = bb_mid - entry_price
expected_profit_short = entry_price - bb_mid

if position_signal == LONG and expected_profit_long < min_expected_profit:
skip_trade()

if position_signal == SHORT and expected_profit_short < min_expected_profit:
skip_trade()
```
50
结果跑出来了,恭喜,终于开始赚钱了,说明我们之前优化的思路是对的。曲线也相对健康很多。
51
这一版策略已经有了明显进步,从之前接近打平提升到了小幅盈利,说明整体方向是正确的。交易次数进一步减少,手续费影响也降到了很低的水平,策略变得更加“干净”,不再被频繁进出拖累。同时,胜率提升到76%以上,回撤控制在极低水平(约-0.5%),整体波动非常小,说明风控已经做得很好。从权益曲线来看,策略具备一定的持续修复能力,不再是单边下跌,而是开始呈现稳步上行的结构。
52
Media image
53
Media image
54
当前存在的问题:
55
盈亏比偏低(赚小亏大):虽然胜率很高,但大多数盈利单利润较小,而少数亏损单幅度更大,容易抵消多笔盈利
56
收益效率不高:策略已经稳定,但整体收益增长较慢,很多盈利单过早止盈,没有充分利用行情空间
57
仍存在尾部风险:虽然回撤已经很低,但个别较大亏损仍然存在,对整体收益有放大影响
58
没有太多新问题,只是我们还需要继续优化参数。既然如此,我们直接做全局的参数优化。过滤表现不佳的组合,从其他组合中挑选表现不错的,下面是我自己的一个筛选条件。
59
Media image
60
```
先过滤掉:
- Profit Factor <= 1
- Max Drawdown > 20%
- Total Trades < 10

剩下的组合里,再按:
score = Sharpe * 0.4 + ProfitFactor * 0.3 + TotalReturn * 0.2 - MaxDrawdown * 0.1
选最优
```
61
这次总共跑了19683个参数组合。如果设备够好可以把网格做的更细一些,用来做示范我就不跑太细了。接下来就是漫长的炼丹环节,上帝保佑可以一轮出~
62
Media image
63
夏普4.6看起来还是不错的,但是我们只是在3个月的区间进行回测,很可能过拟合,大家正式跑的时候推荐用4年,可以包含一个大周期。然后再做优化。
64
埋个彩蛋,上一篇说过bb_period选20在加密是不合理的,但是今天我没有调这个参数,留给大家自己调,会有新发现。收摊收摊,最近几个月都不想写量化相关了,还是写宏观吧,宏观好玩😴
Actions
Visual Editor Carousel Maker NEW
Update Thread
What You Can Do
  • Download as PDF
  • Save to Notion
  • Export as Markdown
  • Visual Editor
  • LinkedIn & Instagram Carousel Maker
Create Free Account

Includes 7-day Premium trial

Advertisement