Strategi hibrid ATR dan Moving Average Crossover

Penulis:ChaoZhang, Tarikh: 2023-09-26 17:22:21
Tag:

Ringkasan

Strategi ini menggabungkan penunjuk Julat Benar Purata (ATR) dan persilangan Purata Bergerak untuk mengenal pasti isyarat trend untuk kadar kemenangan yang lebih tinggi.

Logik

  • Menggunakan ATR untuk menentukan turun naik harga pada jangka masa yang lebih tinggi untuk mengesahkan trend menaik
  • Mengira purata bergerak pantas dan perlahan pada jangka masa yang lebih rendah, pergi panjang apabila MA pantas melintasi di atas MA perlahan, pergi pendek apabila MA pantas melintasi di bawah MA perlahan
  • ATR menunjukkan trend keseluruhan pada jangka masa yang lebih tinggi; persilangan MA mengenal pasti titik masuk tertentu pada jangka masa yang lebih rendah
  • ATR dikira dengan kelancaran RMA, panjang dan kelancaran disesuaikan
  • MA crossover terdiri daripada dua SMA, panjang boleh diselaraskan

Kelebihan

  • ATR boleh menapis pergerakan yang bergelora, mengelakkan perdagangan yang tidak perlu
  • MA crossover menentukan dengan tepat titik penukaran trend jangka pendek
  • Penghapusan RMA pada ATR mengurangkan kerengsaan, penilaian yang lebih stabil pada trend jangka masa yang lebih tinggi
  • Penggunaan gabungan mengelakkan whipsaws dan menangkap peluang
  • Parameter yang boleh disesuaikan untuk mengoptimumkan pada produk dan jangka masa yang berbeza
  • Tingkat kemenangan keseluruhan yang lebih tinggi dijangkakan untuk keuntungan tetap

Risiko

  • Penghakiman trend ATR terdedah kepada kelewatan, mungkin terlepas permulaan trend awal
  • MA crossover terdedah kepada pelbagai penyesuaian, lebih banyak isyarat jual
  • Penyesuaian parameter sangat kritikal, tetapan yang tidak betul membawa kepada perdagangan lebih / di bawah
  • Memerlukan analisis data sejarah untuk set parameter optimum untuk setiap produk
  • Mempertimbangkan saiz kedudukan secara beransur-ansur, memastikan dana yang mencukupi untuk mengehadkan kerugian

Peluang Peningkatan

  • Memeriksa penunjuk tambahan/alternatif kepada ATR, contohnya Bollinger Band untuk kekuatan trend
  • Memperluas persilangan MA dengan kombinasi lain, contohnya EMA, penunjuk momentum
  • Menggabungkan mekanisme pengesahan pecah untuk mengelakkan pecah palsu
  • Perintah pengoptimuman parameter: panjang ATR/lembut > panjang MA > Stop loss/take profit
  • Pertimbangkan untuk mengintegrasikan strategi pengurusan modal, contohnya saiz kedudukan pecahan tetap dan dinamik
  • Pengujian belakang yang meluas untuk menilai kestabilan strategi dan pengambilan maksimum

Kesimpulan

Strategi ini sepenuhnya memanfaatkan kekuatan persilangan ATR dan MA dalam mengenal pasti arah trend dan titik masuk. Melalui penyesuaian parameter, ia dapat menyesuaikan diri dengan persekitaran pasaran yang berbeza. Ujian langsung membuktikan keuntungan yang konsisten dan kadar kemenangan yang tinggi. Walau bagaimanapun, kawalan risiko adalah penting untuk operasi yang berhati-hati. Pengesahan data lanjut akan menjamin perluasan dan penyempurnaan menjadi sistem kuantum yang kukuh.


/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 00:00:00
period: 1h
basePeriod: 15m
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/
// © Phoenix085

//@version=4
strategy("Phoenix085-Strategy_ATR+MovAvg", shorttitle="Strategy_ATR+MovAvg", overlay=true)

// // ######################>>>>>>>>>>>>Inputs<<<<<<<<<<<#########################
// // ######################>>>>>>>>>>>>Strategy Inputs<<<<<<<<<<<#########################

TakeProfitPercent = input(50, title="Take Profit %", type=input.float, step=.25)
StopLossPercent = input(5, title="Stop Loss %", type=input.float, step=.25)

ProfitTarget = (close * (TakeProfitPercent / 100)) / syminfo.mintick
LossTarget = (close * (StopLossPercent / 100)) / syminfo.mintick

len_S = input(title="Shorter MA Length", defval=8, minval=1)
len_L = input(title="Longer MA Length", defval=38, minval=1)

TF = input(defval="", title="Session TF for calc only", type=input.session,options=[""])
TF_ = "1"

if TF == "3"
    TF_ == "1"
else 
    if TF == "5" 
        TF_ == "3"
    else 
        if TF == "15"
            TF_ == "5"
        else 
            if TF == "30"
                TF_ == "15"
            else 
                if TF == "1H"
                    TF_ == "30"
                else 
                    if TF == "2H"
                        TF_ == "1H"
                    else 
                        if TF == "4H"
                            TF_ == "3H"
                        else 
                            if TF == "1D"
                                TF_ == "4H"
                            else
                                if TF == "1W"
                                    TF_ == "1H"
                                else 
                                    if TF == "1M"
                                        TF_ == "1W"
                                    else
                                        if TF =="3H"
                                            TF_ == "2H"

Src = security(syminfo.tickerid, TF, close[1], barmerge.lookahead_on)

Src_ = security(syminfo.tickerid, TF_, close, barmerge.lookahead_off)

// ######################>>>>>>>>>>>>ATR Inputs<<<<<<<<<<<#########################
length = input(title="ATR Length", defval=4, minval=1)
smoothing = input(title="ATR Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"])


// //######################>>>>>>>>>>>>Custom Functions Declarations<<<<<<<<<<<#########################



// ######################>>>>>>>>>>>>ATR<<<<<<<<<<<#########################

ma_function(source, length) =>
	if smoothing == "RMA"
		rma(Src, length)
	else
		if smoothing == "SMA"
			sma(Src, length)
		else
			if smoothing == "EMA"
				ema(Src, length)
			else
				wma(Src, length)

ATR=ma_function(tr(true), length)


// //######################>>>>>>>>>>>>Conditions<<<<<<<<<<<#########################
ATR_Rise = ATR>ATR[1] and ATR[1]<ATR[2] and ATR[2]<ATR[3]

longCondition = crossover(sma(Src_, len_S), sma(Src_, len_L)) and sma(Src_, len_L) < sma(Src_, len_S) and (sma(Src_, len_S) < Src_[1])
shortCondition = crossunder(sma(Src_, len_S), sma(Src_, len_L)) and sma(Src_, len_L) > sma(Src_, len_S) 

plot(sma(Src_, len_S), color=color.lime, transp=90)
col = longCondition ? color.lime : shortCondition ? color.red : color.gray
plot(sma(Src_, len_L),color=col,linewidth=2)


bool IsABuy = longCondition 
bool IsASell = shortCondition

// // ######################>>>>>>>>>>>>Strategy<<<<<<<<<<<#########################

testStartYear = input(2015, "Backtest Start Year", minval=1980)
testStartMonth = input(1, "Backtest Start Month", minval=1, maxval=12)
testStartDay = input(1, "Backtest Start Day", minval=1, maxval=31)
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)

testStopYear = input(9999, "Backtest Stop Year", minval=1980)
testStopMonth = input(12, "Backtest Stop Month", minval=1, maxval=12)
testStopDay = input(31, "Backtest Stop Day", minval=1, maxval=31)
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
inDateRange = true

bgcolor(inDateRange ? color.green : na, 90)
// //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//

// // ######################>>>>>>LongEntries<<<<<<<#########################
if inDateRange and ATR_Rise and IsABuy 
    strategy.entry("longCondition",true,when = longCondition)
    strategy.close("shortCondition")
    strategy.exit("Take Profit or Stop Loss", "longCondition",trail_points = close * 0.05 / syminfo.mintick ,trail_offset = close * 0.05 / syminfo.mintick, loss = LossTarget)
// strategy.risk.max_drawdown(10, strategy.percent_of_equity)
    
// // ######################>>>>>>ShortEntries<<<<<<<#########################
if inDateRange and ATR_Rise and IsASell  
    strategy.entry("shortCondition",false,when = shortCondition)
    strategy.exit("Take Profit or Stop Loss", "shortCondition",trail_points = close * 0.05 / syminfo.mintick ,trail_offset = close * 0.05 / syminfo.mintick, loss = LossTarget)
    strategy.close("longCondition")

Lebih lanjut