TradingView回測教學-Pine Script 怎麼寫?重要語法介紹整理

上一篇文章介紹了如何在TradingView利用內建策略用Pine編輯器修改預設策略進行回測,這一篇文章會教你Pine編輯器中的Pine Script要怎麼寫、介紹Pine Script重要語法有哪些,以及交易策略腳本的程式架構介紹,

看完這篇Pine Script教學,能快速了解如何用TradingView Pine編輯器撰寫屬於自己的交易策略。

提醒一下,文章內容會有很多操作步驟,在編寫程式時,使用電腦版會比較順暢。

還沒用過TradingView的可先閱讀:最完整的TradingView新手使用教學

Pine編輯器 是什麼

Pine編輯器是在TradingView上用來編寫Pine Script程式的工具,Pine Script是TradingView開發的程式語言(programming language),

想在TradingView上編寫自訂的技術指標或交易策略,就必須學會Pine Script,才能跟TradingView溝通、下達指令,而Pine編輯器就是TradingView上編輯這些程式語言和指令的介面。

簡單介紹,TradingView的Pine編輯器可以撰寫交易策略腳本,並透過「策略測試器」套用腳本,就能跑回測評估交易策略的績效。

Pine編輯器和TradingView一樣是在網頁上就可以直接運作的,不需要額外安裝應用程式,只要在TradingView界面中點擊下方的「Pine編輯器」,就可以開啟。

接下來會詳細介紹 Pine Script 重要語法有哪些。

Pine Script 語法介紹

Pine Script是TradingView上撰寫技術指標和交易策略的程式語言,

先認識Pine Script的基礎語法,了解大概架構,比較能順利寫出自己設計的交易策略腳本。

版本 Version

在開始撰寫腳本時,要先有一行程式碼,告訴編輯器自己使用的是第幾版的Pine Script。

Pine Script目前最新的版本是第6版(version 6),每一次更新版本都會做一些變更和改善,和前一個版本會有些許不同,有些語法可以和上一版相容,另一些不行的則要改寫。

Pine Script 宣告版本範例

//@version=6

這是在告訴Pine編輯器接下來腳本使用的是第6版的Pine Script。
(目前TradingView內建的指標和策略多數也都是用第6版編輯的)

如果沒告訴TradingView要用哪一個版本的Pine Script(程式碼中沒有宣告版本),會出現錯誤訊息:

未宣告版本的錯誤訊息

Error: Pine version must be explicitly specified. Add //@version=N as the first line of the script.

所以在撰寫任何策略腳本前的第一步驟,一定要記得先宣告Pine Script版本。

屬性 Property

Pine Script一定要聲明腳本的屬性(declaration statement),告訴TradingView這程式的用途是什麼,腳本是一種「指標 Indicator」還是「策略 Strategy」?只有標示出腳本的類型,Pine編輯器才會知道程式碼允許出現哪些內容和怎麼執行,

當程式碼沒有聲明腳本屬性,Tradingview會不知道這段程式要用在哪裡,Pine編輯器因此會出現錯誤而無法執行。

  • 指標 Indicator:意思程式碼是用來計算畫圖,在價格上幫助畫出技術指標。但不涉及交易買賣。
  • 策略 Strategy:意思是程式碼裡面會包含下單買進賣出的時機條件、持有部位數等條件訊號。也可以根據策略做回測分析。

想深入了解指標和策略差在哪,看這篇:指標和策略有什麼不一樣?用在哪?

指標腳本 Indicator Script

宣告腳本的屬性是指標,需要用到 indicator 這個函數。

indicator函數 用法介紹

indicator(title, shorttitle, overlay, format, precision, scale, max_bars_back, timeframe, timeframe_gaps, explicit_plot_zorder, max_lines_count, max_labels_count, max_boxes_count, calc_bars_count, max_polylines_count, dynamic_requests, behind_chart)

indicator後面括號中每一個被逗號分開的項目都是一個參數,只有title是必要參數,當使用indicator時一定要提供title(指標的名稱),剩下所有參數都可以選擇性填寫,

例如shorttitle是會出現在圖表右上角的簡短名稱,有填寫的話就會顯示簡稱,沒有填寫也不會造成程式執行的錯誤。

indicator函數 範例說明

indicator("My Indicator", overlay=true)

• My Indicator:指標名稱,你也可以自由取名換別的名字。由於名稱對程式來說是一個字串(字串就是一串字符的意思,英文稱作string),格式上文字的前後需要加上雙引號 ” ,才能讓程式識別這是字串內容,而不是函數或變數。
• overlay=true:true表示指標疊在圖表上,false表示指標會另外在單獨的視窗顯示

這段程式碼宣告了這是一個叫做My Indicator的指標腳本,而且指標會疊在開啟的圖表視窗上。

想一一認識indicator所有可指定的參數,可以看:Pine Script 官方說明手冊

市場先生補充:函數、參數、變數分別是什麼?

• 函數 (Function):函數通常是一段可以重複使用的程式碼,接收參數後做運算,產生出一個結果。

• 參數 (Parameter):參數是函數的輸入值,函數會基於這些輸入的參數做計算產生結果。

• 變數 (Variable):儲存數據結果,變數在程式的執行過程中可以變化,也可以保持不變。

以下用程式碼舉例說明:

f(x) => 
 2x + 1
y = f(3)

f(x):函數,自定義函數f(x)的值會等於輸入值x乘以2再加上1的結果
x:參數,控制函數的輸入值
y:變數,儲存函數的輸出值,根據公式計算得出,結果會因為輸入值x的變化而改變,在這個例子中y會因為指定x代入3而得到y=7

策略腳本 Strategy Script

宣告腳本的屬性是策略,需要用到 strategy 這個函數。

strategy函數 用法介紹

strategy(title, shorttitle, overlay, format, precision, scale, pyramiding, calc_on_order_fills, calc_on_every_tick, max_bars_back, backtest_fill_limits_assumption, default_qty_type, default_qty_value, initial_capital, currency, slippage, commission_type, commission_value, process_orders_on_close, close_entries_rule, margin_long, margin_short, explicit_plot_zorder, max_lines_count, max_labels_count, max_boxes_count, calc_bars_count, risk_free_rate, use_bar_magnifier, fill_orders_on_standard_ohlc, max_polylines_count, dynamic_requests, behind_chart)

strategy和indicator函數使用上是一樣的邏輯,只有title是必填參數,剩下所有參數都是選擇性填寫。

strategy函數 範例說明

strategy ("My Strategy", overlay=true)

• My Strategy:策略名稱
• overlay=true:true表示策略畫的圖會疊在現有圖表上,false表示圖會在另外單獨的視窗顯示

這段程式碼宣告了這是一個叫做My Indicator的策略腳本,而且策略會疊在開啟的圖表視窗上。

市場先生提醒:

接下來這篇文章中提到的所有程式範例,程式碼的開頭全部都需要寫上版本與屬性,也就是

//@version=6
indicator("My Indicator", overlay=true)

//@version=6
strategy("My Strategy", overlay=true)

本文礙於篇幅且範例眾多,以下例子會省略這段共用程式碼,但在 Pine編輯器 編輯時若沒寫清楚版本與屬性,執行會遇到錯誤。

運算子 Operator

程式碼的內容離不開算術邏輯,要將一種策略轉化成為程式語言,一定會用到數學和邏輯,運算子就是其中操作運算的符號,在程式的世界中它們被稱為運算子(也稱作運算符)。

算術運算子

算數運算子就是對數值做數學運算的符號,加、減、乘、除在Pine程式語言中分別對應的算數運算子是+ – * / 。

運算子用途程式碼寫法語法意義執行結果*
+加法y=5+3y是5和3相加y=8
減法y=5-3y是5和3相減y=2
*乘法y=5*3y是5和3相乘y=15
/除法y=5/3y是5除3的結果y=1.67
%除法剩下的餘數y=5%3y是5除3的餘數y=2
^次方y=5^3y是5的3次方y=125
*執行結果是指程式跑完以後會儲存下來的結果,並不會直接顯示在畫面上,除非使用繪圖相關程式指令(後面會介紹到),才能將結果繪製出來顯示在圖表畫面上。
資料來源:TradingView
資料整理:Mr. Market市場先生

比較運算子

Pine Script裡用來比較兩個數值之間的關係就要透過比較運算子,比較出來的結果只有兩種:

• true (正確):比較結果是對的

• false (錯誤):比較結果是錯的

運算子用途程式碼寫法語法意義執行結果*
==判斷相等5==35等於3嗎false
!=判斷不相等5!=35不等於3嗎true
>判斷大於5>35大於3嗎true
<判斷小於5<35小於3嗎false
>=判斷大於或等於5>=35大於等於3嗎true
<=判斷小於或等於5<=35小於等於3嗎false
*執行結果是指這行程式跑完以後會儲存下來的結果,並不會直接顯示在畫面上,儲存的結果可被拿到接下來的程式碼中使用。
資料來源:TradingView
資料整理:Mr. Market市場先生

判斷語法

寫策略程式時一定會用到的重要語法其一就是條件判斷式,例如判斷目前情況是不是符合進場條件,判斷股價有沒有高於或低於某指標,這些情景都會用到條件判斷式,以下介紹重要的Pine Script條件判斷語法。

語法功能適用時機
?:(三元條件運算子)簡化條件判斷簡單條件、計算選擇
if基本條件判斷更複雜的條件邏輯判斷
switch多種條件分別判斷需要一次比較多種條件
資料來源:TradingView
資料整理:Mr. Market市場先生

以下會分別詳細介紹這三種判斷語法的用法和範例:

?:(三元條件運算子)

?:的用法介紹

?:實際使用時,問號和冒號在語法中是分開的,?:只是一種代表縮寫,
當你想在Pine Script中查詢功能解釋時,須輸入?:才能找到三元條件運算子的說明頁面,

?:完整語法如下:

條件 ? trueValue : falseValue

問號前要寫一段條件,假設這段條件執行程式碼時被判斷為真,這行程式碼的結果就會是trueValue這個位置填入的值,反之,當這段條件執行時是被判定不符合的,結果就會是falseValue這個位置填入的值。

?:的範例說明

利用收盤價和均線做比較,判斷目標價格是多少的策略:

10MA = ta.sma(close, 10)
target = close > 10MA ? close + 5 : close - 5

第1行:ta.sma是內建函數(內建函數後面會介紹),ta.sma(close, 10)會用收盤價計算出10日移動平均線,10MA是自己取名的變數,內容是10日移動平均線的計算結果 (稱作10日均線)

第2行:目標價(target) 會因為 ?: 條件判斷出的結果而有不同的數值

  • 收盤價(close)比10日均線(10MA)高:目標價會等於收盤價+5 (close+5)
  • 收盤價(close)比10日均線(10MA)低:目標價會等於收盤價-5 (close-5)

?:的適用時機

• 條件數量少:簡單來說就是 非A即B 的情況,只有一個判斷準則(一種條件),符合條件的話結果就是A,不符合條件的話結果就是B。

• 條件簡單、純計算的選擇題:三元判斷?: 只能執行數學計算,判斷完條件要做的動作是計算出一個數值然後輸出結果,無法執行更複雜的多行邏輯或是使用繪圖函數。

提示:
?:很類似EXCEL裡面的if函式
=if( 條件 , True時結果 , False時的結果)
在Pine裡面寫法變成
條件 ? True時結果 : False時的結果

和if函數不同在於?:只適合呈現簡單運算和簡單結果,複雜的建議還是用下面的if

if

if的用法介紹

if (條件1)
    當條件1為 true 時執行的程式碼
else if (條件2)
    當條件1為 false 且條件2為 true 時執行的程式碼
else
    當條件1和條件2都為 false 時執行的程式碼

第1行:if 後的括號( )裡寫出要被判斷的條件1

第2行:當條件1為真時被觸發,程式會執行這一行程式碼指定的動作

第3行:當條件1為否(條件不成立),程式會接著判斷這一行else if 後的括號裡( )的條件2

第4行:當條件1為否且條件2為真時被觸發,程式會執行這一行程式碼指定的動作

第5行:else 指的是當條件1和條件2都為否(2項條件都不成立)

第6行:2項條件都不成立時被觸發,程式會執行這一行程式碼指定的動作

else if 不限數量

else if部分的程式碼(第3行~第4行)是不限制只有一個else if的,可以無限增加else if數量,也就是說,條件越多項,else if也會隨之增加,例如3項條件需要1個if + 2個else if的搭配才能完成判斷;4項條件需要1個if + 3個else if的搭配才能完成判斷。

else if部分的程式碼也可以被省略,當條件只有1項,只需要寫if和else,而不需要else if的存在了。

else 可省略

else部分的程式碼(第5行~第6行)不是必須存在的,而是可選擇需不需要的,如果這腳本只有條件為真時須執行相對應的動作,可以只保留第1行~第4行程式碼並移除第5行~第6行,代表當條件都不成立時,不用進行任何動作。

市場先生提醒:記得要縮排

if, else if 及 else下一行的code需要縮排(空格),這是Pine Script的規定,沒有縮排的話會出現錯誤,程式碼無法執行。

if的範例說明

利用收盤價和均線做比較,在圖表上作出標記:

10MA = ta.sma(close, 10)
if (close > 10MA)
    label.new(bar_index, high, "Uptrend", style=label.style_label_down, color=color.green)
else if (close < 10MA)
    label.new(bar_index, low, "Downtrend", style=label.style_label_up, color=color.red)
else
    label.new(bar_index, close, "Neutral", style=label.style_label_left, color=color.blue)

以下會逐行程式碼進行說明:

10MA = ta.sma(close, 10)

第1行:ta.sma是內建函數(內建函數後面會介紹),ta.sma(close, 10)會用收盤價計算出10日移動平均線,10MA就是10日移動平均線的計算結果 (稱作10日均線)


if (close > 10MA)
    label.new(bar_index, high, "Uptrend", style=label.style_label_down, color=color.green)

第2行:if判斷式,判斷括號內條件 close > 10MA (收盤價(close)高於10日均線) 是否成立,成立會接著執行第3行,不成立會直接略過第3行跳到第4行

第3行:當括號內條件 close > 10MA 為真時,程式才會執行這一行程式碼,這裡使用到內建函數label.new (內建函數後面會介紹),當收盤價 > 10日均線時標記出「Uptrend」標籤


else if (close < 10MA)
    label.new(bar_index, low, "Downtrend", style=label.style_label_up, color=color.red)

當前面第2行if判斷式括號內的條件不成立,程式執行會跳到第4行。

第4行:else if判斷式,判斷括號內條件 close < 10MA (收盤價(close)低於10日均線) 是否成立,成立會接著執行第5行,不成立會直接略過第5行跳到第6行

第5行:當括號內條件 close < 10MA 為真時,程式才會執行這一行程式碼,這裡使用到內建函數label.new (內建函數後面會介紹),當收盤價 < 10日均線時標記出「Downtrend」標籤


else
    label.new(bar_index, close, "Neutral", style=label.style_label_left, color=color.blue)

第6行:else 只有當前面2項條件都不成立時,程式才會執行到這部分

第7行:2項條件都不成立時,程式會執行這一行程式碼,這裡使用到內建函數label.new (內建函數後面會介紹),當收盤價 = 10日均線時標記出「Neutral」標籤

if的適用時機

通常較複雜的條件邏輯判斷會需要if來完成,沒辦法單純使用三元判斷?:寫出所需的程式碼。

• 判斷完條件相對應的執行動作是新增標籤或繪圖

• 條件數量多:條件數多可透過多個else if完成

• 執行動作複雜:執行動作可以寫多行程式碼來完成,也可以使用函數來完成

switch

switch的用法介紹

假設現在有n項條件,要判斷目前狀態符合哪一項條件,決定輸出結果是什麼:

變數 = switch
    條件1 => 結果1
    條件2 => 結果2
    …
    條件n => 結果n
    => 預設結果

第1行:switch的結果會儲存到變數中,以便後續程式碼操作使用

第2行:當條件1為真時被觸發,變數會儲存結果1

第3行:當條件2為真時被觸發,變數會儲存結果2

第4行~第5行:表示程式碼中間還有很多條件,每一項條件的程式碼寫法都會跟 條件n => 結果n 相似,實際寫程式碼時不會用…和n表示,可以看接下來介紹的範例會更了解

第6行:n項條件(全部條件)都不成立時被觸發,變數會儲存預設結果

switch的條件檢查是依照從上到下的順序,一旦某個條件成立(判斷式為真),就會立刻執行相對應的動作,而且後續的其他條件不會再檢查,只有當條件不成立(判斷式為否),會繼續檢查下一項條件。

如果都沒有任何條件成立,會執行預設結果,也就是 => 後程式碼指定的動作。

市場先生提醒:記得要縮排

switch下方的條件判斷及結果執行的程式碼需要縮排(空格),這是Pine Script的規定,沒有縮排的話會出現錯誤,程式碼無法執行。

下面用實際例子來說明switch的程式碼應該要怎麼寫,搭配應用範例來參考會更容易理解。

switch的範例說明

利用RSI指標判斷市場是否超買或超賣:

RSI = ta.rsi(close, 14)
rsi_status = switch
    RSI > 80 => "Very Overbought"
    RSI > 70 => "Overbought"
    RSI < 30 => "Oversold"
    RSI < 20 => "Very Oversold"
    => "Neutral"
label.new(bar_index, close, rsi_status, style=label.style_label_down, color=color.blue)

以下會逐行程式碼進行說明:

RSI = ta.rsi(close, 14)

第1行:ta.rsi是內建函數(內建函數後面會介紹),ta.rsi(close, 14)會用最近14天的收盤價計算出RSI(相對強弱指標),將計算結果儲存在命名為RSI的這個變數中


rsi_status = switch

第2行:switch的結果會儲存到rsi_status這個變數中,以便後續程式碼操作使用


    RSI > 80 => "Very Overbought"
    RSI > 70 => "Overbought"
    RSI < 20 => "Very Oversold"
    RSI < 30 => "Oversold"
    => "Neutral"

第3行:當RSI > 80 為真時,rsi_status會儲存為”Very Overbought”,程式碼不會再執行剩餘的條件判斷,直接跳到第8行

第4行:當RSI > 80 為否且RSI > 70 為真時,rsi_status會儲存為”Overbought”,程式碼不會再執行剩餘的條件判斷,直接跳到第8行

第5行:當RSI > 80 為否且RSI > 70 也為否,判斷RSI < 20為真時,rsi_status會儲存為”Very Oversold”,程式碼不會再執行剩餘的條件判斷,直接跳到第8行

第6行:當RSI > 80 為否、RSI > 70 為否、RSI < 20也為否,且RSI < 30為真時,rsi_status會儲存為”Oversold”,程式碼不會再執行剩餘的條件判斷,直接跳到第8行

第7行:只有當以上條件都不成立(第3行~第6行皆為否)時,rsi_status會儲存為”Neutral”


label.new(bar_index, close, rsi_status, style=label.style_label_down, color=color.blue)

第8行:不管switch執行後判斷的結果是什麼,這一行程式碼都會執行,這裡使用到內建函數label.new (內建函數後面會介紹),在圖上標示出RSI狀態,標籤內容會由rsi_status決定,分別是「Very Overbought」、「Overbought」、「Oversold」、「Very Oversold」、「Neutral」這五種標籤。

switch的適用時機

switch適合使用在條件數量較多,而且程式後續可能要頻繁進行修改維護的狀況下,

• 條件數量較多:條件數量較多時(條件數>4),相比if-elseif,使用switch的語法會更簡潔。

• 須頻繁進行修改維護:後續可能要動態調整條件、時常須要維護修改程式碼時,switch語法更容易閱讀及擴增新條件。

內建變數

Pine Script有許多內建的變數,是由TradingView事先定義的變數,提供和圖表數據、時間、價格等相關的資訊,可以在程式碼中直接使用。

K棒價格

以下表格整理出K棒價格相關的內建變數:

內建變數代表意義
openK棒的開盤價
closeK棒的收盤價
highK棒的最高價
lowK棒的最低價
資料來源:TradingView
資料整理:Mr. Market市場先生

這些內建變數常被用在技術指標相關的計算,舉例來說,要計算某一天的高低價的平均值,可以直接叫出high和low變數,相加除以2。

avg = (high + low) / 2

上述程式碼會將K棒平均值儲存在名為avg的變數中(變數可以自己取名),讓後續程式碼使用。

K棒時間

以下表格整理出與K棒時間有關的內建變數:

內建變數代表意義輸出結果
monthK棒的月份1~12: 1代表1月,以此類推
yearK棒的年份4位數數字: 2024,代表西元2024年
dayofweekK棒是星期幾0~6: 0代表星期日,1代表星期一
dayofmonthK棒是月份中的第幾天1~31: 1代表當月的1號
資料來源:TradingView
資料整理:Mr. Market市場先生

例如想在圖表上標示出每週一,可以使用dayofweek做到,以下程式碼示範:

if (dayofweek == 1)  
    label.new(bar_index, low, "Monday", style=label.style_label_up, color=color.blue)

只要判斷目前的K棒dayofweek等於1,就代表這根K棒是星期一的K棒,並使用label.new內建函數(後面會介紹),在圖上標示出「Monday」。

K棒序號 (K棒編號)

內建變數代表意義輸出結果
bar_index目前這根K棒的位置編號1: 代表圖表中的第1根K棒
2: 代表圖表中的第2根K棒
以此類推
資料來源:TradingView
資料整理:Mr. Market市場先生

bar_index常配合內建函數label.new(內建標籤函數,後面會介紹)使用,用來標記特定K棒的位置。

例如想標記出第50根K棒在圖表上,可以使用以下程式碼達成:

if (bar_index == 50)
    label.new(bar_index, close, "This is bar 50", style=label.style_label_up, color=color.green)

內建函數

Pine Script有許多內建的函數,在技術分析中比較基礎且通用的指標大多已經有預設函數,這邊會介紹幾個比較常用且實用的函數語法要如何運用。

技術分析相關函數(ta模組)

ta模組是Pine的內建模組,全名是Technical Analysis (技術分析),包含了技術分析會用到的內建函數,例如移動平均線、震盪指標、交叉檢測等。

技術分析指標內建函數
簡單移動平均線
(Simple Moving Average)
ta.sma
加權移動平均線
(Weighted Moving Average)
ta.ema
RSI
(Relative Strength Index)
ta.rsi
MACD
(Moving Average Convergence & Divergence)
ta.macd
KD指標
(Stochastic Oscillator)
ta.stoch
布林通道
(Bollinger Band)
ta.bb
上穿
(Cross Over)
ta.crossover
下穿
(Cross Under)
ta.crossunder
資料來源:TradingView
資料整理:Mr. Market市場先生

以下會一一介紹上表中提及的技術指標ta模組要如何在Pine編輯器中使用:

簡單移動平均線(Simple Moving Average)  

ta.sma 語法

ta.sma(source, length)
  • source: 填入K棒的價格參考來源,例如開盤價、收盤價、最高價、最低價等等,可使用前面介紹過的K棒價格內建參數
  • length: 填入總共要取幾根K棒 (K棒數量)。

ta.sma 範例

sma = ta.sma(close, 14)
plot(sma, color=color.blue, title="SMA")

第1行:使用ta.sma函數,取14天K棒的收盤價做計算,計算結果存入名為sma的變數中

第2行:使用plot函數(內建繪圖函數,後面會介紹)在圖表上繪製出藍色的14日均線,命名為SMA

加權移動平均線(Weighted Moving Average)

ta.ema 語法

ta.ema(source, length)
  • source: 填入K棒的價格參考來源,例如開盤價、收盤價、最高價、最低價等等,可使用前面介紹過的K棒價格內建參數
  • length: 填入總共要取幾根K棒 (K棒數量)。

ta.ema 範例

ema = ta.ema(close, 14)
plot(ema, color=color.orange, title="EMA")

第1行:使用ta.ema函數,取14天K棒的收盤價做計算,計算結果存入名為ema的變數中

第2行:使用plot函數(內建繪圖函數,後面會介紹)在圖表上繪製出橘色的14日加權平均線,命名為EMA

RSI (Relative Strength Index)

ta.rsi 語法

ta.rsi(source, length)
  • source: 填入K棒的價格參考來源,例如開盤價、收盤價、最高價、最低價等等,可使用前面介紹過的K棒價格內建參數
  • length: 填入總共要取幾根K棒 (K棒數量)。

ta.rsi 範例

if (ta.rsi(close, 14) > 70)
    label.new(bar_index, high, "Overbought", style=label.style_label_down, color=color.red)

第1行:使用ta.rsi函數,取14天K棒的收盤價計算RSI,判斷RSI是否有大於70

第2行:當RSI>70成立時,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出「Overbought」

MACD (Moving Average Convergence & Divergence)  

ta.macd 語法

[macd, signal, hist] = ta.macd(source, short, long, signal)

使用ta.macd內建函數,需要填入4個參數設定,會得到3個變數儲存計算結果。

參數:

  • source: 填入K棒的價格參考來源,例如開盤價、收盤價、最高價、最低價等等,可使用前面介紹過的K棒價格內建參數
  • short: 設定短期指數移動平均線(EMA)的週期,常使用12日。
  • long: 設定長期指數移動平均線(EMA)的週期,常使用26日。
  • signal: 設定信號線(Signal line)的週期,常使用9日。

變數:

  • macd: 短期EMA減去長期EMA的值,表示MACD線(快線)。
  • signal: 信號線(慢線)的值。
  • hist: 快線減去慢線的值,得到柱狀圖。

台灣和國外對MACD定義和用詞不太一樣,可以看這裡複習,但一般我們最關注的是柱狀圖變化。

ta.macd 範例

算出MACD快線和慢線,實現黃金交叉與死亡交叉的標記功能:

[macd, signal, hist] = ta.macd(close, 12, 26, 9)
if (ta.crossover(macd, signal))
    label.new(bar_index, low, "Golden Cross", style=label.style_label_up, color=color.green)
if (ta.crossunder(macd, signal))
    label.new(bar_index, high, "Death Cross", style=label.style_label_down, color=color.red)

第1行:使用ta.macd(close, 12, 26, 9),獲得macd(快線)、signal(慢線)和hist的值

第2行:使用ta.crossover函數(內建函數,後面會介紹),判斷macd從下往上穿過signal

第3行:當macd上穿signal成立,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出「Golden Cross」

第4行:使用ta.crossunder函數(內建函數,後面會介紹),判斷macd從上往下穿過signal

第5行:當macd下穿signal成立,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出「Death Cross」

KD指標 (Stochastic Oscillator)

ta.stoch 語法

ta.stoch(close, high, low, length)

使用ta.stoch內建函數計算KD指標,需要填入4個參數設定,且函數只會算出RSV (英文全名: Raw Stochastic Value,中文是未成熟隨機值),K值與D值需要另外計算。

  • close: K棒價格參考收盤價。
  • high: K棒價格參考最高價。
  • low: K棒價格參考最低價。
  • length: 設定計算的週期取幾天,通常會取9天(國內)或14天(國外)。

在國外有兩種不同定義的KD線,分為快版和慢版:

•快版:K線直接使用RSV的數值,D線會再對K線平滑化(通常是取3日移動平均)

•慢版:K線先對RSV平滑化(通常是取3日移動平均),D線再對K線平滑化(通常是取3日移動平均)

ta.stoch的計算結果是RSV值,如果要用ta.stoch分別算出慢版的K值與D值,可使用以下程式碼:

RSV = ta.stoch(close, high, low, 14)
K = ta.sma(RSV, 3)
D = ta.sma(K, 3)

ta.stoch 範例

算出K線和D線,標示出超買與超賣狀態:

RSV = ta.stoch(close, high, low, 14)
K = ta.sma(RSV, 3)
D = ta.sma(K, 3)
if (K > 80)
    label.new(bar_index, high, "Overbought", color=color.red, style=label.style_label_down)
if (K < 20)
    label.new(bar_index, low, "Oversold", color=color.green, style=label.style_label_up)

第1行:使用ta.stoch(close, high, low, 14),獲得RSV的值

第2行:使用ta.sma函數算出K值

第3行:使用ta.sma函數算出D值

第4行:判斷 K值>80 是否成立
(使用快線K線判斷是因為信號變動比較快,能及時反映價格波動,但可能出現雜訊,不希望受雜訊影響想用更穩定的信號判斷,可使用再經過一次平滑的慢線D線)

第5行:當 K值>80 成立,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出「Overbought」(超買)

第6行:判斷 K值<20 是否成立

第7行:當 K值<20 成立,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出「Oversold」(超賣)

布林通道 (Bollinger Band)

ta.bb 語法

[basis, upper, lower] = ta.bb(close, length, mult)

使用ta.bb內建函數,需要填入3個參數設定,會得到3個變數儲存計算結果。

參數:

  • source: 填入K棒的價格參考來源,例如開盤價、收盤價、最高價、最低價等等,可使用前面介紹過的K棒價格內建參數
  • length: 設定移動平均線(SMA)的週期,常使用20日。
  • mult: SMA上下標準差的倍數,用來計算上線與下線的距離,常使用2個標準差。

變數:

  • basis: 中心線,也等於移動平均線。
  • upper: 上線,通常是中心線再加上2倍標準差。
  • lower: 下線,通常是中心線再減去2倍標準差。

ta.bb 範例

計算出布林通道的三條線,在圖上畫出來並分別標記「Basis」(中心線)、「Upper Band」(上線) 與「Lower Band」(下線):

[basis, upper, lower] = ta.bb(close, 20, 2)
plot(basis, color=color.blue, title="Basis")
plot(upper, color=color.green, title="Upper Band")
plot(lower, color=color.red, title="Lower Band")

第1行:使用ta.bb函數,設定使用收盤價、20日均線與2倍標準差,分別獲得中心線、上線與下線的計算結果

第2行:使用plot函數(內建繪圖函數,後面會介紹)在圖上畫出中線,標記「Basis」

第3行:使用plot函數(內建繪圖函數,後面會介紹)在圖上畫出上線,標記「Upper Band」

第4行:使用plot函數(內建繪圖函數,後面會介紹)在圖上畫出下線,標記「Lower Band」

上穿 (Cross Over)

ta.crossover 語法

ta.crossover(series1, series2)

ta.crossover是用來檢查兩個數值之間有沒有交叉的函數,所以需要填入兩個參數,分別是series1與series2,用來判斷series1是否從下方穿過(上穿)series2。

  • 當series1上穿series2:執行結果為true。
  • 當series1沒有上穿series2:執行結果為false。

ta.crossover 範例

判斷當短期均線上穿長期均線時,標記「黃金交叉」:

short_ma = ta.sma(close, 10)
long_ma = ta.sma(close, 30)
if (ta.crossover(short_ma, long_ma))
    label.new(bar_index, low, "Golden Cross", style=label.style_label_up, color=color.green)

第1行:使用ta.sma,獲得10日移動平均線的值(短期均線),存入short_ma變數

第2行:使用ta.sma,獲得30日移動平均線的值(長期均線,存入long_ma變數

第3行:當short_ma上穿long_ma成立,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出「Golden Cross」

下穿 (Cross Under)

ta.crossunder 語法

ta.crossunder(series1, series2)

ta.crossunder是用來檢查兩個數值之間有沒有交叉的函數,只是判斷方向和crossover相反,需要填入兩個參數,分別是series1與series2,用來判斷series1是否從上方穿過(下穿)series2。

  • 當series1下穿series2:執行結果為true。
  • 當series1沒有下穿series2:執行結果為false。

ta.crossunder 範例

判斷當短期均線下穿長期均線時,標記「死亡交叉」:

short_ma = ta.sma(close, 10)
long_ma = ta.sma(close, 30)
if (ta.crossunder(short_ma, long_ma))
    label.new(bar_index, high, "Death Cross", style=label.style_label_down, color=color.red)

第1行:使用ta.sma,獲得10日移動平均線的值(短期均線),存入short_ma變數

第2行:使用ta.sma,獲得30日移動平均線的值(長期均線),存入long_ma變數

第3行:判斷short_ma是否下穿long_ma

第4行:當short_ma下穿long_ma成立,使用label.new函數(內建標籤函數,後面會介紹)在圖表上標示出在「Death Cross」

繪圖/標記函數

TradingView的特色其一就是多功能的圖表,利用Pine編輯器寫程式建立指標或策略後,通常會需要在圖表上標記出相對應的指標或策略進出點位,這時就需要用到繪圖/標記函數。

代表意義內建函數
繪圖plot
標記label.new
資料來源:TradingView
資料整理:Mr. Market市場先生

接下來會介紹繪圖和標記函數的用法:

繪圖函數plot

plot函數是用來繪製數據線條的,可以畫出價格相關數據、重要技術指標、想重點強調的數據曲線,甚至是柱狀圖等等。

plot 語法

plot(series, title, color, linewidth, style, trackprice, histbase, offset)

plot函數中所有的參數只有series是必填的,其他參數項目都是選填,可以不指定,程式會使用預設值。

  • series (必填):在圖表上要繪製的數列。
  • title:繪圖的名稱,語法為title=”名稱”,因為名稱是一組字串(string),在程式中要用雙引號””將字串包起來,程式才能辨別。
  • color:指定線條的顏色,格式要用 color.顏色的英文名稱,例如藍色的語法是color.blue。
  • linewidth:線條的粗細,預設是1,想加粗可以設定一個大於1的數字。
  • style:定義繪圖樣式,例如柱狀圖的語法是plot.style_histogram。
  • trackprice:有設定要追蹤價格的話(trackprice = true),在價格軸上會顯示當下的價格。
  • histbase:有使用柱狀圖的時候,可以用histbase來定義基準線。
  • offset:把畫出來的圖往左或右平移指定的K棒數量,預設值是0,表示繪圖不會水平偏移。

下面簡單介紹幾個範例,讓你了解如何應用上面提到的參數。

plot 範例

1. 繪製簡單平均線

sma = ta.sma(close, 5)
plot(sma, title="SMA", color=color.orange)

第1行:使用ta.sma,獲得5日移動平均線的值,存入sma變數

第2行:用plot函數繪製5日均線(sma),命名線圖名稱為SMA,指定線條顏色為橘色

2. 繪製收盤價,在右側顯示

plot(close, title="Close Price", color=color.blue, trackprice=true)

用plot函數繪製收盤價格曲線(close是收盤價的內建變數),命名線圖名稱為Close Price,指定線條顏色為藍色,並在右側價格軸顯示當下收盤價格。

3. 繪製MACD柱狀圖

[macd, signal, hist] = ta.macd(close, 12, 26, 9)
plot(hist, title="MACD Histogram", color=hist >= 0 ? color.green : color.red, style=plot.style_histogram)

第1行:使用ta.macd,獲得柱狀圖存入hist變數

第2行:用plot函數繪製MACD柱狀圖,數據來源是hist,命名圖表名稱為MACD Histogram,指定當柱狀圖為正時,顏色用綠色,當柱狀圖為負時,顏色用紅色,plot.style_histogram定義了繪圖樣式是柱狀圖。

其中color的語法要分段理解,首先要看

hist >= 0 ? color.green : color.red

這裡用的是前面提及的 ?:三元條件運算子,忘記的話可以先往前複習,當hist大於等於0成立時(柱狀圖為正),會帶出color.green(指定綠色柱狀圖),反之,當hist小於0成立時(柱狀圖為負),會帶出color.red(指定綠色柱狀圖),

這一段程式碼前面再多加上 color= ,就會變回指定plot函數中顏色參數的語法「color=color.顏色的英文名稱」了。

標記函數label.new

label.new 是用來在圖表上新增標籤的函數,輔助用戶視覺化的分析重要資訊,標記出重要的點位或K棒的位置等等。

label.new 語法

label.new(x, y, text, color, style, textcolor, size)

label.new函數中所有的參數只有x與y是必填的,其他參數項目都是選填,可以不指定,程式會使用預設值。

  • x (必填):標籤的水平(x軸)位置,通常會用bar_index,表示標籤會放在哪一根K棒上。
  • y (必填):標籤的垂直(y軸)位置,通常會用價格數值,例如high、low、close。
  • text:標籤顯示的文字,語法為text=”標籤內容”,因為文字是一組字串(string),在程式中要用雙引號””將字串包起來,程式才能辨別。
  • color:指定標籤背景、邊框和箭頭的顏色,格式要用 color.顏色的英文名稱,例如藍色的語法是color.blue預設是透明的。
  • style:定義標籤的樣式,預設是label.style_label_down,代表標籤往下指,也可以使用上指標籤label.style_label_up、圓形標籤label.style_circle或方形標籤label.style_square。
  • textcolor:標籤文字的顏色預設是白色。
  • size:設定標籤的大小,預設是size.normal,其他選項有size.small、size.large、size.auto。

下面簡單介紹幾個範例,讓你了解如何應用上面提到的參數。

label.new 範例

1. 當RSI>70時,標記超買,顯示文字Overbought

if (ta.rsi(close, 14) > 70)
    label.new(bar_index, high, "Overbought", style=label.style_label_down, color=color.red)

第1行:用ta.rsi取得14天RSI數值,判斷是否>70

第2行:用label.new函數在RSI>70的K棒的上方標記Overbought標籤(往下指),背景色是紅色,文字顏色沒有指定,所以是預設的白色。

2. 標記黃金交叉與死亡交叉,顯示文字Golden Cross與Death Cross

sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)
if (ta.crossover(sma_short, sma_long))
    label.new(bar_index, low, "Golden Cross", style=label.style_label_up, color=color.green, textcolor=color.white)
if (ta.crossunder(sma_short, sma_long))
    label.new(bar_index, high, "Death Cross", style=label.style_label_down, color=color.red, textcolor=color.white)

第1行~第2行:用ta.sma取得10天與30天的移動平均線,分別存入sma_short與sma_long變數

第3行:判斷短均線sma_short是否有從下往上穿過長均線sma_long

第4行:用label.new函數在上穿發生的K棒的下方標記Golden Cross標籤(往上指),背景色是綠色,文字顏色是白色。

第5行:判斷短均線sma_short是否有從上往下穿過長均線sma_long

第6行:用label.new函數在下穿發生的K棒的上方標記Death Cross標籤(往下指),背景色是紅色,文字顏色是白色。

策略相關函數

建立策略腳本(strategy script)時,除了在程式碼開頭使用strategy函數,程式碼的最後會需要明確寫出策略進出場的判斷準則,這時會用到策略相關的函數。

策略主要的函數指令,包括進場建倉(多或空),增減倉位、平倉等等條件。

代表意義內建函數
建倉strategy.entry
下單(建倉/加減倉/平倉皆可)strategy.order
平倉(可部分平倉)strategy.exit
全部平倉strategy.close
資料來源:TradingView
資料整理:Mr. Market市場先生

以下會一一介紹上表中提及的strategy相關函數要如何在Pine編輯器中使用:

strategy.entry

strategy.entry用在進場下單(建倉),可以指定開倉的方向是多單或是空單。

strategy.entry 語法

strategy.entry(id, direction, qty, limit, stop, comment)

strategy.entry必填的參數有id和direction,剩下的參數都是選填。

  • id (必填):訂單的名稱代號,用來識別這筆交易。
  • direction (必填):交易的方向,填入 strategy.long 代表做多,或是填入 strategy.short 代表做空。
  • qty:訂單的數量。
  • limit:限價單的價位,觸發時會照指定價格執行交易,預設是na,代表訂單不是限價單。
  • stop:停損單的價位,觸發時會照市價執行交易,預設是na,代表訂單不是停損單。
  • comment:自己定義的註解,方便在策略測試器中辨別操作。

strategy.entry 範例

當短均線上穿突破長均線,進場建倉做多:

sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)
if (ta.crossover(sma_short, sma_long))
    strategy.entry("Long Entry", strategy.long, qty=1)

第1行~第2行:用ta.sma取得10天與30天的移動平均線,分別存入sma_short與sma_long變數

第3行:判斷短均線sma_short是否有從下往上穿過長均線sma_long

第4行:當short_ma上穿long_ma成立,使用strategy.entry函數進場建倉,訂單的名稱(id)為Long Entry,方向是做多,訂單數量設置1

市場先生提醒:使用strategy.entry時若已持有相反方向的倉位,會自動平倉過去所有既有倉位,再建立新的指定數量倉位(翻倉)

假如下多單時已經持有空單倉位,在實際執行strategy.entry會先強制平倉空單,才會建倉指定數量的多單,無法同時持有多單與空單,反之亦然。

舉例來說,當現有倉位是1張多單,使用strategy.entry進場建立空單(方向是strategy.short),當qty設置為1,執行後總持倉會變成持有1張空單(此時多單已被平倉,並且再空1單位空單,實際上等於執行2單位空單)。

如果你只要增減多空倉位,而不是建立新的方向倉位,要用strategy.order指令去加減。

strategy.order

strategy.order是最通用的下單函數,進場和出場都可以使用,可分批建倉(增加部位)或分批平倉(減少部位)。

strategy.order 語法

strategy.order(id, direction, qty, limit, stop, comment)

strategy.order必填的參數有id和direction,剩下的參數都是選填。

  • id (必填):訂單的名稱代號,用來識別這筆交易。
  • direction (必填):交易的方向,填入 strategy.long 代表建立多單或平倉空單,填入 strategy.short 代表建立空單或平倉多單,建倉或平倉是取決於目前持有倉位的數量。
    目前持有多單 →使用strategy.long會增加多單部位,使用strategy.short會平倉
    目前持有空單 →使用strategy.long會平倉,使用strategy.short會增加空單部位
  • qty:訂單的數量。
  • limit:限價單的價位,觸發時會照指定價格執行交易,預設是na,代表訂單不是限價單。
  • stop:停損單的價位,觸發時會照市價執行交易,預設是na,代表訂單不是停損單。
  • comment:自己定義的註解,方便在策略測試器中辨別操作。

strategy.order 範例

當短均線上穿突破長均線(黃金交叉),進場建倉做多:

sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)
if (ta.crossover(sma_short, sma_long))
    strategy.order("Long Order", strategy.long, qty=1, comment="Long Entry")

第1行~第2行:用ta.sma取得10天與30天的移動平均線,分別存入sma_short與sma_long變數

第3行:判斷短均線sma_short是否有從下往上穿過長均線sma_long

第4行:當short_ma上穿long_ma成立,使用strategy.order函數進場建倉,訂單的名稱(id)為Long Order,方向是做多,訂單數量設置1

執行完這段程式碼的倉位結果,會因為原始持倉數量而有所不同,一共會有3種情況:

1. 多單增加:假設在這段程式碼執行之前,當時部位已經有多單,那執行結果會變為原本的多單部位數量再+1。

2. 平倉:假設在這段程式碼執行之前,當時部位已經有1張空單,那執行結果會變為平倉。

3. 空單減少:假設在這段程式碼執行之前,當時部位已經有2張以上空單,那執行結果會變為空單部位數量-1 (相當於平倉1張空單)。

strategy.entry v.s. strategy.order

了解了strategy.entry與strategy.order的功能和語法後,雖然兩者都可以進場建倉,但在使用時機與背後操作邏輯上還是有一些差異,以下整理完整比較表:

功能比較strategy.entrystrategy.order
用途專門用在新進場
直接調整到指定最新多空倉位
進場/出場皆可
在原有倉位上增減單位數
自動全部平倉
下反向單時會自動平倉舊倉位,再建立新倉依據下單數量計算平倉數
適用時機指定單一方向建倉靈活下單策略
分批買進/平倉/加減碼
反向建倉邏輯直接下反向單即可須自行計算訂單數量
平倉操作與strategy.exit搭配使用須自行撰寫平倉邏輯
資料來源:TradingView
資料整理:Mr. Market市場先生

strategy.exit

strategy.exit是用來關閉指定訂單(平倉)的函數,可以部份平倉,也可以設定停損、停利、移動停損等條件。

strategy.exit 語法

strategy.exit(id, from_entry, qty, stop, limit, trail_points, trail_offset)

strategy.exit必填的參數有id和from_entry,剩下的參數都是選填。

  • id (必填):這筆出場單自己的名稱代號,用來識別這一次的交易。
  • from_entry (必填):要關閉的進場訂單名稱代號(strategy.entry中建立的id),用來識別要平倉哪一筆交易。
  • qty:出場訂單的數量,沒有填寫的話預設是全部平倉。
  • limit:限價單的價位,觸發時會照指定價格執行交易,預設是na,代表訂單不是限價單。
  • stop:停損單的價位,觸發時會照市價執行交易,預設是na,代表訂單不是停損單。
  • trail_points:移動停損的點數。
  • trail_offset:移動停損觸發的點位。

strategy.exit 範例

延續前面使用過在黃金交叉時建倉的strategy.entry範例,設定出場停利與停損點:

sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)
if (ta.crossover(sma_short, sma_long))
    strategy.entry("Long Entry", strategy.long, qty=1)
strategy.exit("Long Exit", from_entry="Long Entry", stop=low - 10, limit=high + 20)

第1行~第4行:在strategy.entry範例已解析過,簡單來說是在黃金交叉時做多

第5行:開多單後,設定停損點為目前K棒最低價-10,設定停利點為目前K棒最高價+20,觸發任何一個條件時,平倉出場。

strategy.close

strategy.close是用來關閉指定訂單(平倉)的函數,只能完全平倉,和前面介紹的strategy.exit不一樣,strategy.close無法設定停損、停利、移動停損等條件,且不能部份平倉。

strategy.close 語法

strategy.close(id, comment)

strategy.close必填的參數只有id,剩下的參數都是選填。

  • id (必填):要關閉的進場訂單名稱代號(strategy.entry中建立的id),用來識別要平倉哪一筆交易。
  • comment:自己定義的註解,方便在策略測試器中辨別操作。

strategy.close會關閉指定id訂單的所有倉位,不能部分關倉,所以並不存在qty這個參數。

易混淆觀念澄清:

strategy.close的id代表的意義相當於strategy.exit的from_entry,都是用來確認想關閉的是哪一筆進場訂單,和strategy.entry與strategy.order中的id(進場訂單自己建立的代號)所代表的意義並不一樣。

strategy.close 範例

延續前面使用過在黃金交叉時建倉的strategy.entry範例,
當短均線下穿突破長均線(死亡交叉),立刻將已建立的多單部位關閉:

sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)
if (ta.crossover(sma_short, sma_long))
    strategy.entry("Long Entry", strategy.long, qty=1)
if (ta.crossunder(sma_short, sma_long))
    strategy.close("Long Entry")

第1行~第4行:在strategy.entry範例已解析過,簡單來說是在黃金交叉時做多

第5行:判斷短均線sma_short是否有從上往下穿灌破長均線sma_long

第6行:當short_ma下穿long_ma成立,使用strategy.close函數平倉多單,要平倉的訂單名稱(id)為Long Entry

strategy.exit v.s. strategy.close

了解了strategy.exit與strategy.close的功能和語法後,雖然兩者都可以平倉出場,但在使用時機與功能性上還是有些差異,以下整理完整比較表:

功能比較strategy.exitstrategy.close
用途設定出場條件強制完全平倉
產生新訂單ID
qty參數
部份平倉
(透過qty設定)
設定停損停利
設定移動停損
適用時機靈活出場條件強制平倉
資料來源:TradingView
資料整理:Mr. Market市場先生

Pine Script 執行模型

Pine Script 和一般程式語言最大不同的一點,就是Pine Script執行時是用迴圈的方式執行

會依照TradingView圖表上所設定的時間單位(秒/分/時/日/月/年),分別將每一筆歷史資料帶入程式碼執行一次,直到跑完最後一筆時間的資料,才算執行完畢。

因此Pine Script 並不需要用戶自行寫迴圈帶出每一筆歷史資料,比如說要用到當收盤價這個數據時,只要寫到close這個內建變數,就會在運行程式碼時自動跑一個迴圈,帶出圖表範圍內每一天的當日收盤價。

Pine Script 迴圈執行模型範例

使用Pine Script計算20日均線的程式碼

price = close
20MA = ta.sma(price,20)

第1行:代表將收盤價存入price這個自定義的變數,第一天的price就會是第一天的收盤價,第二天的price就會是第二天的收盤價,以此類推,不需要寫迴圈從第一天開始迭代到最後一天以跑出每一天的price是多少。

第2行:20日均線直接使用內建函數ta.sma,程式會自動取20天的收盤價做計算,以今天已經收盤為例,得到包含今天往前推共20天的收盤價格,再計算出20天收盤價的平均值。

程式會將每一個日期往前推算共20天,並使用20天的收盤價格算出平均值,接連產生一連串的數值連成一條線,這就是簡單移動平均線。

Pine Script 交易策略腳本 怎麼寫?

學習了Pine Script的重要語法後,想知道怎麼寫出一套交易策略腳本,還需要了解腳本程式的架構長怎樣、分為哪幾個部份、分別代表什麼意義。

其實程式的架構邏輯和寫一個策略的步驟很相似,只需要把這些步驟的概念轉換為程式語言,讓程式聽得懂你想做的事,接下來程式就會代你執行策略回測。

交易策略腳本的程式架構一共分為4個部分:

  1. 宣告策略 (Declaration)
  2. 定義指標 (Define Indicators)
  3. 條件判斷 (Conditions)
  4. 交易 (Trade)

宣告策略 (Declaration)

Pine Script開頭一定會要求宣告屬性,由於我們要寫的是策略腳本,必須宣告腳本屬性是Strategy函數。

//@version=6
strategy("My Strategy", overlay=true)

市場先生提醒:使用策略函數宣告策略腳本才能在TradingView策略測試器進行回測。

定義指標 (Define Indicators)

一個交易策略中,或多或少一定會使用到一些技術指標,比如說移動平均線KD指標布林通道等等,這些技術指標的語法前面章節已經介紹過,

在交易策略腳本的程式碼中,需要清楚定義會使用到的指標有哪些,輸入的參數值是多少,舉例來說,使用10日移動平均線當短線、30日移動平均線當長線,就要分別定義兩個變數sma_short和sma_long來儲存10日均線和30日均線這兩個指標。

sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)

條件判斷 (Conditions)

策略什麼時候要進場、什麼時候要出場,全部要依靠條件是否觸發來做判斷,所以在策略腳本的架構組成中,一定會存在條件判斷的部份,

例如最常見的就是指標是否交叉(上穿或下穿):

if (ta.crossover(sma_short, sma_long))
    strategy.entry("Long Entry", strategy.long, qty=1)

有時候也會使用到相對值做條件判斷,例如:

stop_loss = close - 10
take_profit = close + 20 

設定停損點(stop_loss)為最低價-10,設定停利點(take_profit)為最高價+20。

交易 (Trade)

確認已經定義清楚的判斷條件後,接下來就是寫出執行交易的指令,當條件被觸發時,要進行怎樣的交易,例如進場建倉、平倉或轉向先平倉再建倉,還要寫清楚何時出場。

strategy.exit("Long Exit", from_entry="Long Entry", stop=stop_loss, limit=take_profit)

將以上4個步驟寫出的程式碼結合,就可以得到完整的交易策略腳本如下:

//@version=6
strategy("My Strategy", overlay=true)
sma_short = ta.sma(close, 10)
sma_long = ta.sma(close, 30)
if (ta.crossover(sma_short, sma_long))
    strategy.entry("Long Entry", strategy.long, qty=1)
stop_loss = close - 10
take_profit = close + 20 
strategy.exit("Long Exit", from_entry="Long Entry", stop=stop_loss, limit=take_profit)

這交易策略腳本是一個簡單的均線交叉策略,當短期均線上穿長期均線時(黃金交叉)進場做多,出場時機則依靠停損和獲利做判斷。

(提醒:先以大家常見的均線策略舉例示範,比較好理解,並沒有推薦應用此策略之意。)

市場先生 總結

其實市場先生也沒有程式背景,以前因為想了解書上說的一些技術指標到底準不準、能不能在實際操作中使用而動念想自己跑回測,所以自行研究過跑回測需要的程式語言,像是XQ的XS、Multicharts、TradingView的Pine Script等等,

缺乏程式語言能力但想跑回測絕對不是大問題,只要清楚交易策略的準則,再加上一般的數學和邏輯技巧,稍微研究一下程式語法的使用,就可以開始跑回測了。

TradingView是蠻容易上手的一套軟體,回測部分已經預設了很多指標,用戶不用自己寫,也有許多內建的策略可以參考,而且圖表多資料又豐富,

看完這篇回測教學,應該有辦法自己利用TradingView Pine編輯器寫出一套交易策略腳本,或者你也可以先去看看其他的範本寫法,再把範本中的程式條件改成你需要的。

有興趣的人可以自己試試看囉。

前往網站:TradingView官網(點此連結)

這篇寫得很辛苦(程式教學不好寫~),如果覺得有收穫可以留言告訴我,也歡迎在底下留言提供回饋和交流。

延伸閱讀:

1. 回測是什麼?為什麼需要回測?

2. TradingView 回測教學-如何用策略測試器帶入內建策略進行回測?(完整流程圖解教學)

3. TradingView 回測教學-如何用Pine編輯器建立策略腳本?(完整步驟圖解教學)

4. 如何用TradingView腳本編輯器功能設定避開空頭的技術指標【程式篇】

5. TradingView模擬交易工具功能介紹(流程圖解)

這篇文章為市場先生資訊整理與觀念教學分享,內容提到任何標的或券商均無推薦之意,投資必定有風險,任何投資決策前請務必自行評估判斷。


如果覺得這篇文章有幫助,
幫我按個讚,分享給更多人看到,謝謝!

編輯:Crystal 主編:市場先生

上 / 下一篇文章

一般留言

  1. 你好

    我一直用一套免費的indicator於Tradingview ,我現想再加入一些指令,將它成為一個strategy ,然後import去ctrader 的robot algo trade

    請問你們可以做到嗎?if yes,收費是如何計算?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *