Skip to content

Latest commit

 

History

History
188 lines (122 loc) · 6.46 KB

布林带突破交易策略Bollinger-Band-Breakout-Trading-Strategy.md

File metadata and controls

188 lines (122 loc) · 6.46 KB

Name

布林带突破交易策略Bollinger-Band-Breakout-Trading-Strategy

Author

ChaoZhang

Strategy Description

[trans]

本策略通过判断价格对布林带通道的突破情况进行交易。该策略属于通道突破类策略的一种,旨在捕捉价格突破通道形成的趋势交易机会。

策略原理:

  1. 计算布林带通道,中轨为n日简单移动均线,上下轨为中轨之上下若干倍标准差。

  2. 当价格从上向下突破下轨时,进行短仓入场。当价格从下向上突破上轨时,进行多仓入场。

  3. 设置止损线为相反方向轨线之外,进行风险控制。

  4. 根据最大回撤情况调整通道带宽,优化参数。

  5. 结合交易量过滤判断,避免虚假突破。

该策略的优势:

  1. 突破通道可有效判断趋势转折点。

  2. 布林带参数优化简单实际,不易过优化。

  3. 结合交易量可过滤假突破,提高质量。

该策略的风险:

  1. 布林带滞后问题较突出,可能错过最佳入场点。

  2. 突破后容易出现反转,须设置合理止损。

  3. 优化中追求低频交易可能错失机会。

总之,该策略通过判断布林带的突破情况进行交易,是一种典型的通道突破策略。Relative 简单的规则有利于参数优化,但滞后及止损设置问题仍需警惕,始能获得长期稳定收益。

||

This strategy trades the price breakout of Bollinger Bands. It aims to capture trend opportunities from channel breakouts.

Strategy Logic:

  1. Calculate Bollinger Bands with n-period moving average as midline and volatility bands above and below.

  2. Enter short when price breaks down below lower band. Enter long when breaking above upper band.

  3. Set stops outside opposite band for risk control.

  4. Adjust band width based on max drawdown for parameter optimization.

  5. Add volume filter to avoid false breakouts.

Advantages:

  1. Breaking bands effectively identifies trend turns.

  2. Bollinger parameter optimization is simple and practical.

  3. Volume filter improves quality by avoiding falseouts.

Risks:

  1. Lagging bands may miss best entry timing.

  2. Post-breakout reversals are common, requiring reasonable stops.

  3. Seeking low-frequency trades in optimization can miss opportunities.

In summary, this is a typical channel breakout strategy trading Bollinger breaks. The relatively simple rules benefit optimization but lag and stop placement issues remain that impact long-term steady gains.

[/trans]

Strategy Arguments

Argument Default Description
v_input_1 40 Length
v_input_2 3 R
v_input_3 false Auto Adjust R
v_input_4 0.02 Step in R
v_input_5 2000 Base Year
v_input_6 120 Volume Threadhold
v_input_7 true Include Long
v_input_8 true Include Short
v_input_9 true Enable Position Sizing

Source (PineScript)

/*backtest
start: 2023-08-12 00:00:00
end: 2023-09-11 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
// strategy("ChannelBreakOutStrategyV2.1", commission_type = "percent", commission_value = 0.1, calc_on_order_fills = true, overlay=true)

length = input(title="Length",  minval=1, maxval=1000, defval=40)
maxR = input(title = "R",  minval = 1.0, maxval = 10, defval = 3, step = 0.1)
adoptR = input(title = "Auto Adjust R",  defval = false)
stepR = input(title = "Step in R",  minval = 0.01, maxval = 0.1, step = 0.01, defval = 0.02)
baseYear = input(title = "Base Year",  minval = 2000, maxval = 2016, defval = 2000)
volumeTh = input(title = "Volume Threadhold",  minval = 100.0, maxval = 200, defval = 120, step = 5)
hasLong = input(title = "Include Long",  defval = true)
hasShort = input(title = "Include Short",  defval = true)
usePositionSizing = input(title = "Enable Position Sizing",  defval = true)

getTrailStop(val, current) => 
    s = val > 1.6 ? 0.8 : val >= 1.4 ? 0.85 : val >= 1.3 ? 0.9 : 0.93
    s * current


upBound = highest(high, length)
downBound = lowest(low, length)
hasVol = (volume / sma(volume, length) * 100 >= volumeTh) ? 1 : 0

hasPos = strategy.position_size != 0 ? 1 : 0

trailstop = atr(length) * 3
ptvalue = syminfo.pointvalue
equity = strategy.openprofit > 0 ? strategy.equity - strategy.openprofit : strategy.equity
curR = adoptR == false ? maxR : n == 0 ? maxR : hasPos == 1 ? curR[1] : (rising(equity,1) > 0? curR[1] + stepR : falling(equity, 1) > 0 ? curR[1] <= 2.0 ? 2.0 : curR[1] - stepR : curR[1])
contracts = usePositionSizing == false ? 20 : floor(equity / 100 * curR / (trailstop * ptvalue))

realbuystop = close - trailstop
realsellstop = close + trailstop

isPFst = (hasPos[1] == 0 and hasPos == 1) ? 1 : 0
isPOn = (hasPos[1] + hasPos == 2) ? 1 : 0
largestR = hasPos == 0 or isPFst == 1 ? -1 : nz(largestR[1]) < close ? close : largestR[1]
pctRise =  largestR / strategy.position_avg_price

rbs = strategy.position_size <= 0 ? realbuystop : isPFst ? strategy.position_avg_price - trailstop : pctRise >= 1.3 ? getTrailStop(pctRise, largestR) : (isPOn and realbuystop > rbs[1] and close > close[1]) ? realbuystop : rbs[1]
rss = strategy.position_size >= 0 ? realsellstop : isPFst ? strategy.position_avg_price + trailstop : (isPOn and realsellstop < rss[1] and close < close[1]) ? realsellstop : rss[1]

isStart = na(rbs) or na(rss) ? 0 : 1
buyARun = close - open > 0 ? 0 : open - close
sellARun = open - close > 0 ? 0 : close - open

if (strategy.position_size > 0 and buyARun >= trailstop / 3 * 2 and pctRise < 1.3)
    strategy.close("buy")
    strategy.cancel("exit")
if (strategy.position_size < 0 and sellARun >= trailstop / 3 * 2)
    strategy.close("sell")
    strategy.cancel("exit")

strategy.cancel("buy")
strategy.cancel("sell")
conLong = hasLong == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("buy", strategy.long, qty = contracts, stop=upBound + syminfo.mintick * 5, comment="BUY", when = conLong)
if (rbs > high)
    strategy.close("buy")
strategy.exit("exit", "buy", stop = rbs, when = hasPos == 1 and isStart == 1)

conShort = hasShort == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("sell", strategy.short, qty = contracts, stop=downBound - syminfo.mintick * 5, comment="SELL", when = conShort)
if (rss < low)
    strategy.close("sell")
strategy.exit("exit", "sell", stop = rss, when = hasPos == 1 and isStart == 1)

plot(series = rbs, color=blue)
plot(series = realbuystop, color=green)
plot(series = rss, color=red)
plot(series = realsellstop, color=yellow)

Detail

https://www.fmz.com/strategy/426504

Last Modified

2023-09-12 16:23:12