撰寫交易策略的SOP

By | 2016-04-22

隨著開始使用XS寫交易策略的朋友們愈來愈多,我們愈來愈常被求救,問題看多了,歸納整理後,我寫了一個撰寫交易策略的SOP,我認為在撰寫交易腳本時,有四大步驟,嚴謹且按步就班地作好每個步驟,應該可以協助我們完成交易策略的撰寫。

這四個步驟如下圖

撰寫腳本的SOP

 

茲分項說明之

一,準備數據

程式交易語法跟其他如C++,Java等不同之處,是在於它的目標很明確~透過大量金融數據的運算,作成交易決策,所以在一個程式交易腳本中,最基本的課題是: “要拿那些金融數據進來運算?”

每個腳本,都像一道食譜,每個食譜,都會要我們先準備食材,腳本的食材,就是我們要拿下去運算的每個元素,在XS的腳本中,這些要拿來加減乘除作運算的元素,可以歸類為以下幾種

1. 即時行情的數據。包括單量,當日漲幅,內盤量,外盤量,五檔委買賣的價與委託量等等,我們可以用 Getquote的語法把它們拉出來使用。

2. 盤後數據。包括法人進出,資券變化,主力進出等等數據,我們用Getfield的語法把這些欄位拿到腳本中來使用

3. 回傳值。開高低收成交量等語法中最基本的元素,在以K棒為基礎的架構裡,我們可以用Close[n]之類的語法,把K棒中 的每一個被存下來的值拿來運算。

4. 參數。為了更改參數方便而由使用者以INPUT的語法所設定的參數,也是可以被拿來腳本中作運算。

5. 變數。為了運算方便,由使用者自行宣告的變數,也是腳本中常見的元素。

6. 常數。有的時候,就是會運用到簡單的阿拉伯數字,或是True及false這兩個布林值,這些都是腳本運算中常用的元素。當我們要要撰寫一個腳本時,就像食譜要先準備的食材一樣,我們得先決定要用上述六大類裡的那些元素,這個決定的工作,就像是煮一道菜之前,先把相關的食材從冰箱裡取出來。

0 42201 

決定好之後,接下來要做的是事情有兩個

第一個是宣告: 我們先透過宣告的方式,把要用的變數及參數先準備好,我們為它們取名字,設初始值。

第二個是指定: 然後接下來我們用getquote及getfield的語法,把盤後資料及盤中資料指定到特定的某個變數

二,建構演算

以上的這兩個步驟,就好像是煮菜之前的備料工作。備完料,接下來就是建構演算的機制,在這當中,若是有需要,會使用到系統或自訂的 函數。    大家可以透過先前學會的流程控,以及各種函數,透過數學及邏輯運算,完成各種運算。

這部份主要是看個人的功力,只能多看多寫,多看別人寫過的好語法。

三,設定輸出條件

接下來,就是建立輸出條件,我們用if ……..then  ret=1; 來指定策略雷達的觸發條件,以及選股的符合條件,用if………then plot1…;來輸出自訂指標。

我與個例子來說明以上的流程

我們希望電腦在個股符合下列三個條件時通知我們,

  1.    十日法人買超的移動平均超過1000張
  2.    當日外盤量佔成交量超過五成
  3.    當日股價比前一日上漲

那麼我們可以寫下一個腳本如下:

各位可以看到,我們依以下的步驟在完成一個警示腳本

步驟一: 宣告參數

步驟二: 宣告變數

步驟三: 取得盤後資料

步驟四: 取得即時數據

步驟五: 建構運算關係

步驟六: 設立觸發,畫指標或確認 函數的敘述式

當然在實作上,步驟一到步驟五的任何一項 ,都可能因為沒有用到相關數據而被省略,最簡單的警示腳本如if close=high then ret=1;就只有步驟六而已。

但如果大家記得這六個基本的步驟,應該可以很快的把各式各樣的數據,同步放在一個警示腳本中來使用。

042202

 

 

 四,編譯與勘誤

接下來的編譯及勘誤,是另一個重點,很多朋友就算是提供了中文的勘誤,還是無法自行找出程式碼的問題之所在,所以我把大家常見的程式上的疏誤,以及在勘誤時系統會出現的訊息做了一個對照表如下,供大家參考。

XS的勘誤方式,跟其他的IDE類似,在使用者按下編譯按鈕之後,如果程式有Bug,會在訊息視窗中,以表格的方式來呈現錯誤的地方,其呈現方式如下:

 

物件名稱 行號 字元 錯誤描述
呈現腳本的名稱 顯示錯誤的敘述在第幾行 錯誤的地方是從該行的第幾個字元開始 表達錯誤的可能原因,俾使用者正確地找到錯誤。

 

根據我自己使用的經驗,User通常會出現的錯誤,以及XS編輯器對應會出現的勘誤訊息,大致有以下幾類。

 文字上的小失誤

 

錯誤描述 原因說明及備註
未知的關鍵字 “xxx”,請檢查是否有宣告此變數或是拼字是否有誤。 可能是自己宣告的參數或變數的名稱打字時打錯了,造成電腦無法理解這個字代表的意思
需要輸入更多參數。 通常是像plot1之類的忘了把裡頭的參數輸進去,如果是函數忘了輸入正確的參數個數,系統會直接呈現”需要輸入x個參數”
需要輸入 x ~ y 個參數。 輸入的參數比系統要求的多時會出現這個message
在 “xxxxxx” 之前可能少了”;”, “DOWNTO”, “TO”, “OR”, “XOR”, “AND”, “=”, “<>”, “<“, “>”, “<=”, “>=”, “Crosses Above”, “Crosses Over”, “Crosses Below”, “Crosses Under”, “+”, “-“, “*”, “/” 最有可能的是前一行忘了打分號。
編譯器看到了一個無法辨認的字 “x”,請檢查這個字有沒有寫錯。 這種情況通常是輸入了之前沒有宣告過的文字格式內容

 流程的錯誤

 

錯誤描述 原因說明及備註
for 迴圈的變數型態應為數值。 for的用法為for 某變數=xx to xxxxx及xxx必須都是數值
「IF/Once/While/Repeat」後面需要一個真偽值或是真偽值的判斷式。 這些流程的後面必須是一個布林值的判斷式,不能是一個結果是特定數值的運算式

 

 函數的錯誤使用

 

錯誤描述 原因說明及備註
需要輸入x個參數 這代表使用這函數所需要輸入的參數的個數與user實際輸入的參數並不相符,可能是漏打或是多打了某個參數。
函數 xxxxx:第 x 個參數應該是 Numeric(string)。 這代表使用者輸入的函數參數格式錯了,該是數字的地方使用了文字,或是該是文字的地方使用了數字。
函數宣告的輸入型態有誤,應該是 Numeric,NumericSimple,NumeircSeries, String,StringSimple,StringSeries,TrueFalse,TrueFalseSimple,TrueFalseSeries。 在自訂函數宣告參數時必須宣告資料的型態而不是直接使用初始值
函數 xxxxx:第 x 個參數應該是 Numeric 函數裡每一個參數的格式(type)必須是對的,不能把文字放到該填數值的函數去
參數的數值不可以在函數中被修改,如果有需修改參數值,請將參數型態改為 NumericRef(數值)或是 NumericArray(陣列)。 在函數中的參數,它的數值是不能在宣告後直接被賦予特定值的,例如不能寫input:abc(numeric);abc=1;

 

 用到不該用的欄位

 

錯誤描述 原因說明及備註
在「警示」腳本中無法使用「plot」 在警示類的腳本中不能使用plot
此欄位無法使用 [ ](無法索引前期值)。 例如在getquote的欄位裡使用前期值的語法
在「指標」腳本中無法使用「xxxxx」。 在指標類型的腳本中不能使用getquote的欄位

 

 數值與布林值使用上的混淆

 

錯誤描述 原因說明及備註
“=” 左右兩邊的型態不同。 數值是無法等於布林值的,例如不能寫value1=true; 因為value1是數值變數,true是布林值,應該要寫成condition1=true;
“+” 左右兩邊的型態不同。 數值跟布林值是無法相加的
“AND” 與左右兩邊的型態不同。 and的兩邊必須都是布林值的敘述,不能有數值
“-” 與右邊的型態不同 減號的兩邊都必須是數值
“not” 與右邊的型態不同。 not的兩邊都必須是布林值

 

 宣告參數時容易發生的失誤

 

錯誤描述 原因說明及備註
在指標跟警示裡面不用型態的方式,請修正。 在指標跟警示裡,使用input宣告參數時直接用初始值,而不是宣告資料型態。

 

 變數使用上的錯誤

 

錯誤描述 原因說明及備註
變數 “xxx” 為系統保留文字,請更改變數名稱。 宣告變數時用到了其他關鍵字, 或是重覆宣告了同名字的變數
變數 “xxx” 沒有宣告,請用 Vars: 的方式宣告,冒號後面是變數名稱再用括號填入預設值。例如: Vars:varA(100); 如果要宣告陣列請用 Arrays: 冒號後面是名稱再用 [] 設定維度與大小,括號填入預設值。例如 Arrays:arr1[10](0);。 直接使用了某個電腦看不懂的英文字詞,電腦會提醒把這個字詞宣告成變數後再來使用
xxxx不是陣列,不能在後面加 [ ],請把  [ ] 與裡面的數字移除掉。 在使用變數前一期值時要小心,不要直接指定特定一期值為某常數,因為這是陣列才會有的行為,例如可以寫value1=value1[1]+value1[2];但不能寫value1[1]=5;

 

 陣列使用上出現的疏誤

 

錯誤描述 原因說明及備註
變數宣告為 Array 但沒有宣告陣列維度,例:Array:arr[X](numericarray); 使用陣列時只記得宣告是陣列卻忘了宣告陣列的維度
有宣告陣列維度但變數並不是宣告為 Array。 宣告了陣列的參數,但忘了宣告陣列格式的變數,兩邊對不起來
陣列參照不正確。 宣告陣列後,必須按陣列的格式來assign值或變數,而不能像非陣列的assign方式,例如宣告了一個陣列如下:array:arr1[5](0);arr1[1]=1; 這樣寫是可以的,但不能寫成

arr1=1; 因為在陣列中的每一個變數都是獨立的,不能透過這種語法想要一次assign所有陣列的值都是1

同樣的,也不能寫成

value1=arr1;

因為左邊是一個變數,右邊是一個陣列。
另外維度兩邊對不起來時也可能出現陣列參照不正確的訊息

陣列(Array)宣告不支援超過9維的維度。 這種情況代表使用者宣告的陣列維度超過九個,這超出了系統所能提供的上限。

 

 

當編譯後出現錯誤訊息後,即可根據上面表格的說明,找出錯誤的原因並且加上修正,如此一來可以縮短程式開發的速度,並且讓程式可以忠實呈現使用者的想法。