函式#

當一段邏輯需要在腳本中重複使用時,可以將它封裝成 函式。函式讓程式碼更簡潔、易讀,也更容易維護。

定義函式#

Pine Script 函式的定義語法:

functionName(param1, param2) =>
    // 函式本體(縮排)
    returnValue

最後一行的值會自動成為回傳值(不需要 return 關鍵字)。

簡單範例:計算兩個值的平均:

//@version=6
indicator("函式示範")

// 定義函式
average(a, b) =>
    (a + b) / 2

// 呼叫函式
midPrice = average(high, low)
plot(midPrice, "中間價", color=color.orange)

參數預設值#

函式參數可以設定預設值,呼叫時可省略該參數:

//@version=6
indicator("參數預設值")

// length 預設為 14
myRSI(src, length = 14) =>
    ta.rsi(src, length)

// 使用預設 length=14
plot(myRSI(close))

// 指定 length=7
plot(myRSI(close, 7), color=color.orange)

多行函式#

函式本體可以包含多行程式碼,使用縮排分隔:

//@version=6
indicator("多行函式", overlay=true)

// 判斷 K 棒類型並回傳顏色
barTypeColor() =>
    bodySize = math.abs(close - open)
    rangeSize = high - low
    ratio = rangeSize > 0 ? bodySize / rangeSize : 0

    if ratio > 0.7
        color.new(close > open ? color.green : color.red, 0)  // 實體大:強勢K棒
    else if ratio > 0.3
        color.new(color.gray, 50)  // 中等實體
    else
        color.new(color.gray, 80)  // 上下影線長:不確定K棒

barcolor(barTypeColor())

回傳多個值#

函式可以用 tuple(元組)的形式同時回傳多個值,接收時使用 [a, b] 解構:

//@version=6
indicator("回傳多值", overlay=true)

// 同時回傳最高收盤和最低收盤
highLowClose(length) =>
    h = ta.highest(close, length)
    l = ta.lowest(close, length)
    [h, l]

// 解構接收
[channelHigh, channelLow] = highLowClose(20)

plot(channelHigh, "通道上軌", color=color.green)
plot(channelLow,  "通道下軌", color=color.red)
fill(plot(channelHigh, display=display.none),
     plot(channelLow,  display=display.none),
     color=color.new(color.blue, 90))

函式的限制#

Pine Script 自訂函式有幾個重要限制:

  • 不支援遞迴:函式不能直接或間接呼叫自身
  • 不能修改全域變數:函式內部只能讀取全域變數,無法對其賦值(:=
  • 不能呼叫特定內建函式indicator()strategy()barcolor()bgcolor()alertcondition() 等只能在全域範圍呼叫,不能放在自訂函式內

method — 型別方法#

Pine Script 支援 method,可以用 . 語法呼叫自訂函式,讓程式碼更像物件導向風格:

//@version=6
indicator("method 示範")

// 為 array<float> 型別定義一個 method
method normalize(array<float> arr) =>
    minVal = array.min(arr)
    maxVal = array.max(arr)
    result = array.new<float>()
    for val in arr
        normalized = maxVal != minVal ? (val - minVal) / (maxVal - minVal) : 0.0
        array.push(result, normalized)
    result

// 用 . 語法呼叫
prices = array.from(close, close[1], close[2], close[3], close[4])
normalizedPrices = prices.normalize()

plot(array.get(normalizedPrices, 0), "標準化收盤價")

實用範例:封裝 MACD 訊號#

//@version=6
indicator("封裝 MACD 訊號", overlay=false)

// 封裝 MACD 計算並回傳三個值
calcMACD(src, fastLen, slowLen, signalLen) =>
    fastMA   = ta.ema(src, fastLen)
    slowMA   = ta.ema(src, slowLen)
    macdLine = fastMA - slowMA
    sigLine  = ta.ema(macdLine, signalLen)
    hist     = macdLine - sigLine
    [macdLine, sigLine, hist]

// 呼叫函式
[macd, signal, histogram] = calcMACD(close, 12, 26, 9)

plot(macd,      "MACD",   color=color.blue)
plot(signal,    "Signal", color=color.orange)
plot(histogram, "Hist",   style=plot.style_histogram,
     color=histogram >= 0 ? color.green : color.red)

Reference#