Strategi Perdagangan Bollinger Peratusan Bands

Penulis:ChaoZhang, Tarikh: 2023-12-11 11:14:53
Tag:

img

Ringkasan

Strategi ini adalah berdasarkan kepada penunjuk Bollinger Bands, digabungkan dengan purata bergerak dan penunjuk teknikal ATR, untuk melaksanakan sistem pecah jangka pendek. Strategi ini mengira kedudukan peratusan relatif harga dalam saluran Bollinger Bands untuk menilai situasi overbought dan oversold, digabungkan dengan pecah tertinggi dan terendah baru untuk menjana isyarat perdagangan.

Logika Strategi

  1. Mengira saluran Bollinger Bands dan kedudukan peratusan relatif harga dalam saluran
  2. Mengira purata bergerak secara berasingan untuk harga terbuka, tutup, tinggi dan rendah
  3. Mengira penunjuk ATR dan menetapkan garis stop loss yang digabungkan dengan ATR
  4. Menghakimi sama ada harga adalah berhampiran tinggi baru atau rendah baru
  5. Gabungkan paras tertinggi dan terendah tahunan untuk menilai trend jangka masa yang lebih besar
  6. Menghasilkan isyarat dagangan berdasarkan perubahan peratusan Bollinger Bands dan paras tertinggi/rendah baru

Strategi ini menggunakan saluran Bollinger Bands untuk menilai turun naik pasaran, dengan lebar saluran ditentukan oleh penyimpangan standard. Isyarat beli dihasilkan apabila harga memecahkan di bawah band bawah, dan isyarat jual apabila harga memecahkan di atas band atas. Purata bergerak dapat meratakan turun naik Bollinger dan mengurangkan pecah palsu. Indikator ATR digabungkan dengan kerugian berhenti yang mengikuti untuk menetapkan skala kerugian berhenti. Tinggi / rendah baru membantu mengelakkan mengejar puncak dan membatasi penurunan. Tinggi / rendah tahunan menapis penyatuan jangka masa yang lebih besar. Ringkasnya, strategi ini menggabungkan pelbagai alat analisis teknikal untuk menilai irama pasaran dan masa kemasukan.

Kelebihan

  1. Penapis pecah Bollinger Bands yang ketat membantu mengurangkan isyarat palsu
  2. Purata bergerak lancar harga dan mengenal pasti trend sebenar
  3. Indikator ATR secara dinamik menjejaki stop loss dan mengehadkan kerugian perdagangan tunggal
  4. Tinggi/rendah baru dan tinggi/rendah tahunan menjadikan isyarat lebih boleh dipercayai
  5. Gabungan pelbagai penunjuk yang berkesan meningkatkan kecekapan

Risiko dan Penyelesaian

  1. Parameter Bollinger Bands yang tidak betul boleh menyebabkan pecah palsu yang berlebihan, kombinasi parameter yang berbeza harus diuji untuk hasil yang terbaik
  2. Referensi harga penutupan boleh membawa kepada pengeluaran melebihi julat stop loss yang ditetapkan ATR, pertimbangkan untuk menggunakan harga tinggi/rendah yang lebih berubah-ubah untuk pengiraan peratusan
  3. Penapisan Bollinger yang ketat mungkin terlepas beberapa peluang trend jangka panjang, melepaskan penapis dan tempoh penahan yang sesuai
  4. Indikator ATR menyusuri perubahan harga yang besar perlahan, pertimbangkan langkah-langkah turun naik frekuensi yang lebih tinggi seperti julat sebenar
  5. Penembusan tinggi/rendah baru mudah diganggu oleh bunyi bising jangka pendek, menilai kepentingan statistik dan kelestarian trend

Arahan pengoptimuman

  1. Uji kombinasi parameter yang berbeza untuk menentukan parameter Bollinger optimum dan panjang purata bergerak
  2. Menggunakan kombinasi model yang menggabungkan parameter Bollinger atau purata bergerak yang berbeza
  3. Uji ketahanan dalam jangka masa dan produk yang berbeza, meningkatkan kesesuaian
  4. Menggabungkan isyarat jangka masa yang lebih tinggi seperti isyarat Bollinger harian atau faktor bermusim
  5. Menilai peluang mengikut trend untuk mengembangkan liputan strategi dan keuntungan

Kesimpulan

Strategi ini secara berkesan menggabungkan band peratusan Bollinger, purata bergerak, penunjuk ATR, tinggi / rendah baru dan tinggi / rendah tahunan untuk membina sistem perdagangan breakout jangka pendek yang agak ketat dan cekap. Kelebihannya yang luar biasa terletak pada menggunakan pelbagai alat untuk mengurangkan bunyi bising dan mengenal pasti isyarat trend yang benar. Sudah tentu strategi ini juga menghadapi beberapa kesukaran penyesuaian parameter dan peluang yang hilang dalam keadaan yang ketat. Secara keseluruhan, ia mewakili gaya perdagangan yang unik dan strategi breakout Bollinger yang cekap yang menjamin penyelidikan dan pengesahan lebih lanjut pada data perdagangan sebenar.


/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Bollinger %B Candles Strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

BBLength = input(100, minval=1, step=1)
StdDev = 10
useMovingAverage = input(true)
MAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
lookbackPeriod = input(22, minval=10, step=10)
colorByPreviousClose = input(true)

AtrMAType = input(title="Moving Average Type", defval="hma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(10)
AtrMult = input(4)
wicks = input(false)

considerYearlyHighLow = input(false)
considerNewLongTermHighLows = input(false)
shortHighLowPeriod = 100
longHighLowPeriod = 200
tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])

backtestYears = input(10, minval=1, step=1)


//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
    newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
    newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
    [newHigh,newLow]

//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
    yhigh = security(syminfo.tickerid, '12M', high[1]) 
    ylow = security(syminfo.tickerid, '12M', low[1]) 
    yhighlast = yhigh[365]
    ylowlast = ylow[365]
    yhighllast = yhigh[2 * 365]
    ylowllast = ylow[2 * 365]
    
    yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
    yearlyHighCondition = (  (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
    yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
    yearlyLowCondition = (  (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
    
    label_x = time+(60*60*24*1000*1)
    [yearlyHighCondition,yearlyLowCondition]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

inDateRange = true
[yearlyHighCondition,yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHighS,newLowS] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
[middleclose, upperclose, lowerclose] = bb(close, BBLength, StdDev)
[middleopen, upperopen, loweropen] = bb(open, BBLength, StdDev)
[middlehigh, upperhigh, lowerhigh] = bb(high, BBLength, StdDev)
[middlelow, upperlow, lowerlow] = bb(low, BBLength, StdDev)

percentBClose = (close - lowerclose)*100/(upperclose-lowerclose)
percentBOpen = (open - loweropen)*100/(upperopen-loweropen)
percentBHigh = (high - lowerhigh)*100/(upperhigh-lowerhigh)
percentBLow = (low - lowerlow)*100/(upperlow-lowerlow)

percentBMAClose = f_getMovingAverage(percentBClose, MAType, lookbackPeriod)
percentBMAOpen = f_getMovingAverage(percentBOpen, MAType, lookbackPeriod)
percentBMAHigh = f_getMovingAverage(percentBHigh, MAType, lookbackPeriod)
percentBMALow = f_getMovingAverage(percentBLow, MAType, lookbackPeriod)

newOpen = useMovingAverage? percentBMAOpen : percentBOpen
newClose = useMovingAverage? percentBMAClose : percentBClose
newHigh = useMovingAverage? percentBMAHigh : percentBHigh
newLow = useMovingAverage? percentBMALow : percentBLow

truerange = max(newHigh, newClose[1]) - min(newLow, newClose[1])

averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
atr = averagetruerange * AtrMult

longStop = newClose - atr
longStopPrev = nz(longStop[1], longStop)
longStop := (wicks ? newLow[1] : newClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop

shortStop = newClose + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := (wicks ? newHigh[1] : newClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and (wicks ? newHigh : newClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? newLow : newClose) < longStopPrev ? -1 : dir

trailingStop = dir == 1? longStop : shortStop

candleColor = colorByPreviousClose ?
                 (newClose[1] < newClose ? color.green : newClose[1] > newClose ? color.red : color.silver) : 
                 (newOpen < newClose ? color.green : newOpen > newClose ? color.red : color.silver)
plotcandle(newOpen, newHigh, newLow, newClose, title='PercentBCandle', color = candleColor, wickcolor=candleColor)
plot(trailingStop, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= dir == 1 ? color.green : color.red)

buyCondition = dir==1 and yearlyHighCondition and newHighS
exitBuyCondition = dir == -1
sellCondition = dir == -1 and yearlyLowCondition and newLowS
exitSellCondition = dir == 1
strategy.risk.allow_entry_in(tradeDirection)

barcolor(buyCondition? color.lime : sellCondition ? color.orange : color.silver)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=exitBuyCondition)

strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca_sell")
strategy.close("Sell", when=exitSellCondition)

Lebih lanjut