天天看點

[QMT]04-在QMT之外調用xtquant直接編寫政策背景前提xtquant簡介啟動XtMiniQmt用戶端xttrader驗證Demo運作結果

背景

希望不用在QMT軟體裡面憋屈地寫代碼,想使用pychar、vscode、notepad++等IDE編寫python代碼,因為有代碼提示、補全。這完全沒問題!QMT簡直是為個人量化交易者量身打造的神器,它支援以上想法。

前提

想在Python本地調用(隻支援python 36\37\38),需要兩個前提條件:

  1. 啟動XtMiniQmt.exe,它存在于QMT安裝目錄下的bin.x64子目錄中。
  1. 将xtquant庫,從bin.x64\Lib\site-packages拷貝到python本地的Lib\site-packages中。比如這裡我的安裝路徑是G:\Anaconda3\Lib\site-packages\xtquant。

xtquant簡介

xtquant是QMT官方内置的XtMiniQmt極簡用戶端對應的Python接口,目前支援Python的版本為3.6~3.8,可支援曆史行情下載下傳、實時資料訂閱、外部資料通路、普通賬戶和兩融賬戶交易(需開通相關權限),對量化交易支援的比較完善,跟極速政策交易系統相比最主要的優勢是簡潔、靈活,不局限在bar、kline的事件觸發,可以容易地內建多種資料源進行綜合分析、判斷。

QMT内置的Python版本為3.6,第一次使用的話需手動下載下傳相關的庫,或直接拷貝已經下載下傳好的xtquant庫。

XtMiniQmt.exe存在于QMT安裝目錄下的bin.x64子目錄中, xtquant庫預設安裝在bin.x64\Lib\site-packages中。

内置的Python版本較老,對于一些較新的庫支援有限,是以,如果我們想在自定義的Python中調用,如Python3.8,隻需将xtquant拷貝到我們自己python安裝目錄的Lib\site-packages中便可,這裡我的安裝路徑是 C:\ProgramData\Anaconda3\Lib\site-packages\xtquant。

QMT這個東東基本是由兩部分組成的:QMT交易終端(看盤界面 + 政策界面) + 量化庫(xtquant)

XtQuant:基于迅投MiniQMT衍生出來的一套完善的Python政策運作架構,以Python庫的形式提供政策交易所需要的:行情 + 交易 API接口。

它封裝了政策交易所需要的Python API接口,可以和MiniQMT用戶端互動,報單、撤單、查資産、查委托、查成交、查持倉以及收到資金、委托、成交和持倉等變動的主推消息。

xtquant主要包含兩大塊:

  • xtdata:xtdata提供和MiniQmt的互動接口,本質是和MiniQmt建立連接配接,由MiniQmt處理行情資料請求,再把結果回傳傳回到python層。需要注意的是這個子產品的使用目前并不需要登入,是以隻要安裝了QMT,就可以無門檻的使用其提供的資料服務。
  • xttrader:xttrader是基于迅投MiniQMT衍生出來的一套完善的Python政策運作架構,對外以Python庫的形式提供政策交易所需要的交易相關的API接口。該接口需開通A股實盤版權限方可登入使用。

啟動XtMiniQmt用戶端

啟動MiniQMT用戶端。通常有兩種方式,一種是直接啟動極簡QMT用戶端XtMiniQmt.exe:

[QMT]04-在QMT之外調用xtquant直接編寫政策背景前提xtquant簡介啟動XtMiniQmt用戶端xttrader驗證Demo運作結果

另一種是啟動QMT量化交易終端XtItClient.exe,在登入界面選擇極簡模式:

[QMT]04-在QMT之外調用xtquant直接編寫政策背景前提xtquant簡介啟動XtMiniQmt用戶端xttrader驗證Demo運作結果

部分券商不支援政策的雲伺服器運作,但接收行情資料不受影響。設定好用戶端後,便可在ipython、jupyter等環境中調試資料和政策了。

xttrader驗證Demo

需要調整的參數:①:77行的path變量需要改為本地用戶端路徑 ②:84行的資金賬号需要調整為自身資金賬号

注意:本政策隻用于提供政策寫法及參考,若您直接進行實盤下單,造成損失本部落客概不負擔責任。

# 建立政策
#coding=utf-8
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
from xtquant import xtconstant

class MyXtQuantTraderCallback(XtQuantTraderCallback):
    def on_disconnected(self):
        """
        連接配接斷開
        :return:
        """
        print("connection lost")
    def on_stock_order(self, order):
        """
        委托回報推送
        :param order: XtOrder對象
        :return:
        """
        print("on order callback:")
        print(order.stock_code, order.order_status, order.order_sysid)
    def on_stock_asset(self, asset):
        """
        資金變動推送
        :param asset: XtAsset對象
        :return:
        """
        print("on asset callback")
        print(asset.account_id, asset.cash, asset.total_asset)
    def on_stock_trade(self, trade):
        """
        成交變動推送
        :param trade: XtTrade對象
        :return:
        """
        print("on trade callback")
        print(trade.account_id, trade.stock_code, trade.order_id)
    def on_stock_position(self, position):
        """
        持倉變動推送
        :param position: XtPosition對象
        :return:
        """
        print("on position callback")
        print(position.stock_code, position.volume)
    def on_order_error(self, order_error):
        """
        委托失敗推送
        :param order_error:XtOrderError 對象
        :return:
        """
        print("on order_error callback")

        print(order_error.order_id, order_error.error_id, order_error.error_msg)
    
    def on_cancel_error(self, cancel_error):
        """
        撤單失敗推送
        :param cancel_error: XtCancelError 對象
        :return:
        """
        print("on cancel_error callback")
        print(cancel_error.order_id, cancel_error.error_id,
        cancel_error.error_msg)
    def on_order_stock_async_response(self, response):
        """
        異步下單回報推送
        :param response: XtOrderResponse 對象
        :return:
        """
        print("on_order_stock_async_response")
        print(response.account_id, response.order_id, response.seq)
    
if __name__ == "__main__":
    print("demo test")
    # path為mini qmt用戶端安裝目錄下userdata_mini路徑
    path =r'輸入你本地的userdata_mini目錄'
    # session_id為會話編号,政策使用方對于不同的Python政策需要使用不同的會話編号
    session_id = 123456
    xt_trader = XtQuantTrader(path, session_id)
    
    # 建立資金賬号為1000000365的證券賬号對象
    #acc = StockAccount('1000000365')
    acc = StockAccount('輸入你的QMT資金賬号')
    # 建立交易回調類對象,并聲明接收回調
    callback = MyXtQuantTraderCallback()
    xt_trader.register_callback(callback)
    
    # 啟動交易線程
    xt_trader.start()
    
    # 建立交易連接配接,傳回0表示連接配接成功
    connect_result = xt_trader.connect()
    print(connect_result)
    
    # 對交易回調進行訂閱,訂閱後可以收到交易主推,傳回0表示訂閱成功
    subscribe_result = xt_trader.subscribe(acc)
    print(subscribe_result)
    #stock_code = '600000.SH'
    stock_code = '000768.SZ'
    # 使用指定價下單,接口傳回訂單編号,後續可以用于撤單操作以及查詢委托狀态
    print("order using the fix price:")
    fix_result_order_id = xt_trader.order_stock(acc, stock_code,
    xtconstant.STOCK_BUY, 200, xtconstant.FIX_PRICE, 10.5, 'strategy_name',
    'remark')
    print(fix_result_order_id)
    
    # 使用訂單編号撤單
    print("cancel order:")
    cancel_order_result = xt_trader.cancel_order_stock(acc, fix_result_order_id)
    print(cancel_order_result)
    
    # 使用異步下單接口,接口傳回下單請求序号seq,seq可以和on_order_stock_async_response 的委托回報response對應起來
    print("order using async api:")
    async_seq = xt_trader.order_stock(acc, stock_code, xtconstant.STOCK_BUY,
    200, xtconstant.FIX_PRICE, 10.5, 'strategy_name', 'remark')
    print(async_seq)

    # 查詢證券資産
    print("query asset:")
    asset = xt_trader.query_stock_asset(acc)
    if asset:
        print("asset:")
        print("cash {0}".format(asset.cash))

    # 根據訂單編号查詢委托
    print("query order:")
    order = xt_trader.query_stock_order(acc, fix_result_order_id)
    if order:
        print("order:")
        print("order {0}".format(order.order_id))


    # 查詢當日所有的委托
    print("query orders:")
    orders = xt_trader.query_stock_orders(acc)
    print("orders:", len(orders))
    if len(orders) != 0:
        print("last order:")
        print("{0} {1} {2}".format(orders[-1].stock_code,
        orders[-1].order_volume, orders[-1].price))
    
    # 查詢當日所有的成交
    print("query trade:")
    trades = xt_trader.query_stock_trades(acc)
    print("trades:", len(trades))

    if len(trades) != 0:
        print("last trade:")
        print("{0} {1} {2}".format(trades[-1].stock_code,
        trades[-1].traded_volume, trades[-1].traded_price))


    # 查詢當日所有的持倉
    print("query positions:")
    positions = xt_trader.query_stock_positions(acc)
    print("positions:", len(positions))
    
    if len(positions) != 0:
        print("last position:")
        print("{0} {1} {2}".format(positions[-1].account_id,
        positions[-1].stock_code, positions[-1].volume))
    
    # 根據股票代碼查詢對應持倉
    print("query position:")
    position = xt_trader.query_stock_position(acc, stock_code)
    if position:
        print("position:")
        print("{0} {1} {2}".format(position.account_id, position.stock_code,
        position.volume))

    # 阻塞線程,接收交易推送
    xt_trader.run_forever()

           

運作結果

[QMT]04-在QMT之外調用xtquant直接編寫政策背景前提xtquant簡介啟動XtMiniQmt用戶端xttrader驗證Demo運作結果