Cette stratégie détermine la direction de la tendance en calculant l'angle de pente des moyennes mobiles, combiné à l'indicateur du taux de variation des prix pour les transactions longues et courtes.
La stratégie repose principalement sur les indicateurs suivants:
Angle de pente de la moyenne mobile: Calculer les angles de pente de la moyenne mobile de Jurik et de la moyenne mobile exponentielle pour déterminer la direction de la tendance des prix.
Taux de variation des prix: Calcule le taux de variation du prix de clôture sur les 12 dernières barres pour filtrer les signaux par volatilité.
Lorsque la pente de la moyenne mobile monte (plus grande que 0) et que le taux de variation des prix répond aux critères, passez à la vente. Lorsque la pente descend (moins de 0) et que le taux de variation des prix répond aux critères, passez à la vente.
Les avantages de cette stratégie:
Utiliser la pente MA pour déterminer la tendance est très fiable avec un bon taux de gain.
L'indicateur du taux de variation des prix filtre efficacement les fluctuations de la fourchette afin d'éviter les transactions invalides.
Jurik MA offre une réponse rapide à l'évolution de la tendance tandis que l'EMA offre un jugement stable de la tendance, les deux étant complémentaires.
Aller à la fois long et court sur le marché tendance pourrait capturer un plus grand profit.
Quelques risques de cette stratégie:
Dans les cas extrêmes, MA peut générer des signaux erronés. Cela peut être réduit par l'optimisation des paramètres.
Les signaux peuvent changer fréquemment pendant la gamme, ce qui entraîne des transactions inutiles.
Un stop loss plus large peut être utilisé.
La stratégie peut être optimisée dans les aspects suivants:
Optimiser les paramètres MA pour trouver la meilleure combinaison de paramètres améliorant la stabilité.
Ajouter la volatilité, les filtres de volume, etc. pour réduire davantage les transactions invalides.
Incorporer d'autres indicateurs pour un positionnement stop loss plus intelligent.
Développer des algorithmes adaptatifs de dimensionnement des positions pour une rentabilité plus stable.
Dans l'ensemble, il s'agit d'une stratégie de suivi de tendance très pratique. Elle détermine de manière fiable la tendance en utilisant l'angle de pente MA et filtre efficacement les signaux de bruit en utilisant l'indicateur de taux de variation de prix. Prendre des positions longues et courtes pourrait générer de bons profits. Avec des optimisations continues, cette stratégie peut devenir une stratégie quantitative très stable et fiable.
/*backtest start: 2023-12-01 00:00:00 end: 2023-12-31 23:59:59 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // Based on ma angles code by Duyck which also uses Everget Jurik MA calulation and angle calculation by KyJ strategy("Trend Angle BF", overlay=false) /////////////// Time Frame /////////////// testStartYear = input(2017, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0) testStopYear = input(2019, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0) testPeriod() => true src=input(ohlc4,title="source") // definition of "Jurik Moving Average", by Everget jma(_src,_length,_phase,_power) => phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5 beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2) alpha = pow(beta, _power) jma = 0.0 e0 = 0.0 e0 := (1 - alpha) * _src + alpha * nz(e0[1]) e1 = 0.0 e1 := (_src - e0) * (1 - beta) + beta * nz(e1[1]) e2 = 0.0 e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1]) jma := e2 + nz(jma[1]) //// //// Determine Angle by KyJ //// //// angle(_src) => rad2degree=180/3.14159265359 //pi ang=rad2degree*atan((_src[0] - _src[1])/atr(14)) jma_line=jma(src,10,50,1) ma=ema(src,input(56)) jma_slope=angle(jma_line) ma_slope=angle(ma) ///////////// Rate Of Change ///////////// source = close roclength = input(12, minval=1) pcntChange = input(2, minval=1) roc = 100 * (source - source[roclength]) / source[roclength] emaroc = ema(roc, roclength / 2) isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2)) /////////////// Strategy /////////////// long = ma_slope>=0 and isMoving() short = ma_slope<=0 and isMoving() last_long = 0.0 last_short = 0.0 last_long := long ? time : nz(last_long[1]) last_short := short ? time : nz(last_short[1]) long_signal = crossover(last_long, last_short) short_signal = crossover(last_short, last_long) last_open_long_signal = 0.0 last_open_short_signal = 0.0 last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1]) last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1]) last_long_signal = 0.0 last_short_signal = 0.0 last_long_signal := long_signal ? time : nz(last_long_signal[1]) last_short_signal := short_signal ? time : nz(last_short_signal[1]) in_long_signal = last_long_signal > last_short_signal in_short_signal = last_short_signal > last_long_signal last_high = 0.0 last_low = 0.0 last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1]) last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1]) sl_inp = input(2.0, title='Stop Loss %') / 100 tp_inp = input(900.0, title='Take Profit %') / 100 take_level_l = strategy.position_avg_price * (1 + tp_inp) take_level_s = strategy.position_avg_price * (1 - tp_inp) since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na slShort = strategy.position_avg_price * (1 + sl_inp) long_sl = in_long_signal ? slLong : na short_sl = in_short_signal ? slShort : na /////////////// Execution /////////////// if testPeriod() strategy.entry("Long", strategy.long, when=long) strategy.entry("Short", strategy.short, when=short) strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0) strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0) ///////////// Plotting ///////////// hline(0, title='Zero line', color=color.purple, linewidth=1) plot(ma_slope,title="ma slope", linewidth=2,color=ma_slope>=0?color.lime:color.red) bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80) bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)