Trend Angle Moving Average Crossover Strategi

Penulis:ChaoZhang, Tarikh: 2024-01-25 14:35:13
Tag:

img

Ringkasan

Strategi ini menentukan arah trend dengan mengira sudut kemiringan purata bergerak, digabungkan dengan penunjuk kadar perubahan harga untuk perdagangan panjang dan pendek.

Logika Strategi

Strategi ini terutamanya berdasarkan petunjuk berikut untuk penilaian:

  1. Sudut Kemiringan Purata Bergerak: Hitung sudut kemiringan Jurik Moving Average dan Exponential Moving Average untuk menentukan arah trend harga. Sudut yang lebih besar daripada 0 menunjukkan trend menaik, kurang daripada 0 bermaksud trend menurun.

  2. Kadar Perubahan Harga: Mengira kadar perubahan harga penutupan selama 12 bar terakhir untuk menapis isyarat mengikut turun naik.

Apabila kemiringan purata bergerak naik (lebih besar daripada 0) dan kadar perubahan harga memenuhi kriteria, pergi panjang. Apabila kemiringan turun (kurang daripada 0) dan kadar perubahan harga memenuhi kriteria, pergi pendek.

Secara khusus, strategi ini mula-mula mengira sudut cerun Jurik MA dan EMA. Kemudian penunjuk kadar perubahan harga dikira untuk menapis tempoh yang terikat julat. Apabila kedua-dua isyarat aliran penurunan purata bergerak dan kadar perubahan harga memenuhi kriteria, isyarat dagangan dihasilkan.

Analisis Kelebihan

Kelebihan strategi ini:

  1. Menggunakan cerun MA untuk menentukan trend adalah sangat boleh dipercayai dengan kadar kemenangan yang baik.

  2. Penunjuk kadar perubahan harga berkesan menapis turun naik untuk mengelakkan perdagangan yang tidak sah.

  3. Jurik MA memberikan tindak balas cepat kepada pecah sementara EMA menawarkan penilaian trend yang stabil, kedua-duanya saling melengkapi.

  4. Pergi panjang dan pendek dalam pasaran trend boleh menangkap keuntungan yang lebih besar.

Analisis Risiko

Beberapa risiko strategi ini:

  1. Dalam whipsaw harga yang melampau, MA mungkin menghasilkan isyarat yang salah. Ini boleh dikurangkan dengan pengoptimuman parameter.

  2. Isyarat boleh bertukar dengan kerap semasa julat yang menyebabkan perdagangan yang tidak perlu.

  3. Stop loss boleh dipecahkan dalam peristiwa jurang harga tiba-tiba. Stop loss yang lebih luas boleh digunakan.

Arahan pengoptimuman

Strategi ini boleh dioptimumkan dalam aspek berikut:

  1. Mengoptimumkan parameter MA untuk mencari kombinasi parameter terbaik meningkatkan kestabilan.

  2. Tambah volatiliti, penapis jumlah dan lain-lain untuk mengurangkan perdagangan yang tidak sah.

  3. Menggabungkan penunjuk lain untuk kedudukan stop loss yang lebih bijak.

  4. Membangunkan algoritma saiz kedudukan yang beradaptasi untuk keuntungan yang lebih stabil.

Kesimpulan

Secara keseluruhan, ini adalah strategi trend yang sangat praktikal. Ia dengan boleh dipercayai menentukan trend menggunakan sudut cerun MA, dan berkesan menapis isyarat bunyi menggunakan penunjuk kadar perubahan harga. Mengambil kedua-dua kedudukan panjang dan pendek boleh memperoleh keuntungan yang baik. Dengan pengoptimuman berterusan, strategi ini boleh menjadi strategi kuantitatif yang sangat stabil dan boleh dipercayai.


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


Lebih lanjut