L'idée principale de cette stratégie est de suivre dynamiquement les tendances du marché en achetant lorsque la tendance est à la hausse et en vendant lorsque la tendance est à la baisse.
Cette stratégie utilise divers indicateurs techniques pour déterminer la direction de la tendance. Premièrement, elle calcule un canal de prix, avec les limites supérieures et inférieures basées sur la moyenne mobile simple de clôture et un paramètre d'entrée. Ensuite, elle calcule la moyenne mobile Hull modifiée, qui est considérée comme meilleure pour décrire les tendances. En outre, l'indicateur de régression linéaire est également calculé. Elle génère des signaux d'achat lorsque la HMA modifiée traverse au-dessus de la ligne de régression linéaire, et des signaux de vente lorsqu'elle traverse en dessous. Cela permet de suivre dynamiquement les changements de tendance.
Pour réduire les faux signaux, la stratégie intègre également plusieurs filtres, tels que l'utilisation de l'EMA pour déterminer si elle est dans une tendance à la baisse, et un indicateur de fenêtre pour vérifier la divergence du RSI.
Pour les entrées et sorties, la stratégie enregistre le prix de la dernière position ouverte, et définit les pourcentages de profit et de stop-loss. Par exemple, si le dernier prix d'entrée long est de 100 $, il peut définir l'objectif de profit à 102 $ et le prix de stop-loss à 95 $. Cela permet de suivre dynamiquement les tendances.
Cette stratégie présente les avantages suivants:
Cette stratégie comporte également certains risques:
Pour contrôler les risques, on peut définir un stop loss, utiliser des trailing stops ou des options pour verrouiller les bénéfices.
Cette stratégie peut être améliorée dans les domaines suivants:
Lors de l'optimisation, le backtesting et le trading papier doivent être largement utilisés pour évaluer la qualité et la stabilité du signal.
Dans l'ensemble, il s'agit d'une stratégie de suivi de tendance décente. Il utilise plusieurs indicateurs pour évaluer les tendances, met en place des filtres pour réduire les faux signaux et peut ajuster automatiquement les arrêts et les cibles pour suivre les tendances. Avec un réglage approprié des paramètres, il peut facilement capturer les tendances à moyen et long terme. Les prochaines étapes consisteraient à trouver des paramètres optimaux et à continuer à valider et à améliorer la stratégie.
/*backtest start: 2023-12-03 00:00:00 end: 2023-12-06 00:00:00 period: 3m basePeriod: 1m 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/ // © RafaelZioni //@version=4 strategy(title = " BTC 15 min", overlay = true, pyramiding=1,initial_capital = 10000, default_qty_type= strategy.percent_of_equity, default_qty_value = 20, calc_on_order_fills=false, slippage=0,commission_type=strategy.commission.percent,commission_value=0.075) strat_dir_input = input(title="Strategy Direction", defval="all", options=["long", "short", "all"]) strat_dir_value = strat_dir_input == "long" ? strategy.direction.long : strat_dir_input == "short" ? strategy.direction.short : strategy.direction.all strategy.risk.allow_entry_in(strat_dir_value) price = close length8 = input(30,title = 'length of channel') upmult = input(title = 'upper percent',type=input.float, step=0.1, defval=5) lowmult = input(title = 'lower percent',type=input.float, step=0.1, defval=5) basis = sma(close, length8) vup = upmult * price / 100 vlow = lowmult * price / 100 upper = basis + vup lower = basis - vlow plot(basis, color=color.red) // fastLength = input(3, title="Fast filter length ", minval=1) slowLength = input(21,title="Slow filter length", minval=1) source=close v1=ema(source,fastLength) v2=ema(source,slowLength) // leng=1 p1=close[1] len55 = 10 //taken from https://www.tradingview.com/script/Ql1FjjfX-security-free-MTF-example-JD/ HTF = input("1D", type=input.resolution) ti = change( time(HTF) ) != 0 T_c = fixnan( ti ? close : na ) vrsi = rsi(cum(change(T_c) * volume), leng) pp=wma(vrsi,len55) d=(vrsi[1]-pp[1]) len100 = 10 x=ema(d,len100) // zx=x/-1 col=zx > 0? color.lime : color.orange // tf10 = input("1", title = "Timeframe", type = input.resolution, options = ["1", "5", "15", "30", "60","120", "240","360","720", "D", "W"]) length = input(50, title = "Period", type = input.integer) shift = input(1, title = "Shift", type = input.integer) hma(_src, _length)=> wma((2 * wma(_src, _length / 2)) - wma(_src, _length), round(sqrt(_length))) hma3(_src, _length)=> p = length/2 wma(wma(close,p/3)*3 - wma(close,p/2) - wma(close,p),p) b =security(syminfo.tickerid, tf10, hma3(close[1], length)[shift]) //plot(a,color=color.gray) //plot(b,color=color.yellow) close_price = close[0] len = input(25) linear_reg = linreg(close_price, len, 0) buy=crossover(linear_reg, b) sell=crossunder(linear_reg, b) or crossunder(close[1],upper) // src2=low src3=high Min =input(15) leni = timeframe.isintraday and timeframe.multiplier >= 1 ? Min / timeframe.multiplier * 7 : timeframe.isintraday and timeframe.multiplier < 60 ? 60 / timeframe.multiplier * 24 * 7 : 7 l1 = wma(src2,leni) h1 = wma(src3,leni) // m=(h1+l1)/2 // len5 = 100 src5=m // multi = 2 mean = ema(src5, len5) stddev = multi * stdev(src5, len5) b5 = mean + stddev s5 = mean - stddev var bool long = na var bool short = na long :=crossover(src5, s5) short := crossunder(src5, b5) var float last_open_long = na var float last_open_short = na last_open_long := long ? close : nz(last_open_long[1]) last_open_short := short ? close : nz(last_open_short[1]) entry_value =last_open_long entry_value1=last_open_short r=100 // highb = highest(entry_value1, r) lowb = lowest(entry_value, r) d5 = highb - lowb me = (highb + lowb) / 2 h4 = highb - d5 * 0.236 c3 = highb - d5 * 0.382 c4 = highb - d5 * 0.618 l4 = highb - d5 * 0.764 // col2 = close >= me ? color.lime : color.red p5 = plot(upper, color=col2) p2 = plot(lower, color=col2) fill(p5, p2,color=col2) // Conditions longCond = bool(na) shortCond = bool(na) longCond := crossover(zx,0) or buy shortCond := sell // Count your long short conditions for more control with Pyramiding sectionLongs = 0 sectionLongs := nz(sectionLongs[1]) sectionShorts = 0 sectionShorts := nz(sectionShorts[1]) if longCond sectionLongs := sectionLongs + 1 sectionShorts := 0 sectionShorts if shortCond sectionLongs := 0 sectionShorts := sectionShorts + 1 sectionShorts // Pyramiding pyrl = 1 // These check to see your signal and cross references it against the pyramiding settings above longCondition = longCond and sectionLongs <= pyrl shortCondition = shortCond and sectionShorts <= pyrl // Get the price of the last opened long or short last_open_longCondition = float(na) last_open_shortCondition = float(na) last_open_longCondition := longCondition ? open : nz(last_open_longCondition[1]) last_open_shortCondition := shortCondition ? open : nz(last_open_shortCondition[1]) // Check if your last postion was a long or a short last_longCondition = float(na) last_shortCondition = float(na) last_longCondition := longCondition ? time : nz(last_longCondition[1]) last_shortCondition := shortCondition ? time : nz(last_shortCondition[1]) in_longCondition = last_longCondition > last_shortCondition in_shortCondition = last_shortCondition > last_longCondition // Take profit isTPl = true //isTPs = input(false, "Take Profit Short") tp = input(2, "Exit Profit %", type=input.float) long_tp = isTPl and crossover(high, (1 + tp / 100) * last_open_longCondition) and longCondition == 0 and in_longCondition == 1 //short_tp = isTPs and crossunder(low, (1 - tp / 100) * last_open_shortCondition) and //shortCondition == 0 and in_shortCondition == 1 // Stop Loss isSLl = input(true,"buy Loss Long") //isSLs = input(false, "buy Loss Short") sl = 0.0 sl := input(5, " rebuy %", type=input.float) long_sl = isSLl and crossunder(low, (1 - sl / 100) * last_open_longCondition) and longCondition == 0 and in_longCondition == 1 //short_sl = isSLs and crossover(high, (1 + sl / 100) * last_open_shortCondition) and //shortCondition == 0 and in_shortCondition == 1 // // Conditions longCond5 = bool(na) shortCond5 = bool(na) longCond5 := longCondition shortCond5 := long_tp // sectionLongs5 = 0 sectionLongs5 := nz(sectionLongs5[1]) sectionShorts5 = 0 sectionShorts5 := nz(sectionShorts5[1]) if longCond5 sectionLongs5 := sectionLongs5 + 1 sectionShorts5 := 0 sectionShorts5 if shortCond5 sectionLongs5 := 0 sectionShorts5 := sectionShorts5 + 1 sectionShorts5 // pyr5 = 1 longCondition5 = longCond5 and sectionLongs5 <= pyr5 shortCondition5 = shortCond5 and sectionShorts5 <= pyr5 // Get the price of the last opened long or short last_open_longCondition5 = float(na) last_open_shortCondition5 = float(na) last_open_longCondition5 := longCondition5 ? open : nz(last_open_longCondition5[1]) last_open_shortCondition5 := shortCondition5 ? open : nz(last_open_shortCondition5[1]) last_longCondition5 = float(na) last_shortCondition5 = float(na) last_longCondition5 := longCondition5 ? time : nz(last_longCondition5[1]) last_shortCondition5 := shortCondition5 ? time : nz(last_shortCondition5[1]) in_longCondition5 = last_longCondition5 > last_shortCondition5 in_shortCondition5 = last_shortCondition5 > last_longCondition5 // filter=input(true) g(v, p) => round(v * (pow(10, p))) / pow(10, p) risk = input(100) leverage = input(1) c = g((strategy.equity * leverage / open) * (risk / 100), 4) // l =(v1 > v2 or filter == false ) and longCondition or long_sl // //l = longCondition or long_sl s=shortCondition5 if l strategy.entry("buy", strategy.long,c) if s strategy.entry("sell", strategy.short,c) per(pcnt) => strategy.position_size != 0 ? round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na) stoploss=input(title=" stop loss", defval=5, minval=0.01) los = per(stoploss) q1=input(title=" qty_percent1", defval=50, minval=1) q2=input(title=" qty_percent2", defval=50, minval=1) tp10=input(title=" Take profit1", defval=1, minval=0.01) tp20=input(title=" Take profit2", defval=2, minval=0.01) strategy.exit("x1", qty_percent = q1, profit = per(tp10), loss = los) strategy.exit("x2", qty_percent = q2, profit = per(tp20), loss = los)