Эта стратегия направлена на захват сильных тенденций на рынках криптовалют с использованием нескольких каналов и скользящих средних для выявления сигналов тренда, и сочетает в себе показатели объема для фильтрации ложных прорывов, при этом адаптивно останавливая потери для закрепления прибыли, позволяя получать прибыль на трендовых рынках.
Стратегия использует комбинацию быстрого канала, медленного канала и быстрого скользящего среднего для выявления тенденций. Параметры быстрого канала более чувствительны для улавливания краткосрочных колебаний цен; параметры медленного канала более умеренны для оценки основного тренда; параметры быстрого скользящего среднего находятся посередине, генерируя торговые сигналы, когда он проходит через канал.
Когда цена проходит через верхнюю рельсу, если нижняя рельса медленного канала также выше скользящей средней, генерируется длинный сигнал; наоборот, когда она проходит через нижнюю рельсу, она проверяет, находится ли верхняя рельса медленного канала ниже скользящей средней, генерируя короткий сигнал.
Кроме того, он обнаруживает K-линию, требуя, чтобы несколько K-линий были расположены в последовательности, чтобы отфильтровать ложные прорывы; и рассчитывает показатель коэффициента изменения цены, чтобы определить, вступил ли он в консолидацию, чтобы избежать упущенных возможностей для отмены; и включает показатели объема, чтобы гарантировать, что объем следует за ценой при прорыве.
Для стоп-лосса стратегия использует адаптивные стоп-лосы. Основываясь на недавней волатильности, она динамически корректирует процент стоп-лоса. Это позволяет зафиксировать как можно больше прибыли от тренда, обеспечивая эффективную стоп-лосс.
Наибольшее преимущество этой стратегии заключается в том, что критерии для генерации торговых сигналов относительно строги, что может эффективно отфильтровать ложные прорывы, не связанные с трендом, и действительно улавливать поворотные моменты в рыночных тенденциях.
Комбинация нескольких каналов и скользящих средних имеет более строгие критерии и может уменьшить вероятность ошибочного суждения.
K-линейная последовательность позволяет избежать ошибочных сигналов от одной аберрантной K-линии.
Включение показателя изменения курса цен может определить, вступил ли он в консолидацию, чтобы избежать упущенных возможностей для реверсии.
Добавление суждения по показателю объема гарантирует, что сигналы генерируются только тогда, когда объем следует за ценой, избегая неэффективного прорыва.
Механизм адаптивного стоп-лосса может максимизировать блокировку прибыли от тренда, обеспечивая при этом стоп-лосс.
Таким образом, в целом, эта стратегия имеет характеристики оптимизированной конфигурации, разумного принятия решений, адаптивной стоп-лосс, что делает ее очень подходящей для захвата трендовых возможностей.
Несмотря на то, что эта стратегия сделала большую оптимизацию в фильтрации ложных прорывов и захвате тенденций, все еще есть некоторые риски, которые следует отметить:
Сложные параметры могут привести к большим различиям между параметровыми комбинациями, что требует обширных испытаний для поиска оптимальных параметров, иначе это может генерировать слишком много ложных сигналов.
Когда разрыв между быстрой скользящей средней и каналом слишком мал, он имеет тенденцию генерировать частые входы и выходы, что не способствует постоянному отслеживанию тенденций.
Процентный расчет стоп-лосса в механизме адаптивного стоп-лосса основан на простом стандартном отклонении, которое может привести к недостаточному стоп-лос в экстремальных рыночных условиях.
Он в значительной степени основан на технических показателях и может не реагировать на серьезные фундаментальные изменения.
Как стратегия, следующая за тенденцией, он показывает низкие результаты на нестабильных рынках.
Для борьбы с этими рисками рекомендуются следующие меры:
Провести достаточное обратное тестирование для определения оптимальных комбинаций параметров или рассмотреть возможность использования машинного обучения для оптимизации параметров.
Умеренно расширяйте интервалы каналов, увеличивайте периоды скользящей средней, чтобы уменьшить ненужные записи.
Подумайте о внедрении более продвинутых моделей волатильности, таких как методы хедж-фондов.
Ссылаться на основную информацию своевременно, чтобы избежать чисто технической торговли.
Усилить суждение о состоянии рынка и приостановить торговлю на нестабильных рынках.
Стратегия может быть дополнительно оптимизирована следующими способами:
Внедрение алгоритмов машинного обучения для достижения автоматической оптимизации параметров путем записи производительности параметров в различных рыночных средах для создания таблицы поиска для динамической оптимизации.
Добавьте суждение о состоянии рынка, например, добавьте модули, чтобы определить, является ли рынок тенденционным или неуравновешенным, и приостановить торговлю на неуравновешенных рынках, чтобы избежать ненужных потерь.
Оптимизировать стратегии стоп-лосса, такие как отслеживание стоп-лосса, пропорциональный стоп-лосс и т.д.
Включить фундаментальные факторы для отправки предупреждений при возникновении крупных фундаментальных событий, избегая потерь, основанных исключительно на технических показателях.
Провести оптимизацию портфеля, объединив эту стратегию с другими стратегиями, не связанными с ней, для дальнейшей диверсификации рисков.
Ввести количественную торговую систему для автоматизированного исполнения сигналов и строгого контроля рисков.
В общем, эта стратегия очень подходит для захвата трендовых возможностей на рынках криптовалют. Она использует несколько каналов и скользящие средние для генерации торговых сигналов, эффективно фильтрует ложный шум прорыва и успешно блокирует прибыль от тренда. Но оптимизация параметров, методы остановки потерь, суждение о состоянии рынка и т. Д. Все еще нуждаются в внимании. При постоянном улучшении она имеет потенциал для стабильной доходности от инвестиций.
/*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)