零基礎入門商品期貨程序化交易(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.cn/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 !。當然,這些和期貨公司連接之類的機制在回測系統中都是模擬的,為了讓策略的回測和實盤在設計上盡量保持一致。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM