I. Vue d'ensemble de la stratégie
Cette stratégie s'appelle
II. Principe de stratégie
Identifiez les points extrêmes du prix en utilisant les bandes de Bollinger pour obtenir la ligne ZigZag.
Reconnaître les modèles ABCD complets sur la ligne ZigZag. Les points A, B, C et D doivent répondre à certaines relations proportionnelles.
Réglez le stop-loss après l'ouverture des positions pour contrôler les risques. Utilisez d'abord le stop-loss fixe, passez au stop-loss pour verrouiller certains profits après avoir atteint un certain niveau de profit.
De même, la prise de bénéfices de suivi est également réglée pour obtenir suffisamment de bénéfices dans le temps et éviter les pertes.
Fermez les positions lorsque le prix atteint le seuil de stop loss ou de profit pour terminer un cycle commercial.
III. Analyse des avantages
L'utilisation des bandes de Bollinger pour identifier la ligne ZigZag évite de repeindre les problèmes du ZigZag traditionnel, rendant les signaux de trading plus fiables.
Le modèle de trading ABCD est mature et stable avec des opportunités de trading adéquates.
Les paramètres de stop-loss et de prise de profit en deux étapes permettent de mieux contrôler les risques et de sécuriser les bénéfices.
Une conception raisonnable des paramètres tels que les pourcentages d'arrêt de perte, de prise de profit et d'activation de suivi sont tous personnalisables pour plus de flexibilité.
La stratégie peut être utilisée pour tous les instruments de trading, y compris le forex, les crypto-monnaies, les indices boursiers, etc.
IV. Analyse des risques
Les opportunités de négociation des modèles ABCD sont encore limitées par rapport aux autres stratégies, ce qui ne garantit pas une fréquence suffisante.
Les paramètres nécessitent des ajustements tels que l'élargissement des plages stop loss / profit.
La liquidité des instruments de négociation doit être prise en considération.
La stratégie est sensible aux coûts de transaction. Les courtiers et les comptes à faible taux de commission sont préférés.
Certains paramètres peuvent être optimisés davantage, comme les niveaux d'activation pour le stop-loss et le take profit.
V. Directions d'optimisation
La combinaison avec d'autres indicateurs pour ajouter plus de filtres évite certains faux signaux et réduit les transactions inefficaces.
Ajoutez un jugement sur la structure du marché en trois sections, en n'effectuant que des transactions dans la troisième section.
Testez et optimisez le capital initial pour trouver le niveau optimal.
Effectuer une analyse de marche à l'avance avec des données hors échantillon pour examiner la robustesse des paramètres à long terme.
Continuer à optimiser les conditions d'activation et les tailles de glissement de la perte d'arrêt de trail et de profits pour améliorer l'efficacité.
Résumé de la stratégie
La stratégie s'appuie principalement sur le modèle ABCD pour le timing et les entrées sur le marché. Les paramètres stop-loss et take profit à deux étapes sont utilisés pour gérer les risques et les bénéfices. La stratégie est relativement mature et stable, mais la fréquence de trading peut être faible. Nous pouvons obtenir des opportunités de trading plus efficaces en ajoutant des filtres et des conditions.
/*backtest start: 2024-02-11 00:00:00 end: 2024-02-18 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // @version=4 // @author=Daveatt - BEST // ABCD Pattern Strat StrategyName = "BEST ABCD Pattern Strategy (Trailing SL + TP)" ShortStrategyName = "BEST ABCD Strategy (Trailing)" strategy(title=StrategyName, shorttitle=ShortStrategyName, overlay=true ) filterBW = input(false, title="filter Bill Williams Fractals?") /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// UTILITIES /////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // ||-----------------------------------------------------------------------------------------------------|| // ||--- Fractal Recognition Functions: ---------------------------------------------------------------|| isRegularFractal(mode, _high, _low) => ret = mode == 1 ? _high[4] < _high[3] and _high[3] < _high[2] and _high[2] > _high[1] and _high[1] > _high[0] : mode == -1 ? _low[4] > _low[3] and _low[3] > _low[2] and _low[2] < _low[1] and _low[1] < _low[0] : false isBWFractal(mode, _high, _low) => ret = mode == 1 ? _high[4] < _high[2] and _high[3] <= _high[2] and _high[2] >= _high[1] and _high[2] > _high[0] : mode == -1 ? _low[4] > _low[2] and _low[3] >= _low[2] and _low[2] <= _low[1] and _low[2] < _low[0] : false /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ////////////////////////////// ABCD PATTERN /////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// f_abcd()=> _r = timeframe.period _g = barmerge.gaps_off _l = barmerge.lookahead_on _high = high _low = low filteredtopf = filterBW ? isRegularFractal(1, _high, _low) : isBWFractal(1, _high, _low) filteredbotf = filterBW ? isRegularFractal(-1, _high, _low) : isBWFractal(-1, _high, _low) // ||--- ZigZag: istop = filteredtopf isbot = filteredbotf topcount = barssince(istop) botcount = barssince(isbot) zigzag = (istop and topcount[1] > botcount[1] ? _high[2] : isbot and topcount[1] < botcount[1] ? _low[2] : na) x = valuewhen(zigzag, zigzag, 4) a = valuewhen(zigzag, zigzag, 3) b = valuewhen(zigzag, zigzag, 2) c = valuewhen(zigzag, zigzag, 1) d = valuewhen(zigzag, zigzag, 0) xab = (abs(b-a)/abs(x-a)) xad = (abs(a-d)/abs(x-a)) abc = (abs(b-c)/abs(a-b)) bcd = (abs(c-d)/abs(b-c)) // ABCD Part _abc = abc >= 0.382 and abc <= 0.886 _bcd = bcd >= 1.13 and bcd <= 2.618 _bull_abcd = _abc and _bcd and d < c _bear_abcd = _abc and _bcd and d > c _bull = _bull_abcd and not _bull_abcd[1] _bear = _bear_abcd and not _bear_abcd[1] [_bull, _bear, zigzag] lapos_x = timenow + round(change(time)*12) [isLong, isShort, zigzag] = f_abcd() plot(zigzag, title= 'ZigZag', color=color.black, offset=-2) plotshape(isLong, style=shape.labelup, location=location.belowbar, color=color.new(color.green, 0), size=size.normal, text="ABCD", textcolor=color.white) plotshape(isShort, style=shape.labeldown, location=location.abovebar, color=color.new(color.maroon, 0), size=size.normal, text="ABCD", textcolor=color.white) long_entry_price = valuewhen(isLong, close, 0) short_entry_price = valuewhen(isShort, close, 0) sinceNUP = barssince(isLong) sinceNDN = barssince(isShort) buy_trend = sinceNDN > sinceNUP sell_trend = sinceNDN < sinceNUP change_trend = (buy_trend and sell_trend[1]) or (sell_trend and buy_trend[1]) entry_price = buy_trend ? long_entry_price : short_entry_price /////////////////////////////// //======[ Trailing STOP ]======// /////////////////////////////// // use SL? useSL = input(true, "Use stop Loss") // Configure trail stop level with input StopTrailPerc = input(title="Trail Loss (%)", type=input.float, minval=0.0, step=0.1, defval=3) * 0.01 // Will trigger the take profit trailing once reached use_SL_Trigger = input(true, "Use stop Loss Trigger") StopTrailTrigger = input(2.0, "SL Trigger (%)",minval=0,step=0.5,type=input.float) * 0.01 StopLossPriceTrigger = 0.0 StopLossPriceTrigger := if (use_SL_Trigger) if buy_trend entry_price * (1 + StopTrailTrigger) else entry_price * (1 - StopTrailTrigger) else -1 var SL_Trigger_Long_HIT = false SL_Trigger_Long_HIT := useSL and use_SL_Trigger and buy_trend and high >= StopLossPriceTrigger ? true : SL_Trigger_Long_HIT[1] var SL_Trigger_Short_HIT = false SL_Trigger_Short_HIT := useSL and use_SL_Trigger and sell_trend and low <= StopLossPriceTrigger ? true : SL_Trigger_Short_HIT[1] display_long_SL_trigger = useSL and buy_trend and use_SL_Trigger and SL_Trigger_Long_HIT == false and StopLossPriceTrigger != -1 display_short_SL_trigger = useSL and sell_trend and use_SL_Trigger and SL_Trigger_Short_HIT == false and StopLossPriceTrigger != -1 display_SL_trigger = display_long_SL_trigger or display_short_SL_trigger plot(display_SL_trigger ? StopLossPriceTrigger : na, title='SLPriceTrigger', transp=0, color=color.maroon, style=plot.style_circles, linewidth=3) // Determine trail stop loss prices longStopPrice = 0.0, shortStopPrice = 0.0 longStopPrice := if useSL and buy_trend stopValue = low * (1 - StopTrailPerc) max(stopValue, longStopPrice[1]) else 0 shortStopPrice := if useSL and sell_trend stopValue = high * (1 + StopTrailPerc) min(stopValue, shortStopPrice[1]) else 999999 ////////////////////////////////////////////////////////////////////////////////////////// //*** STOP LOSS HIT CONDITIONS ***// ////////////////////////////////////////////////////////////////////////////////////////// cond_long_stop_loss_hit = useSL and buy_trend and crossunder(low, longStopPrice[1]) and (SL_Trigger_Long_HIT or use_SL_Trigger == false) cond_short_stop_loss_hit = useSL and sell_trend and crossover(high, shortStopPrice[1]) and (SL_Trigger_Short_HIT or use_SL_Trigger == false) // Plot stop loss values for confirmation plot(series=useSL and buy_trend and low >= longStopPrice and (SL_Trigger_Long_HIT or use_SL_Trigger == false) ? longStopPrice : na, color=color.fuchsia, style=plot.style_cross, linewidth=2, title="Long Trail Stop") plot(series=useSL and sell_trend and high <= shortStopPrice and (SL_Trigger_Short_HIT or use_SL_Trigger == false) ? shortStopPrice : na, color=color.fuchsia, style=plot.style_cross, linewidth=2, title="Short Trail Stop") /////////////////////////////// //======[ Take Profit ]======// /////////////////////////////// // Use TP? useTP = input(true, "Use take profit") // TP trailing ProfitTrailPerc = input(1.0, "Trailing Profit (%)",minval=0,step=0.5,type=input.float) * 0.01 use_TP_Trigger = input(true, "Use Take Profit Trigger") // Will trigger the take profit trailing once reached takeProfitTrigger = input(3.0, "Take Profit Trigger (%)",minval=0,step=0.5,type=input.float) * 0.01 // ttp := ttp>tp ? tp : ttp takeprofitPriceTrigger = 0.0 takeprofitPriceTrigger := if (use_TP_Trigger) if (buy_trend) entry_price * (1 + takeProfitTrigger) else entry_price * (1 - takeProfitTrigger) else -1 //plot(entry_price, title='entry_price', transp=100) var TP_Trigger_Long_HIT = false TP_Trigger_Long_HIT := useTP and use_TP_Trigger and buy_trend and high >= takeprofitPriceTrigger ? true : TP_Trigger_Long_HIT[1] var TP_Trigger_Short_HIT = false TP_Trigger_Short_HIT := useTP and use_TP_Trigger and sell_trend and low <= takeprofitPriceTrigger ? true : TP_Trigger_Short_HIT[1] display_long_TP_trigger = useTP and buy_trend and TP_Trigger_Long_HIT == false and takeprofitPriceTrigger != -1 display_short_TP_trigger = useTP and sell_trend and TP_Trigger_Short_HIT == false and takeprofitPriceTrigger != -1 display_TP_trigger = display_long_TP_trigger or display_short_TP_trigger //🔷🔷🔷 // @hugo: Will display the TP trigger as long as not hit // once the TP trigger is hit, the TP trailing will activate plot(display_TP_trigger ? takeprofitPriceTrigger : na, title='takeprofitPriceTrigger', transp=0, color=color.orange, style=plot.style_cross, linewidth=3) longTrailTP= 0.0, shortTrailTP = 0.0 // Trailing Profit // Start trailing once trigger is reached longTrailTP := if useTP and buy_trend tpValue = high * (1 + ProfitTrailPerc) max(tpValue, longTrailTP[1]) else 0 shortTrailTP := if useTP and sell_trend tpValue = low * (1 - ProfitTrailPerc) min(tpValue, shortTrailTP[1]) else 999999 //plot(longTrailTP, title='debug longTrailTP', transp=100) //plot(shortTrailTP, title='debug shortTrailTP', transp=100) ////////////////////////////////////////////////////////////////////////////////////////// //*** TRAILING TAKE PROFIT HIT CONDITIONS TO BE USED IN ALERTS ***// ////////////////////////////////////////////////////////////////////////////////////////// //🔷🔷🔷 // @hugo: I use crossover/crossunder for the alerts to trigger the events only once cond_long_trail_tp_hit = useTP and buy_trend and crossover(high, longTrailTP[1]) and (TP_Trigger_Long_HIT or use_TP_Trigger == false) cond_short_trail_tp_hit = useTP and sell_trend and crossunder(low, shortTrailTP[1]) and (TP_Trigger_Short_HIT or use_TP_Trigger == false) // 🔷🔷🔷 // Plot take profits values for confirmation // Display the trailing TP until not hit plot(series= useTP and buy_trend and high <= longTrailTP and (TP_Trigger_Long_HIT or use_TP_Trigger == false) ? longTrailTP : na, color=color.aqua, style=plot.style_circles, linewidth=2, title="Long Trail TP") plot(series= useTP and sell_trend and low >= shortTrailTP and (TP_Trigger_Short_HIT or use_TP_Trigger == false) ? shortTrailTP : na, color=color.aqua, style=plot.style_circles, linewidth=2, title="Short Trail TP") close_long = cond_long_trail_tp_hit or cond_long_stop_loss_hit close_short = cond_short_trail_tp_hit or cond_short_stop_loss_hit strategy.entry("Long", 1, when=isLong) strategy.close("Long", when=close_long) strategy.entry("Short", 0, when=isShort) strategy.close("Short", when=close_short) if change_trend SL_Trigger_Long_HIT := false SL_Trigger_Short_HIT := false TP_Trigger_Long_HIT := false TP_Trigger_Short_HIT := false