Python做量化|使用AlgoPlus接收期貨實時行情
- 2019 年 11 月 14 日
- 筆記
金融領域也是 Python 的重要方向之一,我知道有一些讀者就是沖著做量化交易才接觸 Python 的。今天給大家分享一個使用 Python 的期貨交易API。
量化交易在中國發展方興未艾。因為T+0且允許做空的交易制度、交易所的大力推動、資訊技術紅利帶來的賺錢效應培養了一大批擁躉等原因,量化交易在期貨行業起步比較早,而且發展比較成熟。
雖然各期貨交易所都開發了自己的交易後台,但是上期所的CTP仍是目前使用最廣泛的。所以,對於想從事量化研究、交易的同學們而言,學習CTP開發是一門必修課。本文就帶大家了解一下CTP,並給大家介紹一個python版CTP交易介面——AlgoPlus
關於CTP
CTP是Comprehensive Transaction Platform的簡稱。CTP有MdApi和TraderApi兩個獨立的開放介面。
MdApi負責行情相關操作(訂閱、接收)。

TraderApi負責交易相關的操作(買、賣、撤、查)。

MdApi與TraderApi方法的執行過程都是非同步的,每一個請求都對應一個或多個負責接收執行結果的回調函數。例如,通過ReqOrderInsert方法向交易所發出買開倉指令,對應的回調方法OnRtnOrder可以實時接收交易所伺服器發回來的執行通知。
關於AlgoPlus
上期所CTP的官方API只支援C++語言,除非有開發經驗,否則不推薦直接使用C++語言開發。
python語言在許多領域被非常廣泛的應用,量化交易也不例外。本文給大家介紹的AlgoPlus就是對官方CTP封裝的python版量化投資介面。相比較其他Python版CTP,AlgoPlus具有以下特點:
- 忠實於CTP官方特性。簡單的說,AlgoPlus就是官方CTP的python翻譯版,沒有過度的封裝,讓交易者根據自己的實際情況選擇官方設計的功能。
- 使用Cython、ctypes技術封裝,即能實現了低延時的要求,又能兼容python語言的易用性。經過嚴格測試,AlgoPlus從策略觸發交易訊號到調用C++方法,延時只有40微秒左右。
- 從實戰的角度為同學們展示量化策略的開發過程,例如趨勢策略、套利策略、風控策略、執行演算法等教程。
安裝AlgoPlus
第一步:安裝Anaconda。
第二步:使用pip install algoplus命令安裝。
當你看到以下內容時:
Processing dependencies for AlgoPlus==1.5 Finished processing dependencies for AlgoPlus==1.5 請按任意鍵繼續. . .
安裝成功!
註冊模擬帳號
1、Simnow是上海期貨交易所旗下技術公司維護的一套模擬交易系統,只需註冊帳號即可免費使用:http://www.simnow.com.cn/
2、在常用下載頁面下載一個客戶端,方便實時查看模擬交易情況:http://www.simnow.com.cn/static/softwareDownload.action
3、記錄個人主頁中的InvestrorID,以及產品與服務頁面中的伺服器地址。配置賬戶參數時需要使用這些資訊。
配置賬戶資訊
FutureAccountInfo是一個期貨賬戶類,包括broker_id(所屬期貨公司的標識),server_dict(行情與交易伺服器地址),reserve_server_dict(備用伺服器地址)、investor_id(賬戶)、password(密碼)、app_id(客戶端ID,與auth_code對應,監管要求)、auth_code(客戶端ID對應的授權碼,監管要求)、instrument_id_list(訂閱合約列表)、md_page_dir(行情相關文件存放地址)、td_page_dir(交易相關文件存放地址)。
將所有的賬戶資訊存放入my_future_account_info_dict字典中。創建交易介面實例時找到相應的賬戶資訊作為參數。
# -*- coding: utf-8 -*- BASE_LOCATION = "." # 根目錄地址 MD_LOCATION = BASE_LOCATION + "\MarketData" # 行情數據地址 TD_LOCATION = BASE_LOCATION + "\TradingData" # 交易數據地址 SD_LOCATION = BASE_LOCATION + "\StrategyData" # 策略數據地址 class FutureAccountInfo: def __init__(self, broker_id, server_dict, reserve_server_dict, investor_id, password, app_id, auth_code, instrument_id_list, md_page_dir=MD_LOCATION, td_page_dir=TD_LOCATION): self.broker_id = broker_id # 期貨公司BrokerID self.server_dict = server_dict # 伺服器地址。TDServer為交易伺服器,MDServer為行情伺服器。伺服器地址格式為"ip:port" self.reserve_server_dict = reserve_server_dict # 備用伺服器地址 self.investor_id = investor_id # 賬戶 self.password = password # 密碼 self.app_id = app_id # 認證使用AppID self.auth_code = auth_code # 認證使用授權碼 self.instrument_id_list = instrument_id_list # 訂閱合約列表[] self.md_page_dir = md_page_dir # MdApi流文件存儲地址,默認MD_LOCATION self.td_page_dir = td_page_dir # TraderApi流文件存儲地址,默認TD_LOCATION my_future_account_info_dict = { # 交易時間測試 'SimNow': FutureAccountInfo( broker_id='9999' # 期貨公司BrokerID # TDServer為交易伺服器,MDServer為行情伺服器。伺服器地址格式為"ip:port" , server_dict={'TDServer': "180.168.146.187:10100", 'MDServer': '180.168.146.187:10110'} # 備用伺服器地址 , reserve_server_dict={'電信1': {'TDServer': "180.168.146.187:10100", 'MDServer': '180.168.146.187:10110'}, '電信2': {'TDServer': "180.168.146.187:10101", 'MDServer': '180.168.146.187:10111'}, '其他1': {'TDServer': "180.168.146.187:10130", 'MDServer': '180.168.146.187:10131'}, # 7*24 '其他2': {'TDServer': "218.202.237.33:10102", 'MDServer': '218.202.237.33:10112'}, # 移動 } , investor_id='' # 賬戶 , password='' # 密碼 , app_id='simnow_client_test' # 認證使用AppID , auth_code='0000000000000000' # 認證使用授權碼 # 訂閱合約列表 , instrument_id_list=[b'rb2001', b'fu2001'] # 訂閱螺紋2001合約和燃料油2001合約 ), }
AlgoPlus創建行情介面
MdApi是行情介面,使用時只需要傳遞賬戶參數創建一個實例就可以了。下面是一個完整的例子:
from AlgoPlus.CTP.MdApi import MdApi class TickEngine(MdApi): # ///深度行情通知 def OnRtnDepthMarketData(self, pDepthMarketData): print(pDepthMarketData) # print(f"{pDepthMarketData.InstrumentID}當前最新價:{pDepthMarketData.LastPrice}") if __name__ == '__main__': from account_info import my_future_account_info_dict future_account = my_future_account_info_dict['SimNow'] tick_engine = TickEngine(future_account.server_dict['MDServer'] , future_account.broker_id , future_account.investor_id , future_account.password , future_account.app_id , future_account.auth_code , future_account.instrument_id_list , None , future_account.md_page_dir) tick_engine.Join()
1、從AlgoPlus.CTP.MdApi文件中導入MdApi類。MdApi已對工作流程的前六步進行了封裝。
2、TickEngine是MdApi的子類。TickEngine類主要實現收到行情的數據處理演算法,示例只將收到的行情列印出來。
3、創建行情介面實例前,需要導入賬戶資訊。示例的賬戶資訊存放在同一個目錄下的account_info.py文件中。
4、交易時間運行以上程式碼就可以將接收到的實時期貨行情列印出來。
5、回調函數OnRtnDepthMarketData接收到的pDepthMarketData行情是DepthMarketDataField結構體的實例,在AlgoPlus.CTP.ApiStruct中被定義。以調用屬性的方式可以獲取行情任意欄位的數值,例如pDepthMarketData.LastPrice表示最新價。DepthMarketDataField包括以下欄位:
class DepthMarketDataField(BaseField): """深度行情""" _fields_ = [ ('TradingDay', c_char * 9) # ///交易日 , ('InstrumentID', c_char * 31) # 合約程式碼 , ('ExchangeID', c_char * 9) # 交易所程式碼 , ('ExchangeInstID', c_char * 31) # 合約在交易所的程式碼 , ('LastPrice', c_double) # 最新價 , ('PreSettlementPrice', c_double) # 上次結算價 , ('PreClosePrice', c_double) # 昨收盤 , ('PreOpenInterest', c_double) # 昨持倉量 , ('OpenPrice', c_double) # 今開盤 , ('HighestPrice', c_double) # 最高價 , ('LowestPrice', c_double) # 最低價 , ('Volume', c_int) # 數量 , ('Turnover', c_double) # 成交金額 , ('OpenInterest', c_double) # 持倉量 , ('ClosePrice', c_double) # 今收盤 , ('SettlementPrice', c_double) # 本次結算價 , ('UpperLimitPrice', c_double) # 漲停板價 , ('LowerLimitPrice', c_double) # 跌停板價 , ('PreDelta', c_double) # 昨虛實度 , ('CurrDelta', c_double) # 今虛實度 , ('UpdateTime', c_char * 9) # 最後修改時間 , ('UpdateMillisec', c_int) # 最後修改毫秒 , ('BidPrice1', c_double) # 申買價一 , ('BidVolume1', c_int) # 申買量一 , ('AskPrice1', c_double) # 申賣價一 , ('AskVolume1', c_int) # 申賣量一 , ('BidPrice2', c_double) # 申買價二 , ('BidVolume2', c_int) # 申買量二 , ('AskPrice2', c_double) # 申賣價二 , ('AskVolume2', c_int) # 申賣量二 , ('BidPrice3', c_double) # 申買價三 , ('BidVolume3', c_int) # 申買量三 , ('AskPrice3', c_double) # 申賣價三 , ('AskVolume3', c_int) # 申賣量三 , ('BidPrice4', c_double) # 申買價四 , ('BidVolume4', c_int) # 申買量四 , ('AskPrice4', c_double) # 申賣價四 , ('AskVolume4', c_int) # 申賣量四 , ('BidPrice5', c_double) # 申買價五 , ('BidVolume5', c_int) # 申買量五 , ('AskPrice5', c_double) # 申賣價五 , ('AskVolume5', c_int) # 申賣量五 , ('AveragePrice', c_double) # 當日均價 , ('ActionDay', c_char * 9) # 業務日期 ]

其他
項目已在 Github 和碼雲上開源。
