Стратегия обратного отслеживания двойного канала - это стратегия обратного отслеживания, которая сочетает в себе полосы Боллинджера, каналы Келтнера и индикаторы импульса.
Расчет средней, верхней и нижней полос для полос Боллинджера
Вычислить средние, верхние и нижние полосы для Keltner каналов
Определить, находятся ли полосы Боллинджера внутри каналов Келтнера.
Вычислить линейный наклон регрессии вал закрытия по отношению к BB и KC средних точек
Расчет ROC и EMA ROC для закрытия
При сжатии, длительное время, когда валь > 0 и ROC превышает пороговое значение
Установка условий остановки потерь и получения прибыли
Улучшенная точность путем объединения системы двойного канала для обратного движения
Избегайте ложных сигналов с использованием линейной регрессии и скорости изменения
Гибкие регулируемые параметры для оптимизации между продуктами
Эффективное управление рисками по сделке с использованием стоп-лосса/прибыли
Достаточные данные об обратных тестах для подтверждения жизнеспособности стратегии
Сжатие не всегда приводит к эффективному обращению
Ложные прорывы генерируют неправильные сигналы.
Слишком широкая стоп-потеря, приводящая к чрезмерным одиночным потерям
Недостаточные испытательные периоды
Оптимизация параметров для большего количества продуктов
Добавление машинного обучения для идентификации поддержки/сопротивления
Включить изменение объема для улучшения валидности прорыва
Проведение анализа в течение нескольких временных рамок для определения сохранности тренда
Оптимизировать динамический стоп-лосс/прибыль
Стратегия обратного отслеживания двойного канала использует такие индикаторы, как полосы Боллинджера и каналы Келтнера для обратной торговли. С оптимизацией параметров она может быть адаптирована для различных продуктов для определения действительности прорыва в некоторой степени.
/*backtest start: 2023-10-02 00:00:00 end: 2023-11-01 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // Credit for the initial Squeeze Momentum code to LazyBear, rate of change code is from Kiasaki strategy("Squeeze X BF 🚀", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0) /////////////// Time Frame /////////////// testStartYear = input(2012, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0) testStopYear = input(2019, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0) testPeriod() => true /////////////// Squeeeeze /////////////// length = input(20, title="BB Length") mult = input(2.0,title="BB MultFactor") lengthKC=input(22, title="KC Length") multKC = input(1.5, title="KC MultFactor") useTrueRange = input(true, title="Use TrueRange (KC)") // Calculate BB source = close basis = sma(source, length) dev = mult * stdev(source, length) upperBB = basis + dev lowerBB = basis - dev // Calculate KC ma = sma(source, lengthKC) range = useTrueRange ? tr : (high - low) rangema = sma(range, lengthKC) upperKC = ma + rangema * multKC lowerKC = ma - rangema * multKC sqzOn = (lowerBB > lowerKC) and (upperBB < upperKC) sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC) noSqz = (sqzOn == false) and (sqzOff == false) val = linreg(source - avg(avg(highest(high, lengthKC), lowest(low, lengthKC)),sma(close,lengthKC)), lengthKC,0) ///////////// Rate Of Change ///////////// roclength = input(30, minval=1), pcntChange = input(7, minval=1) roc = 100 * (source - source[roclength]) / source[roclength] emaroc = ema(roc, roclength / 2) isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2)) /////////////// Strategy /////////////// long = val > 0 and isMoving() short = val < 0 and isMoving() last_long = 0.0 last_short = 0.0 last_long := long ? time : nz(last_long[1]) last_short := short ? time : nz(last_short[1]) long_signal = crossover(last_long, last_short) short_signal = crossover(last_short, last_long) last_open_long_signal = 0.0 last_open_short_signal = 0.0 last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1]) last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1]) last_long_signal = 0.0 last_short_signal = 0.0 last_long_signal := long_signal ? time : nz(last_long_signal[1]) last_short_signal := short_signal ? time : nz(last_short_signal[1]) in_long_signal = last_long_signal > last_short_signal in_short_signal = last_short_signal > last_long_signal last_high = 0.0 last_low = 0.0 last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1]) last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1]) sl_inp = input(100.0, title='Stop Loss %') / 100 tp_inp = input(5000.0, title='Take Profit %') / 100 take_level_l = strategy.position_avg_price * (1 + tp_inp) take_level_s = strategy.position_avg_price * (1 - tp_inp) since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na slShort = strategy.position_avg_price * (1 + sl_inp) long_sl = in_long_signal ? slLong : na short_sl = in_short_signal ? slShort : na /////////////// Execution /////////////// if testPeriod() strategy.entry("Long", strategy.long, when=long) strategy.entry("Short", strategy.short, when=short) strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0) strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0) /////////////// Plotting /////////////// bcolor = iff(val > 0, iff(val > nz(val[1]), color.lime, color.green), iff(val < nz(val[1]), color.red, color.maroon)) plot(val, color=bcolor, linewidth=4) bgcolor(not isMoving() ? color.white : long ? color.lime : short ? color.red : na, transp=70) bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=50) hline(0, color = color.white)