Strategi perdagangan panjang dan pendek yang fleksibel berdasarkan saluran Keltner

ATR EMA SMA MA TR
Tarikh penciptaan: 2025-02-10 15:07:12 Akhirnya diubah suai: 2025-02-10 15:07:12
Salin: 4 Bilangan klik: 448
1
fokus pada
1617
Pengikut

Strategi perdagangan panjang dan pendek yang fleksibel berdasarkan saluran Keltner

Gambaran keseluruhan

Ini adalah strategi perdagangan fleksibel berdasarkan Keltner Channel. Strategi ini menyokong perdagangan dua arah yang banyak, dengan pemantauan kenaikan dan penurunan harga yang menembusi saluran. Inti strategi ini adalah membina saluran harga menggunakan purata bergerak (MA) dan menyesuaikan lebar saluran secara dinamik dengan gelombang sebenar (ATR) untuk mengekalkan kesesuaian strategi dalam keadaan pasaran yang berbeza.

Prinsip Strategi

Strategi ini berdasarkan kepada beberapa prinsip utama:

  1. Trend pusat harga yang dikira melalui EMA atau SMA, membentuk corong tengah
  2. Menggunakan ATR, TR atau Range untuk mengira kadar turun naik, membina laluan naik dan turun
  3. Apabila harga menembusi tren naik, ia akan mencetuskan isyarat berganda, dan apabila ia menembusi tren turun ia akan mencetuskan isyarat kosong
  4. Menggunakan satu mekanisme penangguhan kerugian untuk masuk dan keluar untuk meningkatkan kebolehpercayaan pelaksanaan perdagangan
  5. Membantu pilihan mod dagangan yang fleksibel: hanya buat lebih, hanya buat lebih atau berdagang dua hala

Kelebihan Strategik

  1. Adaptif - menyesuaikan lebar saluran secara dinamik melalui ATR, membolehkan strategi menyesuaikan diri dengan keadaan pasaran yang berbeza
  2. Pengendalian risiko yang sempurna - Mengendalikan risiko dengan berkesan dengan menggunakan satu mekanisme penyerahan stop loss
  3. Fleksibiliti operasi - menyokong pelbagai mod perdagangan yang boleh disesuaikan dengan ciri-ciri pasaran dan keutamaan perdagangan
  4. Terbukti Berkesan - Berkesan baik di pasaran cryptocurrency dan saham, terutamanya di pasaran yang lebih bergolak
  5. Kejelasan visual - menyediakan isyarat perdagangan dan paparan intuitif status pegangan

Risiko Strategik

  1. Risiko pasaran goyah - kemungkinan munculnya isyarat pecah palsu yang kerap dalam pasaran goyah horizontal
  2. Risiko slippage - dalam pasaran yang kurang kecairan, CFD boleh menghadapi slippage yang lebih besar
  3. Risiko trend reversal - kemungkinan kerugian yang lebih besar jika trend berubah secara tiba-tiba
  4. Sensitiviti parameter - pilihan parameter saluran mempunyai kesan penting terhadap prestasi strategi

Arah pengoptimuman strategi

  1. Memperkenalkan penapis trend - mengurangkan isyarat pecah palsu dengan menambah indikator penghakiman trend
  2. Pengoptimuman parameter dinamik - menyesuaikan parameter saluran secara dinamik mengikut keadaan turun naik pasaran
  3. Peningkatan mekanisme henti rugi - penambahan fungsi henti rugi mudah alih untuk melindungi keuntungan dengan lebih baik
  4. Peningkatan pengesahan kuantiti transaksi - Gabungan penunjuk kuantiti transaksi untuk meningkatkan kebolehpercayaan isyarat
  5. Pengendalian kedudukan yang dioptimumkan - memperkenalkan pengurusan kedudukan yang dinamik untuk mengawal risiko dengan lebih baik

ringkaskan

Strategi ini adalah sistem perdagangan yang direka dengan baik dan logik yang jelas, yang menangkap peluang pasaran dengan berkesan dengan menggunakan saluran Kettner dan pelbagai petunjuk teknikal secara fleksibel. Strategi ini sangat disesuaikan untuk digunakan oleh peniaga dengan keutamaan risiko yang berbeza. Dengan pengoptimuman dan penambahbaikan yang berterusan, strategi ini dijangka dapat mengekalkan prestasi yang stabil dalam pelbagai keadaan pasaran.

Kod sumber strategi
/*backtest
start: 2022-02-11 00:00:00
end: 2025-02-08 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=6
strategy(title = "Jaakko's Keltner Strategy", overlay = true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100)

// ──────────────────────────────────────────────────────────────────────────────
// ─── USER INPUTS ─────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
length      = input.int(20,     minval=1,  title="Keltner MA Length")
mult        = input.float(2.0,             title="Multiplier")
src         = input(close,                 title="Keltner Source")
useEma      = input.bool(true,             title="Use Exponential MA")
BandsStyle  = input.string(title = "Bands Style", defval  = "Average True Range", options = ["Average True Range", "True Range", "Range"])
atrLength   = input.int(10,                title="ATR Length")

// Choose which side(s) to trade
tradeMode = input.string(title   = "Trade Mode", defval  = "Long Only", options = ["Long Only", "Short Only", "Both"])

// ──────────────────────────────────────────────────────────────────────────────
// ─── KELTNER MA & BANDS ───────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
f_ma(source, length, emaMode) =>
    maSma = ta.sma(source, length)
    maEma = ta.ema(source, length)
    emaMode ? maEma : maSma

ma    = f_ma(src, length, useEma)
rangeMa = BandsStyle == "True Range" ? ta.tr(true) : BandsStyle == "Average True Range" ? ta.atr(atrLength) : ta.rma(high - low, length)

upper = ma + rangeMa * mult
lower = ma - rangeMa * mult

// ──────────────────────────────────────────────────────────────────────────────
// ─── CROSS CONDITIONS ─────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
crossUpper = ta.crossover(src, upper) // potential long signal
crossLower = ta.crossunder(src, lower) // potential short signal

// ──────────────────────────────────────────────────────────────────────────────
// ─── PRICE LEVELS FOR STOP ENTRY (LONG) & STOP ENTRY (SHORT) ─────────────────
// ──────────────────────────────────────────────────────────────────────────────
bprice = 0.0
bprice := crossUpper ? high + syminfo.mintick : nz(bprice[1])

sprice = 0.0
sprice := crossLower ? low - syminfo.mintick : nz(sprice[1])

// ──────────────────────────────────────────────────────────────────────────────
// ─── BOOLEAN FLAGS FOR PENDING LONG/SHORT ─────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
crossBcond = false
crossBcond := crossUpper ? true : crossBcond[1]

crossScond = false
crossScond := crossLower ? true : crossScond[1]

// Cancel logic for unfilled orders (same as original)
cancelBcond = crossBcond and (src < ma or high >= bprice)
cancelScond = crossScond and (src > ma or low <= sprice)

// ──────────────────────────────────────────────────────────────────────────────
// ─── LONG SIDE ────────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
if (tradeMode == "Long Only" or tradeMode == "Both")  // Only run if mode is long or both
    // Cancel unfilled long if invalid
    if cancelBcond
        strategy.cancel("KltChLE")

    // Place long entry
    if crossUpper
        strategy.entry("KltChLE", strategy.long, stop=bprice, comment="Long Entry")

    // If we are also using “Both,” we rely on short side to flatten the long.
    // But if “Long Only,” we can exit on crossLower or do nothing.
    // Let’s do a "stop exit" if in "Long Only" (like the improved version).
    if tradeMode == "Long Only"
        // Cancel unfilled exit
        if cancelScond
            strategy.cancel("KltChLX")

        // Place exit if crossLower
        if crossLower
            strategy.exit("KltChLX", from_entry="KltChLE", stop=sprice, comment="Long Exit")

// ──────────────────────────────────────────────────────────────────────────────
// ─── SHORT SIDE ───────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
if (tradeMode == "Short Only" or tradeMode == "Both") // Only run if mode is short or both
    // Cancel unfilled short if invalid
    if cancelScond
        strategy.cancel("KltChSE")

    // Place short entry
    if crossLower
        strategy.entry("KltChSE", strategy.short, stop=sprice, comment="Short Entry")

    // If “Short Only,” we might do a symmetrical exit approach for crossUpper
    // Or if "Both," going long automatically flattens the short in a no-hedge account.
    // Let's replicate "stop exit" for short side if "Short Only" is chosen:
    if tradeMode == "Short Only"
        // Cancel unfilled exit
        if cancelBcond
            strategy.cancel("KltChSX")

        // Place exit if crossUpper
        if crossUpper
            strategy.exit("KltChSX", from_entry="KltChSE", stop=bprice, comment="Short Exit")

// ──────────────────────────────────────────────────────────────────────────────
// ─── OPTIONAL VISUALS ─────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
barcolor(strategy.position_size > 0 ? color.green : strategy.position_size < 0 ? color.red : na)

plotshape(    strategy.position_size > 0 and strategy.position_size[1] <= 0, title     = "BUY",  text      = '🚀',  style     = shape.labelup,    location  = location.belowbar,     color     = color.green,     textcolor = color.white,      size      = size.small)

plotshape(    strategy.position_size <= 0 and strategy.position_size[1] > 0,     title     = "SELL",     text      = '☄️',     style     = shape.labeldown,     location  = location.abovebar,     color     = color.red,       textcolor = color.white,     size      = size.small)

plotshape(crossLower, style=shape.triangledown, color=color.red, location=location.abovebar, title="CrossLower Trigger")