返回《給 CFD 交易者的 TradingView PineScript》
第四部分

建立一套完整的順勢系統

把每一堂課組起來:一個可以跑在任何 CFD 商品上的多週期、ATR 規模、警示接好的順勢系統。

進階閱讀時間約 15 分鐘初學 → 進階第 17 / 17 堂
在 TradingView 實際跑一次
完整的系統——每一堂課收在一支腳本裡

日線環境濾網 + 小時線進場 + ATR sizing + 括號出場 + JSON 警示。逐行走過:每一個區塊都是第一到第三部分涵蓋過的東西。

//@version=5
strategy("Trend-following system", overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.fixed,
     default_qty_value=1,
     commission_type=strategy.commission.cash_per_contract,
     commission_value=0,
     slippage=2)

// ── Inputs ──────────────────────────────────────────────────────────
fastLen   = input.int(20, "Fast EMA", minval=5)
slowLen   = input.int(50, "Slow EMA", minval=10)
atrLen    = input.int(14, "ATR length", minval=5)
atrMultSL = input.float(2.0, "ATR stop x", minval=0.5, step=0.1)
atrMultTP = input.float(4.0, "ATR target x", minval=0.5, step=0.1)
riskPct   = input.float(1.0, "Risk % per trade", minval=0.1, step=0.1)

// ── Higher-timeframe regime filter (Part 4) ─────────────────────────
dailyEMA = request.security(syminfo.tickerid, "D", ta.ema(close, 200),
     lookahead=barmerge.lookahead_off)
longBias = close > dailyEMA

// ── Entry signal ────────────────────────────────────────────────────
fastMA    = ta.ema(close, fastLen)
slowMA    = ta.ema(close, slowLen)
entryLong = ta.crossover(fastMA, slowMA) and longBias

// ── Risk-based sizing (Part 3) ──────────────────────────────────────
atrVal    = ta.atr(atrLen)
stopDist  = math.max(atrVal * atrMultSL, syminfo.mintick * 10)
riskMoney = strategy.equity * riskPct / 100
contracts = riskMoney / (stopDist * syminfo.pointvalue)

// ── Orders (Part 3) ─────────────────────────────────────────────────
if entryLong
    strategy.entry("Long", strategy.long, qty=contracts)
    strategy.exit("Long TP/SL", "Long",
         stop  = close - stopDist,
         limit = close + atrVal * atrMultTP)
strategy.close("Long", when=ta.crossunder(fastMA, slowMA))

// ── Visuals ─────────────────────────────────────────────────────────
plot(fastMA,   "Fast EMA",      color=color.blue,   linewidth=2)
plot(slowMA,   "Slow EMA",      color=color.orange, linewidth=2)
plot(dailyEMA, "Daily EMA 200", color=color.gray,   linewidth=3)
plotshape(entryLong, "Entry", shape.triangleup, location.belowbar,
          color=color.green, size=size.small)

// ── Webhook-ready alerts (Part 4) ───────────────────────────────────
if strategy.position_size > 0 and strategy.position_size[1] == 0
    alert('{"action":"buy","ticker":"' + syminfo.ticker +
          '","qty":"'   + str.tostring(contracts) +
          '","stop":"'  + str.tostring(close - stopDist) + '"}',
          alert.freq_once_per_bar_close)
if strategy.position_size == 0 and strategy.position_size[1] > 0
    alert('{"action":"close","ticker":"' + syminfo.ticker + '"}',
          alert.freq_once_per_bar_close)
如何執行
  1. 1. 在 TradingView 打開任一圖表,點選下方的 Pine Editor
  2. 2. 把編輯器裡的內容全選,用這段程式覆蓋過去,然後按 Save
  3. 3. 點選 Add to chart。如果是策略, 再打開 Strategy Tester 分頁。

這套系統

我們要做的是:CFD 商品上的純多單、日線趨勢濾網、小時線進場、ATR 停損、每筆風險決定規模、警示接好可做 webhook 自動化。每一個區塊都用到第一到第四部分涵蓋過的東西。

//@version=5
strategy("Trend-Following v1", overlay=true,
     default_qty_type=strategy.cash, default_qty_value=0,
     initial_capital=10000, commission_type=strategy.commission.cash_per_contract,
     commission_value=0, slippage=2)

// ── Inputs ────────────────────────────────────────────────────────────
fastLen   = input.int(20, "Fast EMA", minval=5)
slowLen   = input.int(50, "Slow EMA", minval=10)
atrLen    = input.int(14, "ATR Length", minval=5)
atrMultSL = input.float(2.0, "ATR Stop Mult", minval=0.5, step=0.1)
atrMultTP = input.float(4.0, "ATR Target Mult", minval=0.5, step=0.1)
riskPct   = input.float(1.0, "Risk % per Trade", minval=0.1)

// ── Higher-timeframe trend filter ─────────────────────────────────────
dailyEMA  = request.security(syminfo.tickerid, "D", ta.ema(close, 200),
     lookahead=barmerge.lookahead_off)
longBias  = close > dailyEMA

// ── Entry signal ──────────────────────────────────────────────────────
fastMA    = ta.ema(close, fastLen)
slowMA    = ta.ema(close, slowLen)
entryLong = ta.crossover(fastMA, slowMA) and longBias

// ── Sizing ────────────────────────────────────────────────────────────
atrVal      = ta.atr(atrLen)
stopDist    = atrVal * atrMultSL
riskMoney   = strategy.equity * riskPct / 100
contracts   = riskMoney / (stopDist * syminfo.pointvalue)
contracts  := math.max(contracts, 0)

// ── Entries and exits ─────────────────────────────────────────────────
if entryLong
    strategy.entry("Long", strategy.long, qty=contracts)
    strategy.exit("X", "Long", stop=close - stopDist, limit=close + stopDist * (atrMultTP / atrMultSL))

// ── Visualisation ─────────────────────────────────────────────────────
plot(fastMA, color=color.new(color.blue, 60))
plot(slowMA, color=color.new(color.orange, 60))
plot(dailyEMA, color=color.new(color.gray, 70), linewidth=2)
plotshape(entryLong, "Entry", shape.triangleup, location.belowbar, color.green, size=size.small)

// ── Webhook-ready alert payload ───────────────────────────────────────
if strategy.position_size > 0 and strategy.position_size[1] == 0
    alert('{"action":"buy","ticker":"' + syminfo.ticker + '","qty":"' + str.tostring(contracts) + '","sl":"' + str.tostring(close - stopDist) + '","tp":"' + str.tostring(close + stopDist * (atrMultTP / atrMultSL)) + '"}', alert.freq_once_per_bar_close)
if strategy.position_size == 0 and strategy.position_size[1] > 0
    alert('{"action":"close","ticker":"' + syminfo.ticker + '"}', alert.freq_once_per_bar_close)

它怎麼運作

純多單。日線 200-EMA 是環境濾網——日線下降趨勢裡不做多。進場在快 EMA 穿越慢 EMA 時觸發,但只在日線趨勢同意時。停損是進場價往下的 2 倍 ATR,目標是 4 倍 ATR。部位規模設定成「停損被打到正好虧損權益的 1%」。警示內容是 JSON,準備好可以導到 webhook。

上線之前你該改什麼

如果你的券商會重新報價,在策略宣告裡加滑價。如果你想在下一根 K 線的開盤而不是收盤執行,加 process_orders_on_close=false。在你敢把它放上實帳戶之前,把這個策略跑過你在資料裡能找到的每一種市場環境(2017 加密狂熱、2020 疫情崩盤、2022 利率衝擊)。

你現在知道什麼

你有完整的工具鏈了。打開 Pine 編輯器、把這段貼進去、逐行走過一遍。每一行都是第一到第四部分涵蓋過的東西。你接下來寫的策略,都會是這個模板的變體。

你剛完成了什麼

給 CFD 交易者的 TradingView PineScript》的第 17 / 17 堂課。跑完範例或讀完這段之後, 把它勾起來,然後進下一堂課。