Стратегия адаптивного отслеживания тренда Bollinger

Автор:Чао Чжан, Дата: 2023-11-16 16:35:01
Тэги:

img

Обзор

Эта стратегия основана на индикаторе полос Боллинджера в сочетании с адаптивной скользящей средней, чтобы точно судить и отслеживать тенденции.

Логика стратегии

Стратегия состоит из следующих основных частей:

  1. Используйте индикатор линейной регрессии для расчета кривой линейной регрессии за определенный период как скользящей средней.

  2. Используйте адаптивный индикатор ATR для расчета диапазонов, в сочетании с параметром ratio2, указанным пользователем, для получения верхних и нижних диапазонов.

  3. Определить направление тренда и направление входа/выхода на основе прорыва цены через полосы Боллинджера. Прорыв верхних сигналов полосы продает вход, а прорыв нижних сигналов полосы покупает вход.

  4. Используйте фиксированные точки остановки потери для контроля рисков и отставания остановки прибыли для максимизации прибыли от тренда.

  5. Комбинируйте с временным окном обратного тестирования для оптимизации и проверки стратегии.

Преимущества

  1. Приспосабливаемые скользящие средние и диапазоны дизайна адаптируются к изменениям рынка.

  2. Сигналы прорыва, прорывы полос Боллинджера дают явные сигналы обратного тренда.

  3. Фиксированный стоп-лосс контролирует риски, а следующий стоп-прибыль направлен на максимизацию прибыли от тренда.

  4. Проверено с помощью обратного тестирования.

  5. Логика понятна, а код лаконичен для легкого понимания.

Риски

  1. Болинджерские полосы требуют настройки параметров. Ширина полосы и период могут нуждаться в оптимизации для разных продуктов. Неправильные параметры приводят к отсутствию сигналов или ложным триггерам.

  2. Ограниченный период обратного теста. Недавний диапазон обратного теста может быть недостаточным для полной проверки стабильности по всесторонним историческим данным.

  3. Риск чрезмерной адаптации: текущие оптимизированные параметры могут быть чрезмерно адаптированы к недавним специфическим рыночным условиям.

  4. Уровень стоп-лосса требует оценки. Небольшие стоп-лосы могут быть слишком чувствительными и могут быть остановлены небольшими колебаниями. Оцениваются подходящие стоп-лосы.

  5. Отсутствие количественной проверки. В настоящее время используется только графический прорыв для торговых сигналов без количественной проверки показателей.

Направления к улучшению

  1. Внедрение более адаптивных индикаторов, тестирование комбинаций различных адаптивных скользящих средних и каналов для создания надежной системы отслеживания трендов.

  2. Используйте более систематические методы, такие как генетические алгоритмы, чтобы найти оптимальную комбинацию параметров.

  3. Расширить период обратного теста. Тест на более широких исторических данных для изучения стабильности параметров. Включить затраты на транзакции для более реалистичного обратного теста.

  4. Введите количественные фильтры. Установите фильтры, такие как прорыв объема, разрыв в гистограмме MACD, чтобы избежать ложных прорывов.

  5. Оптимизируйте остановки. Оцените различные фиксированные уровни остановки потери и методы остановки, чтобы найти оптимальные остановки.

  6. Запустите оптимизированную стратегию в режиме реального времени для записи производительности для дальнейших улучшений.

Заключение

Стратегия имеет четкую логику с использованием полос Боллинджера для определения направления тренда и захвата сигналов прорыва, причем скользящая средняя определяет общий тренд. При правильной оптимизации она может стать стабильным и надежным трендом после стратегии. Но ключевые соображения включают репрезентативность бэкстеста, количественные фильтры и настройку стоп-лосса. Если эти аспекты хорошо обработаны, стратегия может достигать устойчивой и значительной прибыли в живой торговле.


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

//@version=4
strategy("Linear Regression (Backtest / Trailing Stop)",overlay=true)
close_price = close[0]

len = input(40)
linear_reg = linreg(close_price, len, 0)

calculationToPlotAverageMeanLine=linear_reg
useUpperDeviation = input(true, "Upper Deviation", bool)
useLowerDeviation = input(true, "Lower Deviation", bool)
ratio2=input(defval=2,title=" Ratio 2")
avg=atr(len)
r2=avg*ratio2
top=linear_reg+r2
bott=linear_reg-r2

calculationToPlotUpperLine=top
calculationToPlotLowerLine=bott

plotUpperDeviationLine = plot(not useUpperDeviation ? na : calculationToPlotUpperLine, color=color(blue,0))
plotAverageMeanLine = plot(calculationToPlotAverageMeanLine, color=color(olive,0))
plotLowererDeviationLine = plot(not useLowerDeviation ? na : calculationToPlotLowerLine, color=color(red,0))
fill(plotUpperDeviationLine, plotAverageMeanLine, color=color(blue,85))
fill(plotLowererDeviationLine, plotAverageMeanLine, color=color(red,85))


//
length = input(title="linear Length",  defval=40, minval=1)
multiplier = input(title="linear Deviation", type=float, defval=2, minval=1)
overbought = input(title="Overbought",  defval=1, minval=1)
oversold = input(title="Oversold",  defval=0, minval=1)
custom_timeframe = input(title="Use another Timeframe?", type=bool, defval=false)
highTimeFrame = input(title="Select The Timeframe",  defval="60")
res1 = custom_timeframe ? highTimeFrame : timeframe.period

fixedSL = input(title="SL Activation", defval=70)
trailSL = input(title="SL Trigger", defval=10)
fixedTP = input(title="TP Activation", defval=50)
trailTP = input(title="TP Trigger", defval=10)

// === INPUT BACKTEST RANGE ===
FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear  = input(defval = 2019, title = "From Year", minval = 2015)
ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear    = input(defval = 9999, title = "To Year", minval = 2015)

start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)        // backtest finish window
window()  => time >= start and time <= finish ? true : false // create function "within window of time"

smabasis = linreg(close_price, length, 0)
stdev = stdev(close, length)
cierre = request.security(syminfo.tickerid, res1, close, false)
alta = request.security(syminfo.tickerid, res1, high, false)
baja = request.security(syminfo.tickerid, res1, low, false)
basis1 = request.security(syminfo.tickerid, res1, smabasis, false)
stdevb = request.security(syminfo.tickerid, res1, stdev, false)
dev = multiplier * stdevb // stdev(cierre, length)
upper = basis1 + dev
lower = basis1 - dev

bbr = (cierre - lower)/(upper - lower)

// plot(bbr)

// // MARCA LAS RESISTENCIAS
pintarojo = 0.0
pintarojo := nz(pintarojo[1])
pintarojo := bbr[1] > overbought and bbr < overbought ? alta[1] :  nz(pintarojo[1])
p = plot(pintarojo, color = red, style=circles, linewidth=2)

// // MARCA LOS SOPORTES
pintaverde = 0.0
pintaverde := nz(pintaverde[1])
pintaverde := bbr[1] < oversold and bbr > oversold ? baja[1] :  nz(pintaverde[1])
g = plot(pintaverde, color = black, style=circles, linewidth=2)
zz= crossover(pintaverde,pintaverde[1]) or crossunder(pintaverde,pintaverde[1])
kp= crossover(pintarojo,pintarojo[1]) or crossunder(pintarojo,pintarojo[1]) 
plotshape(zz,  title="buy", style=shape.triangleup,location=location.belowbar, color=green, transp=0, size=size.small)
plotshape(kp, title="sell", style=shape.triangledown,location=location.abovebar, color=red, transp=0, size=size.small)


strategy.entry("BUY", strategy.long, qty=10, oca_name="BUY",  when=zz and window())
strategy.exit("B.Exit", "BUY", qty_percent = 100, loss=fixedSL, trail_offset=trailTP, trail_points=fixedTP)

strategy.entry("SELL", strategy.short, qty=10, oca_name="SELL",  when=kp and window())
strategy.exit("S.Exit", "SELL", qty_percent = 100, loss=fixedSL, trail_offset=trailSL, trail_points=fixedTP)


Больше