Стратегии прорыва тренда


Дата создания: 2023-09-28 15:54:32 Последнее изменение: 2023-09-28 15:54:32
Копировать: 1 Количество просмотров: 701
1
Подписаться
1617
Подписчики

Обзор

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

Стратегический принцип

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

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

Кроме того, он также обнаруживает K-линии, требуя, чтобы несколько K-линий были упорядочены для фильтрации ложных прорывов; и рассчитывает показатели динамики цены, чтобы избежать того, чтобы рынок был заперт в колебаниях внутри канала; добавляет показатели объема торговли, чтобы гарантировать, что время прорыва может следовать.

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

Анализ преимуществ

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

  1. Комбинация многоканальных и скользящих средних позволяет снизить вероятность ошибочных выводов.

  2. Проверка последовательности K-линий, чтобы избежать ошибочного сигнала от одной инородной K-линии.

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

  4. Включение количественного энергетического показателя позволит избежать недействительного прорыва, только если количество будет появляться вместе с ценой.

  5. Адаптированный механизм остановки убытков позволяет максимально закрепить трендовую прибыль при условии гарантированного остановки убытков.

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

Анализ рисков

Несмотря на значительные улучшения в этой стратегии, связанные с фильтрацией фальшивых взломов и перехватов, существуют некоторые риски, о которых следует помнить:

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

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

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

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

  5. Эта стратегия относится к категории стратегий отслеживания тенденций, которые плохо работают на консолидированных волатильных рынках.

В ответ на эти риски рекомендуется принять следующие меры по их борьбе:

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

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

  3. Можно рассмотреть возможность внедрения более продвинутых моделей расчета волатильности, таких как хедж-фонды.

  4. Обратитесь к базовой информации, чтобы избежать торговли только на основе технических показателей.

  5. Повышение оценки состояния рынка, приостановка торговли в нестабильных рынках.

Направление оптимизации

В этой стратегии есть несколько пунктов, которые можно улучшить:

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

  2. Повышение оценки состояния рынка, например, повышение оценки тренда или колебания, приостановка торговли на колебательных рынках, чтобы избежать ненужных потерь.

  3. Оптимизация стратегии по прекращению убытков, можно рассмотреть другие способы прекращения убытков, такие как отслеживание убытков, соотношение убытков.

  4. Добавление фундаментальных факторов, предупреждение о крупных фундаментальных событиях, чтобы избежать убытков только из-за технических показателей.

  5. Оптимизация портфеля, объединение этой стратегии с другими не связанными портфелями стратегий, может способствовать дальнейшему распространению риска.

  6. Присоединение к системе количественного трейдинга, автоматическое исполнение сигналов и строгий контроль риска.

Подвести итог

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

Исходный код стратегии
/*backtest
start: 2022-09-21 00:00:00
end: 2023-09-27 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Extremely Overfit", overlay=true, commission_type=strategy.commission.percent, commission_value=.16, default_qty_type=strategy.percent_of_equity, default_qty_value=100, pyramiding = 1)
price = close

goLong = input(title="go long?", type=input.bool, defval=true)
goShort = input(title="go short?", type=input.bool, defval=true)
//trendRestrict = input(title="basic trend restriction?", type=input.bool, defval=false)
dynamicRestrict = true //input(title="dynamic trend restriction?", type=input.bool, defval=true)
longtrendimpt = true //input(title="additional weight on long-term trends?", type=input.bool, defval=true)
volRestrict = true //input(title="volume restriction?", type=input.bool, defval=true)
conservativeClose = false //input(title="conservative order closing?", type=input.bool, defval=false)

Restrictiveness = input ( -40,step=10,title ="Restrictiveness (higher = make fewer trades)")
volatilityImportance = 3.2 //input( 3.2, step = 0.1, minval = 0)
fastChannelLength = input( 6 )
fastChannelMargin = input ( 3.2, step = 0.1, minval = 0)
slowChannelLength = input ( 6, step = 1, minval = 0)
slowChannelMargin = input ( 1.5, step = 0.1, minval = 0)
fastHMAlength = input (4, step = 1, minval = 0)
stopLoss = input( 3, step = 0.1, minval = 0)
//altClosePeriod = input( 27, step = 1, minval = 1)
//altCloseFactor = input( 4.9, step = 0.1)
stopLossFlexibility = 50 //input(50, step=10, title="effect of volatility on SL?")
volumeMAlength = 14 //input ( 14, step = 1, minval = 1)
volumeVolatilityCutoff = 3.8 // ( 3.8, step = 1, minval = 0)
trendSensitivity = 3.8 //input ( 3.8, step = 0.1)
obvLookback = 10 //input(10, step = 10, minval = 10)
obvCorrThreshold = 0.89 //input(0.89, step = 0.01)
ROClength = 80 //input( 80, step = 10)
ROCcutoff = 5.6 //input( 5.6, step=0.1)

trendRestrict = false
//trendLookback = input ( 360, step = 10, minval = 10)
//longTrendLookback = input(720, step = 10, minval = 10)
//longTrendImportance = input(1.5, step = 0.05)
trendLookback = 360
longTrendLookback = 720
longTrendImportance = 1.5

//conservativeness = input( 2.4, step = 0.1)
conservativeness = 0
//trendPower = input( 0, step=1)
trendPower = 0
//conservativenessLookback = input( 650, step = 10, minval = 0)
conservativenessLookback = 10
//consAffectFactor = input( 0.85,step=0.01)
consAffectFactor = 0.85
//volatilityLookback = input(50, step=1, minval=2)
volatilityLookback = int(50)
recentVol = stdev(price,volatilityLookback)/sqrt(volatilityLookback)

//price channel

fastChannel = ema(price, fastChannelLength)
fastChannelUB = fastChannel * (1 + (float(fastChannelMargin) / 1000)) + (recentVol * (float(volatilityImportance) * (1 + (Restrictiveness/100))))
fastChannelLB = fastChannel * (1 - (float(fastChannelMargin) / 1000)) - (recentVol * (float(volatilityImportance) * (1 + (Restrictiveness/100))))
fchU = ((fastChannelUB < open) and (fastChannelUB < close))
fchL = ((fastChannelLB > open) and (fastChannelLB > close))
//plot(fastChannelUB)
//plot(fastChannelLB)

//slow channel
//slowChannelLBmargin = input ( 2, step = 0.1, minval = 0 )
slowChannel = ema(ema(price,slowChannelLength),slowChannelLength)
slowChannelUB = slowChannel * (1 + (float(slowChannelMargin) / 2000)) + (recentVol * (float(volatilityImportance) * (1 + (Restrictiveness/100))))
slowChannelLB = slowChannel * (1 - (float(slowChannelMargin) / 2000)) - (recentVol * (float(volatilityImportance) * (1 + (Restrictiveness/100))))
schU = ((slowChannelUB < close))
schL = ((slowChannelLB > close))
cschU = (((slowChannelUB * (1 + conservativeness)) < close))
cschL = (((slowChannelUB * (1 - conservativeness)) > close))
//plot(slowChannel,color = #00FF00)
//plot(slowChannelUB,color = #00FF00)
//plot(slowChannelLB,color = #00FF00)


fastHMA = hma(price,fastHMAlength)
fastAboveUB = (fastHMA > slowChannelUB)
fastBelowLB = (fastHMA < slowChannelLB)
//plot(fastHMA, color = 	#FF0000, linewidth = 2)

//consecutive candles
//consecutiveCandlesReq = input(1, step = 1, minval = 1, maxval = 4)
consecutiveCandlesReq = 1
consecutiveBullReq = float(consecutiveCandlesReq)
consecutiveBearReq = float(consecutiveCandlesReq)
cbull = ((close[0] > close[1]) and (consecutiveBullReq == 1)) or (((close[0] > close[1]) and (close[1] > close[2])) and consecutiveBullReq == 2) or (((close[0] > close[1]) and (close[1] > close[2]) and (close[2] > close[3])) and consecutiveBullReq == 3) or (((close[0] > close[1]) and (close[1] > close[2]) and (close[2] > close[3]) and (close[3] > close[4])) and consecutiveBullReq == 4)
cbear = ((close[0] < close[1]) and (consecutiveBearReq == 1)) or (((close[0] < close[1]) and (close[1] < close[2])) and consecutiveBearReq == 2) or (((close[0] < close[1]) and (close[1] < close[2]) and (close[2] < close[3])) and consecutiveBearReq == 3) or (((close[0] < close[1]) and (close[1] < close[2]) and (close[2] < close[3]) and (close[3] < close[4])) and consecutiveBearReq == 4)

//trend detection
//trendCutoff = input(0, step = 0.1)
trendCutoff = 0
trendDetectionPct = float(trendCutoff/100)
trendVal = float((close[0] - close[trendLookback])/close[0])
trendUp = (trendVal > (0 + trendDetectionPct))
trendDown = (trendVal < (0 - trendDetectionPct))
//plot(trendVal+36.5,linewidth=2)

// peak indicators
peakHigh = ((fastHMA > fastChannelUB) and (fastChannelLB > slowChannelUB))
peakLow = ((fastHMA < fastChannelLB) and (fastChannelUB < slowChannelLB))
TpeakHigh = (fastHMA > fastChannelUB) and (fastChannelUB > slowChannelUB)
TpeakLow = (fastHMA < fastChannelUB) and (fastChannelLB < slowChannelLB)
//TpeakHigh = (fastHMA > fastChannelUB) and (fastChannelLB > avg(slowChannelUB,slowChannelLB))
//TpeakLow = (fastHMA < fastChannelUB) and (fastChannelUB < avg(slowChannelLB,slowChannelUB))
//TpeakHigh = ((crossover(fastHMA,fastChannelUB)) and (fastChannelLB > slowChannelUB))
//TpeakLow = ((crossover(fastChannelLB,fastHMA)) and (fastChannelUB < slowChannelLB))
//TpeakHigh = (fastHMA > (fastChannelUB * (1 + (trendPower/800)))) and (fastChannelUB > (slowChannelUB * (1 + (trendPower/800))))
//TpeakLow = (fastHMA < (fastChannelUB * (1 - (trendPower/800)))) and (fastChannelLB < (slowChannelLB * (1 - (trendPower/800))))
//TpeakHigh = (fastHMA > (fastChannelUB * (1 + (trendPower/800)))) and (avg(fastChannelUB,fastChannelLB) > (slowChannelUB * (1 + (trendPower/800))))
//TpeakLow = (fastHMA < (fastChannelUB * (1 - (trendPower/800)))) and (avg(fastChannelLB,fastChannelUB) < (slowChannelLB * (1 - (trendPower/800))))
//plot(fastChannelUB * (1 + (trendPower/700)), color=#FF69B4)

// and for closing...
closeLong = (crossover(fastHMA,fastChannelUB) and (fastChannelLB > slowChannelUB))
closeShort = (crossover(fastChannelLB,fastHMA) and (fastChannelUB < slowChannelLB))
//closeLong = (crossover(fastHMA,fastChannelUB) and (fastChannelLB > slowChannelUB)) or (roc(price,altClosePeriod) > altCloseFactor)
//closeShort = (crossover(fastChannelLB,fastHMA) and (fastChannelUB < slowChannelLB))  or (roc(price,altClosePeriod) < (altCloseFactor) * -1)
//closeLong = (crossover(fastHMA,fastChannelUB) and (fastChannelLB > slowChannelUB)) or (((price - fastChannelUB) > (altCloseFactor * abs(((fastChannelUB - fastChannelLB)/2) - ((slowChannelUB - slowChannelLB)/2)))) and (fastChannelLB > slowChannelUB))
//closeShort = (crossover(fastChannelLB,fastHMA) and (fastChannelUB < slowChannelLB)) or (((fastChannelLB - price) > (altCloseFactor * abs(((fastChannelUB - fastChannelLB)/2) - ((slowChannelUB - slowChannelLB)/2)))) and (fastChannelUB < slowChannelLB))
//closeLong = crossover(fastHMA,fastChannelUB) and ((fastChannelLB[0] - fastChannelLB[1]) < (slowChannelUB[0] - slowChannelUB[1]))
//closeShort = crossover(fastChannelLB,fastHMA) and ((fastChannelUB[0] - fastChannelUB[1]) > (slowChannelLB[0] - slowChannelLB[1]))


//stop-loss
priceDev = stdev(price,trendLookback) * (1 + stopLossFlexibility/5)
stopLossMod = stopLoss * (1 + (priceDev/price))
//longStopPrice  = strategy.position_avg_price * (1 - (stopLoss/100))
//shortStopPrice = strategy.position_avg_price * (1 + (stopLoss/100))
longStopPrice  = strategy.position_avg_price * (1 - (stopLossMod/100))
shortStopPrice = strategy.position_avg_price * (1 + (stopLossMod/100))


// volume
volumeMA = ema(volume,volumeMAlength)
volumeDecrease = ((not volRestrict ) or (volumeMA[0] < ema(volumeMA[1] * (1 - (volumeVolatilityCutoff/100)),5)))
volumeCutoff = ema(volumeMA[1] * (1 - (volumeVolatilityCutoff/100)),5)
//plot(volumeMA)
//plot(volumeCutoff)

// detect volatility
//trendinessLookback = input ( 600, step = 10, minval = 0)
trendinessLookback = trendLookback
trendiness = (stdev(price,trendinessLookback)/price) * (1 - (Restrictiveness/100))
longtermTrend = ((price - price[longTrendLookback])/price)
//dynamicTrendDetected = (dynamicRestrict and (abs(trendiness * 100) < trendSensitivity))
dynamicTrendDetected = (longtrendimpt and (dynamicRestrict and (abs(trendiness * 100) < (trendSensitivity+(longtermTrend * longTrendImportance))))) or (not longtrendimpt and ((dynamicRestrict and (abs(trendiness * 100) < trendSensitivity))))

// adapt conservativeness to volatility

//consVal = sma(((stdev(price,conservativenessLookback))/price)*100,25)
consVal = sma(((stdev(price,conservativenessLookback))/price)*100,25)
cVnorm = sma(avg(consVal,3),60)
cVal = consVal - cVnorm

//conservativenessMod = conservativeness * (cVal * consAffectFactor)
conservativenessMod = conservativeness * (consVal * consAffectFactor)
//plot(consVal,linewidth=4)
//plot(cVnorm,color = #00FF00)
//plot(cVal,linewidth=2)

// ROC cutoff (for CLOSING)
//rocCloseLong = (ema(roc(price,ROClength),10) > ROCcutoff)
//rocCloseShort = (ema(roc(price,ROClength),10) < (ROCcutoff * -1))
ROCval = roc(price,ROClength)
ROCema = ema(ROCval,30)
ROCabs = abs(ROCema)
ROCallow = ROCabs < ROCcutoff
ROCallowLong = (ROCabs < ROCcutoff)  or ((ROCabs >= ROCcutoff) and ((fastChannelLB < slowChannelLB) and (fastHMA < fastChannelLB)))
ROCallowShort = (ROCabs < ROCcutoff) or ((ROCabs >= ROCcutoff) and ((fastChannelUB > slowChannelUB) and (fastHMA > fastChannelUB)))
//plot(ROCallow)

// obv
evidence_obv = (correlation(price,obv[0],obvLookback))
obvAllow = evidence_obv > obvCorrThreshold


//if (not na(vrsi))
if trendRestrict or dynamicTrendDetected
    //if (strategy.position_size == 0)
    if not (strategy.position_size < 0)
        if trendUp
        	//if cbear and schL and fchL and trendUp and goLong
        	if cbear and TpeakLow and volumeDecrease and ROCallow and goLong and obvAllow
        	//if cbear and peakLow and rocHigh and volumeDecrease and goLong
        		strategy.entry("Long", strategy.long, comment="Long")
    if not (strategy.position_size > 0)
        if trendDown
        	//if cbull and schU and fchU and trendDown and goShort
        	if cbull and TpeakHigh and volumeDecrease and ROCallow and goShort and obvAllow
        	//if cbull and peakHigh and rocLow and volumeDecrease and goShort
        		strategy.entry("Short", strategy.short, comment="Short")
else
    //if (strategy.position_size == 0)
    if not (strategy.position_size < 0)
        //if cbear and peakLow and goLong
    	//if cbear and peakLow and volumeDecrease and ROCallow and goLong
    	if TpeakLow and goLong and obvAllow
    		strategy.entry("Long", strategy.long, comment="Long")
    if not (strategy.position_size > 0)
        //if cbull and peakHigh and goShort
    	//if cbull and peakHigh and volumeDecrease and ROCallow and goShort
    	if TpeakHigh and goShort and obvAllow
    		strategy.entry("Short", strategy.short, comment="Short")

if conservativeClose
    //pkHigh = ((fastHMA > fastChannelUB) and (fastChannelUB > (slowChannelUB * (1 + conservativeness/1000))))
    //pkLow = ((fastHMA < fastChannelLB) and (fastChannelLB < (slowChannelLB * (1 - conservativeness/1000))))
    //pkHigh = ((fastHMA > fastChannelUB) and (fastChannelUB > (slowChannelUB * (1 + conservativenessMod/1000))))
    //pkLow = ((fastHMA < fastChannelLB) and (fastChannelLB < (slowChannelLB * (1 - conservativenessMod/1000))))
    pkHigh = ((fastHMA > fastChannelUB) and (fastChannelUB > (slowChannelUB * (1 + ((conservativenessMod/1000) * (1 - Restrictiveness/100))))))
    pkLow = ((fastHMA < fastChannelLB) and (fastChannelLB < (slowChannelLB * (1 - ((conservativenessMod/1000) * (1 - Restrictiveness/100))))))
    
    if (strategy.position_size > 0)
        //if fastAboveUB
        //if pkHigh and closeLong
        if closeLong
    		strategy.close("Long", comment="closeLong")
    if (strategy.position_size < 0)
        //if fastBelowLB
        //if pkLow and closeShort
        if closeShort
    		strategy.close("Short", comment="closeShort")
else
    if (strategy.position_size > 0)
        //if fastAboveUB
        if peakHigh
    		strategy.close("Long", comment="closeLong")
    if (strategy.position_size < 0)
        //if fastBelowLB
        if peakLow
    		strategy.close("Short", comment="closeShort")

if (strategy.position_size > 0)
    strategy.exit(id="Long", stop=longStopPrice, comment="stopLong")

if (strategy.position_size < 0)
    strategy.exit(id="Short", stop=shortStopPrice, comment="stopShort")
//plot(strategy.equity, title="equity", color=color.red, linewidth=2, style=plot.style_areabr)