Trend Mengikuti Strategi dengan Purata Bergerak dan SuperTrend

Penulis:ChaoZhang, Tarikh: 2023-10-20 16:50:01
Tag:

img

Ringkasan

Strategi ini menggabungkan penunjuk Moving Average dan penunjuk SuperTrend untuk melaksanakan strategi trend berikut dengan stop loss. Ia mengambil kesempatan penuh daripada keupayaan penilaian trend Moving Averages dan fungsi stop loss SuperTrend untuk mengesan trend dan mengawal risiko dengan berkesan.

Logika Strategi

Strategi ini menggunakan dua purata bergerak FRAMA untuk isyarat perdagangan dan penunjuk SuperTrend untuk penapisan.

Secara khusus, apabila garis pantas melintasi di atas garis perlahan, isyarat beli dihasilkan. Apabila garis pantas melintasi di bawah garis perlahan, isyarat jual dihasilkan. Untuk mengelakkan pecah palsu, strategi menambah penapis yang memerlukan penunjuk SuperTrend sejajar. Perdagangan hanya diambil apabila SuperTrend bersetuju dengan arah isyarat.

Untuk pengurusan kedudukan, strategi menggunakan perubahan arah SuperTrend sebagai isyarat stop loss.

Di samping itu, penangguhan stop loss boleh diaktifkan sebagai pilihan. Selepas sasaran keuntungan tertentu dicapai, penangguhan stop boleh digunakan untuk mengunci keuntungan.

Analisis Kelebihan

  • Menggunakan purata bergerak untuk menentukan arah trend, mampu menapis bunyi pasaran dan dengan tepat menilai trend
  • Menggabungkan dengan penapis SuperTrend mengelakkan perdagangan yang salah daripada pecah palsu
  • Perubahan arah SuperTrend bertindak sebagai titik stop loss, membolehkan stop loss yang cepat dan kawalan risiko yang berkesan
  • Pengecualian stop loss boleh memaksimumkan keuntungan

Analisis Risiko

  • Sebagai trend mengikuti strategi, ia mudah terdedah kepada whipsaws di pasaran yang berbeza.
  • Purata bergerak mempunyai kesan kelewatan, boleh menyebabkan kemasukan awal atau lewat
  • Parameter SuperTrend yang tidak betul boleh membawa kepada stop loss yang terlalu agresif atau terlalu konservatif
  • Apabila membolehkan hentian, lebar hentian perlu ditetapkan dengan betul untuk mengelakkan kehilangan hentian yang terlalu aktif

Risiko ini boleh dikurangkan dengan menyesuaikan parameter Purata Bergerak, mengoptimumkan tetapan SuperTrend, dan menggunakan stop loss yang sesuai.

Arahan pengoptimuman

Strategi ini boleh dioptimumkan dalam aspek berikut:

  1. Mengoptimumkan parameter purata bergerak untuk mencari kombinasi parameter terbaik

Gabungan tempoh yang berbeza boleh diuji untuk mencari keseimbangan kelancaran dan kepekaan yang optimum.

  1. Sesuaikan parameter SuperTrend

Tempoh dan pengganda ATR yang berbeza boleh diuji untuk mengoptimumkan kesan stop loss.

  1. Tambah penapis penunjuk lain

Penapis tambahan seperti Saluran Donchian, penunjuk turun naik boleh diuji.

  1. Mengoptimumkan parameter hentian

Lebar belakang yang berbeza boleh diuji untuk memaksimumkan keuntungan dan mengawal risiko.

  1. Gabungkan dengan strategi stop loss yang lain

Gabungan dengan hentian tetap, hentian turun naik, hentian penyesuaian boleh diuji.

Kesimpulan

Strategi ini mengintegrasikan analisis trend Moving Averages dan pengurusan berhenti SuperTrend ke dalam strategi trend berikut yang lengkap dengan penghentian kerugian. Penambahbaikan lanjut mengenai pengurusan risiko dan pengoptimuman parameter dapat meningkatkan kestabilan dan keuntungan. Ia sesuai untuk peniaga kuantitatif dengan beberapa pengalaman.


/*backtest
start: 2023-10-01 00:00:00
end: 2023-10-13 00:00:00
period: 30m
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/
// © 03.freeman

//@version=4
// strategy("FRAMA strategy", overlay=true,precision=6, initial_capital=1000,calc_on_every_tick=true, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=10000, currency=currency.EUR)
ma_src = input(title="MA FRAMA Source", type=input.source, defval=close)
ma_frama_len = input(title="MA FRAMA Length", type=input.integer, defval=12)
res = input(title="Resolution", type=input.resolution, defval="1W")
frama_FC = input(defval=1,minval=1, title="* Fractal Adjusted (FRAMA) Only - FC")
frama_SC = input(defval=200,minval=1, title="* Fractal Adjusted (FRAMA) Only - SC")
High = security(syminfo.tickerid, res, high)
Low = security(syminfo.tickerid, res, low)
source = security(syminfo.tickerid, res, ma_src)
enterRule = input(false,title = "Use supertrend for enter")
exitRule = input(false,title = "Use supertrend for exit")

ma(src, len) =>
    float result = 0
    int len1 = len/2
    e = 2.7182818284590452353602874713527
    w = log(2/(frama_SC+1)) / log(e) // Natural logarithm (ln(2/(SC+1))) workaround
    H1 = highest(High,len1)
    L1 = lowest(Low,len1)
    N1 = (H1-L1)/len1
    H2_ = highest(High,len1)
    H2 = H2_[len1]
    L2_ = lowest(Low,len1)
    L2 = L2_[len1]
    N2 = (H2-L2)/len1
    H3 = highest(High,len)
    L3 = lowest(Low,len)
    N3 = (H3-L3)/len
    dimen1 = (log(N1+N2)-log(N3))/log(2)
    dimen = iff(N1>0 and N2>0 and N3>0,dimen1,nz(dimen1[1]))
    alpha1 = exp(w*(dimen-1))
    oldalpha = alpha1>1?1:(alpha1<0.01?0.01:alpha1)
    oldN = (2-oldalpha)/oldalpha
    N = (((frama_SC-frama_FC)*(oldN-1))/(frama_SC-1))+frama_FC
    alpha_ = 2/(N+1)
    alpha = alpha_<2/(frama_SC+1)?2/(frama_SC+1):(alpha_>1?1:alpha_)
    frama = 0.0
    frama :=(1-alpha)*nz(frama[1]) + alpha*src
    result := frama
    result

frama = ma(sma(source,1),ma_frama_len)
signal = ma(frama,ma_frama_len)
plot(frama, color=color.red)
plot(signal, color=color.green)


longCondition = crossover(frama,signal)
shortCondition = crossunder(frama,signal)

Factor=input(3, minval=1,maxval = 100)
Pd=input(7, minval=1,maxval = 100)


Up=hl2-(Factor*atr(Pd))
Dn=hl2+(Factor*atr(Pd))

TrendUp = 0.0
TrendDown = 0.0
Trend = 0.0
Tsl = 0.0
TrendUp :=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown :=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn

Trend := close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl := Trend==1? TrendUp: TrendDown

linecolor = Trend == 1 ? color.green : color.red

//plot(Tsl, color = linecolor , style =  plot.style_line , linewidth = 2,title = "SuperTrend")

plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,color.green,0,0)
plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, color.red,0,0)

plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0)


//  Strategy: (Thanks to JayRogers)
// === STRATEGY RELATED INPUTS ===
//tradeInvert     = input(defval = false, title = "Invert Trade Direction?")
// the risk management inputs
inpTakeProfit   = input(defval = 0, title = "Take Profit Points", minval = 0)
inpStopLoss     = input(defval = 0, title = "Stop Loss Points", minval = 0)
inpTrailStop    = input(defval = 0, title = "Trailing Stop Loss Points", minval = 0)
inpTrailOffset  = input(defval = 0, title = "Trailing Stop Loss Offset Points", minval = 0)

// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit   = inpTakeProfit  >= 1 ? inpTakeProfit  : na
useStopLoss     = inpStopLoss    >= 1 ? inpStopLoss    : na
useTrailStop    = inpTrailStop   >= 1 ? inpTrailStop   : na
useTrailOffset  = inpTrailOffset >= 1 ? inpTrailOffset : na

// === STRATEGY - LONG POSITION EXECUTION ===
enterLong() => enterRule? (longCondition and Trend ==1):longCondition                                             // functions can be used to wrap up and work out complex conditions
exitLong() => exitRule and Trend == -1

strategy.entry(id = "Buy", long = true, when = enterLong() )             // use function or simple condition to decide when to get in
strategy.close(id = "Buy", when = exitLong() )                         // ...and when to get out

// === STRATEGY - SHORT POSITION EXECUTION ===
enterShort() => enterRule? (shortCondition and Trend ==-1):shortCondition
exitShort() => exitRule and Trend == 1

strategy.entry(id = "Sell", long = false, when = enterShort())
strategy.close(id = "Sell", when = exitShort() )

// === STRATEGY RISK MANAGEMENT EXECUTION ===
// finally, make use of all the earlier values we got prepped
strategy.exit("Exit Buy", from_entry = "Buy", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
strategy.exit("Exit Sell", from_entry = "Sell", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)

// === Backtesting Dates === thanks to Trost

testPeriodSwitch = input(false, "Custom Backtesting Dates")
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0)
testStopYear = input(2020, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testStopHour = input(23, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0)
testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
isPeriod = true
// === /END

if not isPeriod
    strategy.cancel_all()
    strategy.close_all()

Lebih lanjut