Trendwinkel bewegliche Durchschnitts-Kreuzung

Schriftsteller:ChaoZhang, Datum: 2024-01-25 14:35:13
Tags:

img

Übersicht

Diese Strategie bestimmt die Trendrichtung, indem sie den Neigungswinkel der gleitenden Durchschnitte berechnet, kombiniert mit einem Preisänderungsratenindikator für den Long- und Short-Handel.

Strategie Logik

Die Strategie stützt sich hauptsächlich auf folgende Indikatoren:

  1. Gleitender Durchschnittsneigung Winkel: Berechnen Sie die Neigung Winkel des Jurik gleitenden Durchschnitts und exponentiellen gleitenden Durchschnitts, um die Kurstrendrichtung zu bestimmen.

  2. Preisänderungsrate: Berechnet die Veränderungsrate des Schlusskurses über die letzten 12 Baren, um Signale nach Volatilität zu filtern.

Wenn die gleitende Durchschnittsneigung steigt (größer als 0) und die Preisänderungsrate die Kriterien erfüllt, geht man lang.

Die Strategie berechnet zunächst die Neigungswinkel von Jurik MA und EMA. Anschließend wird der Preisänderungsratenindikator für die Filterung der Bereichsgebundenen Periode berechnet.

Analyse der Vorteile

Die Vorteile dieser Strategie:

  1. Die Verwendung der MA-Spannung zur Bestimmung des Trends ist sehr zuverlässig mit einer guten Gewinnrate.

  2. Der Preisänderungsindikator filtert schwankende Kursschwankungen effektiv, um ungültige Geschäfte zu vermeiden.

  3. Jurik MA reagiert schnell auf Ausbrüche, während die EMA eine stabile Trendbeurteilung anbietet, die sich ergänzt.

  4. Wenn man auf dem Trendmarkt sowohl kurz als auch lang geht, könnte man einen größeren Gewinn erzielen.

Risikoanalyse

Einige Risiken dieser Strategie:

  1. Bei extremen Preisschlägen kann MA falsche Signale erzeugen. Dies kann durch Parameteroptimierung reduziert werden.

  2. Es kann vorkommen, dass sich die Signale während des Abstands häufig wechseln, was zu unnötigen Trades führt.

  3. Bei plötzlichen Preisunterschieden kann ein Stop Loss gebrochen werden.

Optimierungsrichtlinien

Die Strategie kann in folgenden Aspekten optimiert werden:

  1. Optimieren der MA-Parameter, um die beste Parameterkombination zu finden, die die Stabilität verbessert.

  2. Es gibt auch andere Methoden, wie z. B. die Berechnung der Wertminderung.

  3. Einbeziehung anderer Indikatoren für eine intelligentere Stop-Loss-Positionierung.

  4. Entwicklung von algorithmen für die anpassungsfähige Positionsgröße für eine stabilere Rentabilität.

Schlussfolgerung

Insgesamt ist dies eine sehr praktische Trendfolgestrategie. Sie bestimmt den Trend zuverlässig unter Verwendung des MA-Neigungswinkels und filtert mit Hilfe eines Kursänderungsindikators effektiv Rauschsignale. Die Einnahme von Long- und Short-Positionen könnte einen schönen Gewinn erzielen. Mit kontinuierlichen Optimierungen kann diese Strategie zu einer sehr stabilen und zuverlässigen quantitativen Strategie werden.


/*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) 


Mehr