La stratégie vise à capturer les fortes tendances du marché de la crypto-monnaie, en utilisant des signaux de formation de tendances à l’aide de canaux multiples et de moyennes mobiles, et en combinant la capacité de filtrage quantitatif pour les fausses ruptures, tout en utilisant des arrêts de perte adaptatifs pour se bloquer sur les gains, qui peuvent être réalisés dans un marché tendance.
La stratégie utilise une combinaison de la voie rapide, la voie lente et la moyenne mobile rapide pour identifier les tendances. Les paramètres de la voie rapide sont plus sensibles pour capturer les fluctuations de prix à court terme; les paramètres de la voie lente sont plus lents pour juger des grandes tendances; les paramètres de la voie rapide sont intermédiaires et génèrent un signal de transaction lorsqu’ils traversent la voie.
En particulier, il calcule d’abord le haut et le bas de la voie rapide, ainsi que la moyenne mobile. Lorsque le prix franchit la voie supérieure, il génère un signal de plus si la voie inférieure de la voie lente est également au-dessus de la moyenne mobile; à l’inverse, lorsqu’il franchit la voie inférieure pour déterminer si la voie supérieure de la voie lente est en dessous de la moyenne mobile, il génère un signal de vide.
En outre, il détecte la forme des lignes K, exige que les lignes K soient disposées de manière séquentielle pour filtrer les fausses ruptures; et calcule les indicateurs de volatilité des prix, afin d’éviter que les marchés ne soient pris au piège dans les fluctuations de la chaîne; ajout d’un indicateur de volume de transactions pour s’assurer que les temps de rupture suivent.
Pour ce qui est de l’arrêt des pertes, la stratégie utilise un arrêt adaptatif. L’amplitude de l’arrêt est ajustée dynamiquement en fonction de la volatilité de la période la plus récente. Cela permet de retracer autant de tendances que possible tout en garantissant l’arrêt des pertes.
Le plus grand avantage de cette stratégie réside dans le fait que les règles de jugement pour la formation de signaux de négociation sont plus strictes, ce qui permet de filtrer efficacement les fausses ruptures non tendancielles et de vraiment capturer les points de retournement de la tendance du marché. Plus précisément, il y a principalement les aspects suivants:
Les combinaisons de multiples canaux et de moyennes mobiles permettent de réduire la probabilité d’erreurs de jugement.
Les lignes K sont rangées dans l’ordre de vérification afin d’éviter que les lignes K isoconiques produisent un mauvais signal.
En combinant les indicateurs de variation des prix, il est possible de déterminer si la correction est effectuée et d’éviter de rater une occasion de reprise.
L’ajout d’indicateurs de quantité d’énergie ne génère un signal que si la quantité apparaît avec le prix, évitant ainsi une rupture inefficace.
Les mécanismes d’arrêt de perte adaptatifs permettent de bloquer au maximum les bénéfices de la tendance, à condition de garantir l’arrêt des pertes.
L’ensemble de la stratégie est donc parfaitement adapté pour capturer les tendances, avec des caractéristiques telles que l’optimisation de la configuration, la rigueur de la décision et l’adaptation au freinage.
Malgré les améliorations apportées à la stratégie de filtrage des fausses intrusions et des tendances d’interception, il y a encore des risques à prendre en compte:
La configuration des paramètres est trop compliquée, les combinaisons de paramètres varient considérablement, il faut effectuer de nombreux tests pour trouver le paramètre optimal, et une configuration inappropriée peut générer trop de signaux erronés.
Les moyennes rapides et les intervalles de passage au-delà de l’heure sont susceptibles de générer des positions ouvertes et fermées fréquentes, ce qui ne favorise pas un suivi de tendance durable.
Le calcul de la suspension des pertes par le mécanisme d’arrêt automatique est basé sur un écart-type simple, qui peut être trop faible pour les situations extrêmes.
L’excès de dépendance à l’égard des indicateurs techniques rend difficile la réaction face à des changements majeurs dans les fondamentaux.
Cette stratégie est une stratégie de suivi de tendance qui se comporte mal dans les marchés volatiles.
Pour contrer ces risques, il est recommandé de prendre les mesures suivantes:
Il est également possible d’envisager d’optimiser les paramètres en utilisant des méthodes telles que l’apprentissage automatique.
L’élargissement approprié de l’intervalle entre les canaux et le cycle de la moyenne mobile peuvent également être prolongés de manière appropriée, ce qui réduit la fréquence inutile d’ouverture de la position.
L’introduction de modèles de calcul de la volatilité plus avancés tels que les hedge funds peut être envisagée.
Il est recommandé de consulter les informations de base en temps opportun et d’éviter de négocier uniquement avec des indicateurs techniques.
L’augmentation du jugement sur l’état du marché et la suspension des transactions dans les marchés en crise.
La stratégie peut être améliorée dans les domaines suivants:
L’ajout d’algorithmes d’apprentissage automatique permet l’optimisation automatique des paramètres. Les performances des paramètres peuvent être enregistrées dans différents environnements de marché, des tableaux de requêtes peuvent être créés et l’optimisation dynamique est possible.
Augmenter le jugement sur l’état du marché, par exemple en ajoutant des modules pour juger si la situation est tendancielle ou oscillante, suspendre la négociation dans un marché oscillant et éviter des pertes inutiles.
Optimiser les stratégies de stop loss, et envisager d’autres méthodes de stop loss comme le suivi des stops, le stop loss proportionnel, etc.
L’ajout de facteurs fondamentaux et l’alerte en cas d’événements fondamentaux majeurs permettent d’éviter les pertes liées uniquement aux indicateurs techniques.
L’optimisation du portefeuille, qui consiste à associer cette stratégie à d’autres portefeuilles non pertinents, permet de diffuser davantage le risque.
L’intégration d’un cadre de trading quantifié, d’une exécution automatique des signaux et d’un contrôle strict des risques.
Dans l’ensemble, la stratégie est parfaitement adaptée pour capturer les opportunités de tendance dans le marché de la crypto-monnaie. Elle utilise des signaux de négociation multicanaux et des moyennes mobiles, et filtre efficacement le bruit des fausses percées, et réussit à bloquer les bénéfices de la tendance.
/*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)