零基礎入門商品期貨程序化交易(3)

接着上篇文章我們繼續學習。

所有操作的前提--和期貨公司前置機連接

exchange.IO("status")函數判斷與期貨公司前置機連接狀態

可能有的同學會問exchange是什麼?

答:在 零基礎入門商品期貨程序化交易(1) 篇最後,我們動手實踐了一下運行了一個看上去挺複雜的策略,功能是在FMZ實盤頁面狀態欄上顯示一個表格,表格上爲所有的合約代碼以及相關信息。我們實踐時在實盤頁面給實盤配置的 華泰期貨次席(看穿式監管) 就對應策略代碼中的exchange即交易所對象。

所以exchange是什麼?

答:簡單理解exchange就是我們配置好的期貨公司賬戶!

那在實盤上可以配置多個這樣的代表期貨公司賬戶的交易所對象麼?

答:當然可以,不過這屬於略微高階一點的內容,我們僅僅知道就可以,暫時用不到。

上篇我們學會了if(...) {...} else {...}語句的基本用法。接着我們就要學習重點了,前面講解了那麼多基礎語法就是爲了這裏的一個功能。還記得我們說過的:所有操作的前提--和期貨公司前置機連接這句話麼?在if語句的小括號中的判斷條件就是用來判斷和期貨公司前置機連接狀態的。這個if中的表達式條件由exchange.IO("status")函數調用返回。

exchange.IO("status")函數調用時返回true,表示與期貨公司前置機已經連接(並且正常登錄)。

exchange.IO("status")函數調用時返回false,表示與期貨公司前置機未連接。原因可能是:

  • 未到開盤時間,期貨公司前置機服務器並未開啓。
  • 賬戶密碼配置錯誤,這時有錯誤日誌輸出,參看前幾篇文章中提及的內容。
  • 認證失敗,配置的期貨公司未看穿式認證,這時也有錯誤日誌輸出。
  • 網絡原因,IP地址錯誤、端口錯誤等,伴隨錯誤日誌輸出。

這裏就很容易理解這個程序邏輯結構了:

function main(){
    while(true){
        if(exchange.IO("status")){

        } else {
          
        }
    }
}

整個商品期貨策略框架就是:

從策略代碼的主函數,也就是main函數開始執行。首先遇到了一個while循環,並且循環的條件恆定爲真值。所以這個循環會不停的執行。每次執行這個循環的循環體代碼時,會使用if語句進行判斷,通過exchange.IO("status")函數調用時返回的值來確定系統與期貨公司前置機服務器的連接以及登錄狀態(exchange.IO("status")是固定寫法可以死記硬背!)。如果exchange.IO("status")函數返回了true則執行對應的if代碼塊內的代碼。如果返回了false則執行對應的else代碼塊內的代碼。

exchange.SetContractType()設置合約函數

接着我們看看如果和期貨公司前置機服務器連接上之後要做點什麼操作。當exchange.IO("status")函數調用返回true時程序的執行流程就進入了if語句對應的代碼塊,這時已經確定了和期貨公司前置機通信連接正常。可以執行獲取行情、下單等操作。但是請想一想我們做這些操作是不是需要有個目標,簡單說就是要對哪個合約做下單操作?獲取哪個合約的行情?

這裏我們就要學習到一個新的FMZ的API函數:SetContractType(),可以看到SetContractType()exchange交易所對象的成員函數。簡單說就是SetContractType()是基於exchange調用的,作用是設置exchange這個交易所對象代表的期貨賬戶當前所要操作的合約。

代碼中exchange.SetContractType("MA000")我們傳入了參數MA000MA000是一個合約代碼,我們查詢 零基礎入門商品期貨程序化交易(1) 中實踐運行的例子顯示的合約代碼表格里,可以看到MA代碼是指甲醇合約,那麼000是指什麼呢?000是FMZ平臺定義的指數合約代碼,組合起來MA000就是甲醇指數合約。類似的在FMZ上定義的虛擬合約還有主力連續合約(使用888表示),寫法是MA888表示這個合約是甲醇主力連續合約。

exchange.GetTicker()獲取行情數據

當設置好當前的合約,明確了要操作的合約,就可以獲取這個合約的行情數據了。

我們學習的另一個函數GetTicker(),這個函數也是exchange交易所對象的成員函數。作用是獲取當前的實時行情數據,數據結構爲:

{
  "Info": {
    ...
  },
  "High": 2559,
  "Low": 2559,
  "Sell": 2635,
  "Buy": 2528,
  "Last": 2559,
  "Volume": 598161,
  "OpenInterest": 1218937,
  "Time": 1625799200000
}

var ticker = exchange.GetTicker()這行代碼調用了GetTicker()函數獲取當前實時行情賦值給聲明的ticker變量。

Log("MA000 ticker:", ticker)

Log函數作爲使用最頻繁的函數,使用起來也很簡單。其作用就是輸出傳入的參數在實盤的日誌區域。

Log函數用於把一些認爲關鍵的信息在實盤日誌中輸出,也常用於調試策略程序,觀察分析程序中的數據。這裏我們執行的Log("MA000 ticker:", ticker)函數,其中傳入了2個參數。第一個參數是一個字符串MA000 ticker:,第二個參數是被賦值後的ticker變量。

運行時輸出的日誌如下圖:

LogStatus()_D()函數

最後再學習這兩個FMZ的API函數,本例就算是學習完了。

LogStatus函數和Log函數類似,只不過Log函數是在實盤頁面的日誌區域輸出。LogStatus函數是在實盤頁面的狀態欄上輸出,如圖:

至於LogStatus函數還有很多有趣的用法,目前可以暫時先了解到此。(有興趣的可以查看API文檔自行提前學習:https://www.fmz.com/api#logstatusmsg)

那麼_D()函數是做什麼用的呢?

_D()函數用途也十分簡單,如果不傳入參數就是返回一個當前的時間字符串,通常是用來打印當前時間方便觀察。

回測測試

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 !")
        }
    }
}

至此,以上這段代碼從整體到細節我們都分析了一遍。前幾篇內容中也提過,其實我們在FMZ上學習的時候可以充分利用FMZ平臺的回測系統學習策略設計、編程語言語法,甚至提升自己的DEBUG能力(排錯能力)。以上代碼也可以在回測系統中運行。

設置好之後,點擊開始回測按鈕策略就在回測系統中運行起來了。

當然,這個策略代碼例子僅僅是在判斷實盤程序和exchange對應的期貨公司前置機連接之後,設置exchange對象當前操作的合約爲MA000即甲醇指數合約,然後打印實時行情數據。在未連接的狀態下,僅僅在狀態欄上輸出時間未連接CTP !。當然,這些和期貨公司連接之類的機制在回測系統中都是模擬的,爲了讓策略的回測和實盤在設計上儘量保持一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章