Strategi perdagangan panjang dan pendek yang fleksibel berdasarkan saluran Keltner

ATR EMA SMA MA TR
Tanggal Pembuatan: 2025-02-10 15:07:12 Akhirnya memodifikasi: 2025-02-10 15:07:12
menyalin: 4 Jumlah klik: 448
1
fokus pada
1617
Pengikut

Strategi perdagangan panjang dan pendek yang fleksibel berdasarkan saluran Keltner

Ringkasan

Ini adalah strategi perdagangan fleksibel yang didasarkan pada Keltner Channel. Strategi ini mendukung perdagangan dua arah multi-saluran dengan pemantauan kenaikan dan penurunan harga yang menerobos saluran. Inti dari strategi ini adalah membangun saluran harga menggunakan moving average (MA) dan menyesuaikan lebar saluran secara dinamis dengan amplitudo aktual (ATR) untuk mempertahankan fleksibilitas strategi dalam berbagai kondisi pasar.

Prinsip Strategi

Strategi ini didasarkan pada prinsip-prinsip utama berikut:

  1. Tren pusat dari harga yang dihitung melalui EMA atau SMA, membentuk orbit tengah saluran
  2. Menggunakan ATR, TR atau Range untuk menghitung fluktuasi, membangun jalur naik dan turun
  3. Ketika harga menembus tren naik, sinyal multisignal dipicu, dan ketika harga menembus tren turun, sinyal gap dipicu
  4. Menggunakan Stop Loss Mandatory Single Entry and Exit Mechanism untuk meningkatkan keandalan eksekusi transaksi
  5. Mendukung pilihan modus perdagangan yang fleksibel: hanya melakukan over, hanya melakukan overhead, atau perdagangan dua arah

Keunggulan Strategis

  1. Adaptif - Mengatur lebar saluran secara dinamis melalui ATR, sehingga strategi dapat beradaptasi dengan lingkungan pasar yang berbeda
  2. Pengendalian risiko yang sempurna - Menggunakan Stop Loss Mandatory Single Mechanism untuk melakukan perdagangan, mengontrol risiko secara efektif
  3. Fleksibilitas Operasi - Mendukung berbagai modus perdagangan yang dapat disesuaikan dengan karakteristik pasar dan preferensi perdagangan
  4. Verifikasi Efektif - Berkinerja baik di pasar cryptocurrency dan saham, terutama di pasar dengan volatilitas tinggi
  5. Kejelasan visualisasi - memberikan sinyal perdagangan dan tampilan intuitif dari status posisi

Risiko Strategis

  1. Risiko pasar bergoyang - kemungkinan munculnya sinyal palsu yang sering terjadi di pasar bergoyang horizontal
  2. Risiko slippage - Stop loss warrant mungkin menghadapi slippage yang lebih besar di pasar yang kurang likuid
  3. Trend Reversal Risk - risiko kerugian yang lebih besar jika tren tiba-tiba berbalik
  4. Sensitivitas parameter - pilihan parameter saluran memiliki pengaruh penting terhadap kinerja strategi

Arah optimasi strategi

  1. Memperkenalkan filter tren - mengurangi sinyal bouncing palsu dengan menambahkan indikator penilaian tren
  2. Optimasi parameter dinamis - menyesuaikan parameter saluran secara dinamis sesuai dengan kondisi pasar yang berfluktuasi
  3. Perbaikan mekanisme Stop Loss - Tambahkan fitur Stop Loss Mobile untuk lebih melindungi keuntungan
  4. Peningkatan konfirmasi lalu lintas - menggabungkan indikator lalu lintas untuk meningkatkan keandalan sinyal
  5. Optimalkan manajemen posisi - memperkenalkan manajemen posisi dinamis untuk mengendalikan risiko dengan lebih baik

Meringkaskan

Strategi ini adalah sistem perdagangan yang dirancang dengan baik dan logis yang jelas, yang memungkinkan penangkapan peluang pasar yang efektif dengan menggunakan saluran Kettner dan berbagai indikator teknis secara fleksibel. Strategi ini sangat dapat disesuaikan untuk digunakan oleh pedagang dengan preferensi risiko yang berbeda. Dengan pengoptimalan dan perbaikan berkelanjutan, strategi ini diharapkan dapat mempertahankan kinerja yang stabil di berbagai lingkungan pasar.

Kode 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")