Эта стратегия основана на индикаторе Bollinger Bands, в сочетании с скользящими средними и техническим индикатором ATR, для реализации краткосрочной системы прорыва. Стратегия рассчитывает относительную процентную позицию цен в канале Bollinger Bands для оценки ситуаций перекупа и перепродажи, в сочетании с новыми максимумами и минимумами, чтобы генерировать торговые сигналы.
Эта стратегия использует канал Болинджерских полос для оценки волатильности рынка, причем ширина канала определяется стандартным отклонением. Сигналы покупки генерируются, когда цены опускаются ниже нижней полосы, и сигналы продажи, когда цены опускаются выше верхней полосы. Движущиеся средние могут сглаживать колебания Болинджера и уменьшать ложные прорывы.
Эта стратегия эффективно сочетает в себе процентные диапазоны Боллинджера, скользящие средние, индикатор ATR, новые максимумы / минимумы и ежегодные максимумы / минимумы, чтобы построить относительно строгую и эффективную краткосрочную торговую систему прорыва. Ее выдающееся преимущество заключается в использовании различных инструментов для снижения шума и выявления истинных сигналов тренда. Конечно, стратегия также сталкивается с некоторыми трудностями настройки параметров и упущенными возможностями в строгих условиях. В целом она представляет собой уникальный торговый стиль и высокоэффективную стратегию прорыва Боллинджера, которая требует дальнейших исследований и проверки реальных торговых данных.
/*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)