上篇文章我們一起學習了商品期貨交易方面的一些基礎概念、常識。本篇我們繼續從實際出發,學習商品期貨程序化交易策略的基礎設計。
內容講解以CTP協議為例(不清楚CTP這個名詞的可以看一下上篇文章)。
所有操作的前提--和期貨公司前置機連接
我們已經學習了一個重要的概念就是我們的交易程序不是直接連通商品期貨交易所的。而是我們的交易程序連接的是期貨公司的前置機服務器,我們的策略程序觸發交易時一系列的操作例如下單、撤單、查詢賬戶資產、獲取行情等請求都是和期貨公司前置機交互的。那有的同學可能會問:“我們的交易程序下的單只提交到了期貨公司前置機服務器,那么最終是怎么到交易所的?畢竟交易所才是最終撮合交易的地方。”
我們的交易策略程序和期貨公司前置機交互,至於下單、撤單請求最終怎么到交易所,那就是期貨公司前置機和交易所的業務范圍了,可以不予考慮。當然,以上只是簡單描述。實際情況例如CTP協議,當策略程序和期貨公司前置機建立連接之后期貨公司前置機會主動推送行情和一些消息。我們不過多研究CTP協議,這里只了解即可。
在FMZ上設計商品期貨交易策略的第一個需要牢記的概念就是:“確保和期貨公司前置機連接成功”。策略程序中所有的操作都必須基於和期貨公司前置機連接成功的前提之下。所以就有了FMZ API
文檔中描述的商品期貨策略基礎框架(以JavaScript語言編寫策略為例):
function main(){
while(true){
// 需要在判斷exchange.IO("status")函數返回true,即為真值時才可調用行情、交易等函數
if(exchange.IO("status")){
exchange.SetContractType("MA000")
var ticker = exchange.GetTicker()
Log("MA000 ticker:", ticker)
LogStatus(_D(), "已經連接CTP !")
} else {
LogStatus(_D(), "未連接CTP !")
}
}
}
可能有的同學看到代碼就直接感到頭大了。不用怕,本篇文章帶你徹底征服這段代碼。
function
首先我們來說說function
這個單詞,這個單詞是JavaScript語言的關鍵字,所謂關鍵字就是這門編程語言中定義好的一個名稱,這個名稱只用於一個用途。function
的用途就是創建一個函數。那么有萌新同學又會問了:“什么是函數?”。簡單說,函數就是你輸入給它一些參數,它給你反饋一些數據,或者做一些處理,或者執行一些邏輯。
那么function
這個單詞的作用在JavaScript語言中就是創建一個函數。接着往function
后面看,是另一個單詞:main
。這個main
並不是關鍵字,只是一個名稱,意思為“主要的”。function
后面跟着main
就是說這里創建了一個函數,這個函數名稱叫main
。再往后看是一對小括號()
,如果你創建的函數需要傳參數,在這個小括號內就可以寫上形式參數,這里不做深究,暫且知道就行。我們創建的這個名為main
的函數是沒有參數的,所以這里()
里面就是空空的。
繼續往后看,如下圖中的紅色標記:
又是一對兒符號,但是這里是一對兒{}
花括號。我們把花括號連帶其中的代碼內容稱為函數體,就是你要讓函數做的操作統統寫在這里,OK我們也不做深究。至此我們學會了如何創建一個函數了,那么動手實踐實踐,我們利用FMZ的回測系統,很方便的可以學習JavaScript語言。
使用回測系統測試、學習
我們登陸FMZ平台之后,點擊控制中心
,然后點擊策略庫
,然后點擊新建策略
按鈕。然后設置語言為JavaScript語言,如圖:
創建策略時,默認給出的代碼是:
function main() {
return exchange.GetName();
}
這個默認的代碼是一個main
函數,這個main
函數只執行一句代碼:return exchange.GetName();
先不做深究。(這里順便回顧一下,還記得我們開始講的么?商品期貨必須要先判斷連接上前置機服務器)我們清空代碼編輯區。
我們就可以練習創建一個函數了,我們在代碼編輯區鍵入:
function main() {
}
這樣我們就在策略中創建了一個函數,名為main
,我們可以運行一下。
點擊模擬回測
切換到回測頁面,使用回測系統測試。
- 1、設置回測的交易所對象為
商品期貨
。 - 2、添加這個設置好的交易所對象。
- 3、顯示添加上了。
- 4、點擊回測按鈕測試策略代碼。
發現沒任何動靜!! 因為我們函數體里什么都沒寫嘛!如果我們在main
函數的函數體中寫上一句輸出語句Log("你好 FMZ!")
,例如:
function main() {
Log("你好 FMZ!")
}
那么再次點擊模擬回測
按鈕運行一下,就可以看到有日志輸出了。
至於Log
這個是什么?這個語句就是打印日志信息用的,詳細用法后續再講,暫且了解即可。
主函數main
我們經過實踐,創建了一個策略。在策略中創建了一個函數名為main
。可能有的同學會問如果我創建的函數名字不叫main
呢?回測測試時策略還會運行起來么?
答案肯定是:不行。FMZ上策略是必須從main
函數作為入口執行的,如果你的策略中沒有創建main
函數將會報錯,有興趣的可以動手試下,比如上例子中main
改為main1
,雖然名字只加上了一個字符1
。所以我們又學到了,策略必須有main
函數。
函數體中的while
語句
while
又是一個要學習的編程語言關鍵字,這個關鍵字的意思是執行一個循環。while
關鍵字后面跟着是一個小括號()
,這個小括號里面的表達式是while
循環是否能執行的條件。這里可以看到這個小括號()
中寫着一個true
,true
是一個布爾值並且為真值,意思就是“這個循環是否能執行的條件”是一直為真,這個循環在沒有其它跳出循環的語句影響下,會一直執行(如果該循環體中,沒有其它跳出循環的語句,那么這個循環就叫死循環,因為會一直不停的執行循環體)。在while
語句的()
循環條件之后緊跟着就是循環體了,循環體代碼是由{}
花括號包裹住的。
關於“表達式”這個名詞,簡單說就是一個由變量、運算符等組合起來的式子,這個式子是有值的。可以是各種條件、計算的組合,在用作循環的條件時,這個表達式的值的真假決定了循環的是否執行,在以后的量化交易策略編程學習中,還會遇到,這里暫且了解即可。{}
花括號之內的一行一行的代碼,就是每次循環時要逐行執行的代碼了。
if (條件表達式) {觸發時執行的代碼} else {觸發時執行的代碼}
語句
學習完了while
循環,我們看循環體中另一個關鍵字if...else
。if
語句可以單獨使用,也可以和if else
或者else
一起配合使用。
我們先看if
的用法,if語句的意思就如同這個單詞的字面意思“如果”。if之后跟着一個小括號()
我們都已經很熟悉了,這里小括號里面也是需要寫入一個表達式,作為條件判斷,這里可能你聽得一臉懵!沒關系,我們動手來實踐下。運用我們上面學習到的知識,我們很容易寫出一個main
函數,用來在回測系統中測試學習這個if語句。
function main() {
if (1) {
Log("1為真值,所以條件觸發")
}
if (0) {
Log("0為假值,能觸發就見鬼了 >_< ")
}
}
可以看到1
這個數值也可以作為一個表達式,它的值為真。所以上圖中觸發了if
條件語句的執行代碼Log("1為真值,所以條件觸發")
。可以看到這句代碼也是被{}
包裹,在Javascript語言中{}
包裹的代碼為代碼塊,里面可以是一行代碼,也可以是N行代碼。
測試中,第一個if判斷,由於條件為真(1這個值恆為真),所以執行了這個if語句攜帶的代碼塊中的代碼。第二個if判斷,由於條件為假(0這個值恆為假),所以沒有執行這個if語句攜帶的代碼塊中的代碼,{}
中的Log("0為假值,能觸發就見鬼了 >_< ")
這句代碼。
說完了if
語句,那else
語句呢?做什么用的?else
是要和if
配合一起用的,作用簡單說就是在組合使用中,if的條件如果沒觸發就執行else后面的代碼塊。來看這個例子:
function main() {
if (0) {
Log("0為假值,能觸發就見鬼了 >_< ")
} else {
Log("當你看到這句話輸出時,代碼里上面那個if條件一定是假的!不信去看看代碼 ( ̄ ii  ̄;) 吸溜 ( ̄ \"  ̄;) ")
}
}
先講到這里,下篇繼續。