Cette stratégie utilise les bandes de Bollinger, les canaux Keltner et l'indice de force relative adaptative pour déterminer la direction de la tendance actuelle, combinée avec le SAR parabolique pour chronométrer l'entrée. Les signaux de trading sont générés lorsque les jugements de ces trois indicateurs s'accordent.
Cette stratégie combine les trois indicateurs techniques suivants pour déterminer la tendance actuelle:
SQUEEZE Momentum Indicator: Calcule les bandes de Bollinger et les canaux de Keltner. Lorsque les deux bandes se chevauchent, il génère une pression et signale un changement de tendance imminent. Il renvoie l'état de pression et la pente de régression linéaire.
RSI pondéré par volume: Calcule le RSI pondéré par volume. Utilise le point médian pour déterminer les niveaux de surachat/survente. Il met l'accent sur les changements de volume.
SAR parabolique: juge l'emplacement du prix actuel par rapport à la ligne SAR.
La stratégie utilise les bandes de Bollinger pour déterminer la direction de la tendance, les canaux Keltner pour l'affiner, le RSI pour trouver des opportunités d'inversion en cas de surachat/survente et le SAR pour chronométrer l'entrée.
Calculer les bandes de Bollinger, les canaux de Keltner, l'indicateur de compression.
Calculer le RSI pondéré par volume. Le RSI au-dessus du point médian indique une tendance haussière, au-dessous du point médian une tendance baissière.
Calculer SAR parabolique. SAR en dessous du prix montre tendance haussière, au-dessus du prix montre tendance à la baisse.
Combinez les trois indicateurs: lorsque la contraction se produit, le RSI va au-dessus du point médian, le SAR est en dessous du prix, un signal long est généré.
Lorsque le signal est déclenché, vérifiez si les jugements des trois indicateurs de la barre précédente sont l'opposé du signal actuel.
Mettez un stop-loss et prenez des profits après l'entrée, en suivant un stop-loss.
Les avantages de cette stratégie:
La combinaison de plusieurs indicateurs améliore la précision du jugement de tendance. Squeeze détecte avec précision les changements de tendance, RSI identifie clairement les niveaux de surachat/survente, SAR multiplie précisément l'entrée.
La logique de l'indicateur est simple et facile à comprendre.
La confirmation de plusieurs indicateurs aide à filtrer les fausses éruptions.
Les mécanismes d'arrêt des pertes et de prise de profit bloquent les bénéfices et limitent les risques.
Des données de backtests étendues assurent la fiabilité.
Il y a aussi des risques:
La logique d'entrée longue et courte est similaire et peut générer des signaux contradictoires.
Tous les indicateurs utilisent l'optimisation des paramètres, les risques de surajustement.
La fréquence des transactions est élevée, la taille des positions doit être contrôlée.
L'arrêt de perte peut être trop proche et être facilement arrêté.
Les solutions:
Ajouter une vérification de la persistance des jugements des indicateurs pour éviter les oscillations du signal.
Utilisez l'analyse de marche en avant pour ajuster les paramètres et prévenir le surajustement.
Réglez la taille de la pyramide pour contrôler les positions par direction.
Testez différentes gammes de stop loss pour optimiser le prix de stop loss.
Quelques orientations pour optimiser la stratégie:
Optimiser les paramètres de l'indicateur pour la stabilité.
Ajoutez une logique de dimensionnement de position comme pourcentage fixe/égal.
Testez différentes méthodes de stop loss comme la volatilité ou les stops linéaires, les positions de mise à zéro, etc.
Ajoutez la gestion de l'argent comme le dimensionnement des positions fractionnaires fixes.
Utiliser des modèles d'apprentissage automatique pour une entrée et une sortie dynamiques.
Ajouter des mécanismes de couverture en allant à la fois long et court pour réduire les risques systémiques corrélés.
Considérez plus d'indicateurs et construisez des mécanismes de vote pour améliorer la précision.
La stratégie a une logique claire consistant à utiliser plusieurs indicateurs pour déterminer la direction de la tendance et à entrer astucieusement dans la compression. La mécanique de stop loss et de prise de profit limite les risques. L'optimisation des paramètres et les contrôles des risques peuvent améliorer encore les résultats des backtests et des tests en direct.
/*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)