Стратегия поиска трендов с двойным лазером

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

img

Обзор

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

Принципы

Эта стратегия объединяет следующие три технических показателя для определения текущей тенденции:

  1. SQUEEZE Momentum Indicator: рассчитывает полосы Боллинджера и каналы Келтнера. Когда две полосы перекрываются, он генерирует сжатие и сигнализирует о надвигающемся изменении тренда. Он возвращает статус сжатия и наклон линейной регрессии.

  2. RSI с весом объема: рассчитывает RSI с весом объема. Использует среднюю точку для определения уровней перекупленности/перепродажи. Он подчеркивает изменения объема.

  3. Параболический SAR: оценивает положение текущей цены относительно линии SAR. SAR выше цены указывает на понижающийся тренд, а SAR ниже цены указывает на восходящий.

Стратегия использует полосы Боллинджера для определения направления тренда, каналы Келтнера для его уточнения, RSI для поиска возможностей реверсии при перекупке / перепродаже и SAR для определения времени входа.

  1. Вычислите полосы Боллинджера, каналы Келтнера, индикатор сжатия.

  2. Вычислить весовой показатель RSI. RSI выше средней точки указывает на рост, ниже средней точки - снижение.

  3. SAR ниже цены показывает восходящий тренд, выше цены показывает нисходящий.

  4. Объедините три индикатора: когда происходит сжатие, RSI выходит выше средней точки, SAR ниже цены, генерируется длинный сигнал. Когда происходит сжатие, RSI выходит ниже средней точки, SAR выше цены, генерируется короткий сигнал.

  5. Когда сигнал запускается, проверьте, что выводы трех индикаторов на предыдущей панели противоположны текущему сигналу.

  6. Установите стоп-лосс и возьмите прибыль после входа, задержите стоп-лосс.

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

Преимущества этой стратегии:

  1. Сочетание нескольких индикаторов улучшает точность оценки тренда. Squeeze точно определяет изменения тренда, RSI четко определяет уровни перекупа / перепродажи, SAR точно умножает вход.

  2. Логика показателей проста и понятна.

  3. Подтверждение нескольких показателей помогает отфильтровать ложные прорывы.

  4. Механика стоп-лосса и прибыли блокирует прибыль и ограничивает риски.

  5. Обширные данные обратных тестов гарантируют надежность.

Риски

Существуют также некоторые риски:

  1. Долгая и короткая логика входа похожи и могут генерировать противоречивые сигналы.

  2. Все показатели используют оптимизацию параметров, риски перенастройки.

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

  4. Стоп-лосс может быть слишком близко и легко остановить.

Решения:

  1. Добавьте проверку настойчивости показателей, чтобы избежать колебаний сигнала.

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

  3. Установите размер пирамиды для управления позициями по направлению.

  4. Проверьте различные диапазоны стоп-лосса для оптимизации цены стоп-лосса.

Руководство по оптимизации

Некоторые направления для оптимизации стратегии:

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

  2. Добавьте логику размещения позиций, как фиксированный/равный процент.

  3. Проверьте различные методы остановки потери, такие как волатильность или линейные остановки, нулевые позиции и т. Д.

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

  5. Использовать модели машинного обучения для динамического входа и выхода.

  6. Добавьте механизмы хеджирования, используя как длинные, так и короткие позиции для снижения коррелирующих системных рисков.

  7. Рассмотреть больше показателей и создать механизмы голосования для повышения точности.

Заключение

Стратегия имеет четкую логику использования нескольких индикаторов для определения направления тренда и проницательного входа в сжатие. Механика остановки потерь и получения прибыли ограничивает риски. Оптимизация параметров и контроль рисков могут еще больше улучшить результаты бэкстеста и реального времени. Это стабильная стратегия, подходящая для трендовых продуктов, и также может работать в более большие временные рамки, такие как ежедневные. С сильной практической ценностью эта стратегия может быть дополнительно оптимизирована во многих аспектах.


/*backtest
start: 2023-10-06 00:00:00
end: 2023-11-05 00:00:00
period: 1h
basePeriod: 15m
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/
// © XaviZ

//#####©ÉÉÉɶN###############################################
//####*..´´´´´´,,,»ëN########################################
//###ë..´´´´´´,,,,,,''%©#####################################
//###'´´´´´´,,,,,,,'''''?¶###################################
//##o´´´´´´,,,,,,,''''''''*©#################################
//##'´´´´´,,,,,,,'''''''^^^~±################################
//#±´´´´´,,,,,,,''''''''^í/;~*©####æ%;í»~~~~;==I±N###########
//#»´´´´,,,,,,'''''''''^;////;»¶X/í~~/~~~;=~~~~~~~~*¶########
//#'´´´,,,,,,''''''''^^;////;%I^~/~~/~~~=~~~;=?;~~~~;?ë######
//©´´,,,,,,,''''''''^^~/////X~/~~/~~/~~»í~~=~~~~~~~~~~^;É####
//¶´,,,,,,,''''''''^^^;///;%;~/~~;í~~»~í?~?~~~?I/~~~~?*=íÑ###
//N,,,,,,,'''''''^^^^^///;;o/~~;;~~;£=»í»;IX/=~~~~~~^^^^'*æ##
//#í,,,,,''''''''^^^^^;;;;;o~»~~~~íX//~/»~;í?IíI»~~^/*?'''=N#
//#%,,,'''''''''^^^^^^í;;;;£;~~~//»I»/£X/X/»í*&~~~^^^^'^*~'É#
//#©,,''''''''^^^^^^^^~;;;;&/~/////*X;í;o*í»~=*?*===^'''''*£#
//##&''''''''^^^^^^^^^^~;;;;X=í~~~»;;;/~;í»~»±;^^^^^';=''''É#
//##N^''''''^^^^^^^^^^~~~;;;;/£;~~/»~~»~~///o~~^^^^''''?^',æ#
//###Ñ''''^^^^^^^^^^^~~~~~;;;;;í*X*í»;~~IX?~~^^^^/?'''''=,=##
//####X'''^^^^^^^^^^~~~~~~~~;;íííííí~~í*=~~~~Ií^'''=''''^»©##
//#####£^^^^^^^^^^^~~~~~~~~~~~íííííí~~~~~*~^^^;/''''='',,N###
//######æ~^^^^^^^^~~~~~~~~~~~~~~íííí~~~~~^*^^^'=''''?',,§####
//########&^^^^^^~~~~~~~~~~~~~~~~~~~~~~~^^=^^''=''''?,íN#####
//#########N?^^~~~~~~~~~~~~~~~~~~~~~~~~^^^=^''^?''';í@#######
//###########N*~~~~~~~~~~~~~~~~~~~~~~~^^^*'''^='''/É#########
//##############@;~~~~~~~~~~~~~~~~~~~^^~='''~?'';É###########
//#################É=~~~~~~~~~~~~~~^^^*~'''*~?§##############
//#####################N§£I/~~~~~~»*?~»o§æN##################

//@version=4
strategy(title="M-SQUEEZE", overlay = true)

//study(title="M-SQUEEZE", overlay = true)

src = input(close, "SOURCE", type = input.source)

// ███▓▒░░ VARIABLES ░░▒▓███

var bool longCond = na, var bool shortCond = na
var int CondIni_long0 = 0, var int CondIni_short0 = 0
var int CondIni_long = 0, var int CondIni_short = 0
var float last_open_longCondition = na, var float last_open_shortCondition = na
var int last_longCondition0 = na, var int last_shortCondition0 = na
var int last_longCondition = na, var int last_shortCondition = na
var bool long_tp = na, var bool short_tp = na
var int last_long_tp = na, var int last_short_tp = na
var bool Final_Long_tp = na, var bool Final_Short_tp = na
var bool SMI_longCond = na, var bool SMI_shortCond = na
var bool RSI_longCond = na, var bool RSI_shortCond = na
var bool ADX_longCond = na, var bool ADX_shortCond = na
var bool SAR_longCond = na, var bool SAR_shortCond = na
var bool Final_longCondition0 = na, var bool Final_shortCondition0 = na
var bool Final_longCondition = na, var bool Final_shortCondition = na

// ███▓▒░░ SQUEEZE MOMENTUM INDICATOR ░░▒▓███

Act_SMI = input(true, "SQUEEZE MOMENTUM INDICATOR")
BB_length = input(85, title="BOLLINGER BANDS LENGTH", minval = 1)
BB_mult = input(2.1, title="BOLLINGER BANDS MULTI-FACTOR", minval = 0.1, step = 0.1)
KC_length = input(38, title="KELTNER CHANNEL LENGTH", minval = 1)
KC_mult = input(2.0, title="KELTNER CHANNEL MULTI-FACTOR", minval = 0.1, step = 0.1)

SQUEEZE_M(_src,_BB_length,_BB_mult,_KC_length,_KC_mult)=>

    // Calculate BB
    basis = sma(_src, _BB_length)
    dev = _BB_mult * stdev(_src, _BB_length)
    upperBB = basis + dev
    lowerBB = basis - dev
    // Calculate KC
    ma = sma(src, _KC_length)
    rangema = sma(tr, _KC_length)
    upperKC = ma + rangema * _KC_mult
    lowerKC = ma - rangema * _KC_mult
    // Squeeze
    sqzOn = lowerBB > lowerKC and upperBB < upperKC
    sqzOff = lowerBB < lowerKC and upperBB > upperKC
    nosqz = sqzOn == false and sqzOff == false
    // Linear Regression curve
    val = linreg(_src - avg(avg(highest(high, _KC_length), lowest(low, _KC_length)), sma(close, _KC_length)), _KC_length, 0)
    [nosqz,val]
    
[NOSQZ,VAL] = SQUEEZE_M(src,BB_length,BB_mult,KC_length,KC_mult)

barcolor(iff(VAL > 0, iff(VAL > nz(VAL[1]), color.lime, color.green), iff(VAL < nz(VAL[1]), color.red, color.maroon)))

// ███▓▒░░ SAR ░░▒▓███

Act_SAR = input(true, "PARABOLIC SAR")
Sst = input (0.73, "SAR STAR", step=0.01, minval = 0.01)
Sinc = input (0.5, "SAR INC", step=0.01, minval = 0.01)
Smax = input (0.06, "SAR MAX", step=0.01, minval = 0.01)

SAR = sar(Sst, Sinc, Smax)
plot(SAR, style = plot.style_cross, title = "SAR")

// ███▓▒░░ RSI VOLUME WEIGHTED ░░▒▓███

Act_RSI = input(true, "RSI VOLUME WEIGHTED")
RSI_len = input(22, "RSI LENGHT", minval = 1)
RSI_obos = input(45,title="RSI CENTER LINE", type=input.integer, minval = 1)

WiMA(_src, _length)=> 
    var float MA_s=0.0
    MA_s:=(_src + nz(MA_s[1] * (_length-1)))/_length
    MA_s

RSI_Volume(fv, length)=>	
	up=iff(fv>fv[1],abs(fv-fv[1])*volume,0)
	dn=iff(fv<fv[1],abs(fv-fv[1])*volume,0)
	upt=WiMA(up,length)
	dnt=WiMA(dn,length)
	100*(upt/(upt+dnt))

RSI_V = RSI_Volume(src, RSI_len)

// ███▓▒░░ STRATEGY ░░▒▓███

SMI_longCond := (Act_SMI ? (VAL > 0 and (VAL > nz(VAL[1])) and not NOSQZ) : RSI_longCond) 
RSI_longCond := (Act_RSI ? (RSI_V > RSI_obos) : SAR_longCond)
SAR_longCond := (Act_SAR ? (SAR < close) : SMI_longCond)

SMI_shortCond := (Act_SMI ? (VAL < 0 and (VAL < nz(VAL[1])) and not NOSQZ) : RSI_shortCond) 
RSI_shortCond := (Act_RSI ? (RSI_V < RSI_obos) : SAR_shortCond)
SAR_shortCond := (Act_SAR ? (SAR > close) : SMI_shortCond)

longCond := SMI_longCond and RSI_longCond and SAR_longCond
shortCond := SMI_shortCond and RSI_shortCond and SAR_shortCond

CondIni_long0 := longCond ? 1 : shortCond ? -1 : CondIni_long0[1]
CondIni_short0 := longCond ? 1 : shortCond ? -1 : CondIni_short0[1]

longCondition0 = (longCond and CondIni_long0[1] == -1)
shortCondition0 = (shortCond and CondIni_short0[1] == 1)

CondIni_long := longCond[1] ? 1 : shortCond[1] ? -1 : CondIni_long[1]
CondIni_short := longCond[1] ? 1 : shortCond[1] ? -1 : CondIni_short[1]

longCondition = (longCond[1] and CondIni_long[1] == -1)
shortCondition = (shortCond[1] and CondIni_short[1] == 1)

// ███▓▒░░ ALERTS & SIGNALS ░░▒▓███

plotshape(longCondition, title = "Long Signal", style = shape.triangleup, location = location.belowbar, color = color.blue, transp = 0, size = size.tiny)
plotshape(shortCondition, title = "Short Signal", style = shape.triangledown, location = location.abovebar, color = #FF0000, transp = 0, size = size.tiny)

//alertcondition(longCondition, title="Long Alert", message = "LONG") 
//alertcondition(shortCondition, title="Short Alert", message = "SHORT")

// ███▓▒░░ BACKTESTING ░░▒▓███

testStartYear = input(2018, "BACKTEST START YEAR", minval = 1980, maxval = 2222) 
testStartMonth = input(01, "BACKTEST START MONTH", minval = 1, maxval = 12)
testStartDay = input(01, "BACKTEST START DAY", minval = 1, maxval = 31)
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
testStopYear = input(2222, "BACKTEST STOP YEAR", minval=1980, maxval = 2222)
testStopMonth = input(12, "BACKTEST STOP MONTH", minval=1, maxval=12)
testStopDay = input(31, "BACKTEST STOP DAY", minval=1, maxval=31)
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)

testPeriod = time >= testPeriodStart and time <= testPeriodStop ? true : false

strategy.entry("Long", strategy.long, when = longCondition0 and testPeriod)
strategy.entry("Short", strategy.short, when = shortCondition0 and testPeriod)


Больше