天天看點

Python量化交易開源架構:AmazingQuant

1.簡介

開源位址:

https://github.com/zhanggao2013/AmazingQuant AmazingQuant是一款基于event-driven的量化回測交易開源架構,下圖是總體架構架構。
Python量化交易開源架構:AmazingQuant

data_center

to_mongoDB 存放行情、财務等各種資料到MongoDB的存儲子產品

get_data 政策中從資料庫中取資料的接口子產品

trade_center

mossion_engine 包含下單任務(event_order)和風控(event_risk_management)兩部分的engine,分别完成下單前的檢查和風控

broker_engine 分為回測時的simulate的broker(主要是event_deal)撮合成交和連接配接實盤交易CTP、xSpeed等接口兩部分

strategy_center

bar_engine 在回測或者交易模式下,用

逐K線

的方式執行每一根bar的交易邏輯,可在日線、分鐘線、分筆下運作

analysis_center

analysis_engine 對回測形成的交易記錄進行分析和可視化,淨值、年化收益、alpha、beta、回撤等名額,brison、Fama等經典模型的實作

2.安裝配置

MongoDB 3.4

建議使用shard,配置啟動項示例

pymongo

python調用MongoDB

talib

技術名額計算庫

anaconda

python 3.5 的版本,如果大于3.5的版本,ctp的接口暫時不能用,因為編譯問題,後續可以解決

Linux Ubuntu

開發環境是ubuntu,當然也可以在windows下用,但是資料庫的配置和ctp等交易接口需要重新做

安裝AmazingQuant

pip install AmazingQuant 直接安裝

3.政策編寫

# -*- coding: utf-8 -*-

__author__ = "gao"

import numpy as np
import talib

# import strategy基類
from AmazingQuant.strategy_center.strategy import *

# import 交易子產品
from AmazingQuant.trade_center.trade import Trade


# 繼承strategy基類
class MaStrategy(StrategyBase):
    def initialize(self):
        # 設定運作模式,回測或者交易
        self.run_mode = RunMode.BACKTESTING.value
        # 設定回測資金賬号
        self.account = ["test0", "test1"]
        # 設定回測資金賬号資金量
        self.capital = {"test0": 2000000, "test1": 1000}
        # 設定回測基準
        self.benchmark = "000300.SH"
        # 設定複權方式
        self.rights_adjustment = RightsAdjustment.NONE.value
        # 設定回測起止時間
        self.start = "2015-01-11"
        self.end = "2016-01-16"
        # 設定運作周期
        self.period = "daily"
        # 設定股票池
        self.universe = ['000001.SZ', '000002.SZ', '000008.SZ', '000060.SZ', '000063.SZ', '000069.SZ', '000100.SZ',
                         '000157.SZ', '000166.SZ', '000333.SZ', '000338.SZ', '000402.SZ', '000413.SZ', '000415.SZ',
                         '000423.SZ', '000425.SZ', '000503.SZ', '000538.SZ', '000540.SZ', '000559.SZ', '000568.SZ',
                         '000623.SZ', '000625.SZ', '000627.SZ', '000630.SZ', '000651.SZ', '000671.SZ', '000686.SZ',
                         '000709.SZ', '000723.SZ', '000725.SZ', '000728.SZ', '000738.SZ', '000750.SZ', '000768.SZ',
                         '000776.SZ', '000783.SZ', '000792.SZ', '000826.SZ', '000839.SZ', '000858.SZ', '000876.SZ',
                         '000895.SZ', '000898.SZ', '000938.SZ', '000959.SZ', '000961.SZ', '000963.SZ', '000983.SZ',
                         '001979.SZ', '002007.SZ', '002008.SZ', '002024.SZ', '002027.SZ', '002044.SZ', '002065.SZ',
                         '002074.SZ', '002081.SZ', '002142.SZ', '002146.SZ', '002153.SZ', '002174.SZ', '002202.SZ',
                         '002230.SZ', '002236.SZ', '002241.SZ', '002252.SZ', '002292.SZ', '002294.SZ', '002304.SZ',
                         '002310.SZ', '002352.SZ', '002385.SZ', '002411.SZ', '002415.SZ', '002424.SZ', '002426.SZ',
                         '002450.SZ', '002456.SZ', '002460.SZ', '002465.SZ', '002466.SZ', '002468.SZ', '002470.SZ',
                         '002475.SZ', '002500.SZ', '002508.SZ', '002555.SZ', '002558.SZ', '002572.SZ', '002594.SZ',
                         '002601.SZ', '002602.SZ', '002608.SZ', '002624.SZ', '002673.SZ', '002714.SZ', '002736.SZ',
                         '002739.SZ', '002797.SZ', '002831.SZ', '002839.SZ', '002841.SZ', '300003.SZ', '300015.SZ',
                         '300017.SZ', '300024.SZ', '300027.SZ', '300033.SZ', '300059.SZ', '300070.SZ', '300072.SZ',
                         '300122.SZ', '300124.SZ', '300136.SZ', '300144.SZ', '300251.SZ', '300315.SZ', '600000.SH',
                         '600008.SH', '600009.SH', '600010.SH', '600011.SH', '600015.SH', '600016.SH', '600018.SH',
                         '600019.SH', '600021.SH', '600023.SH', '600028.SH', '600029.SH', '600030.SH', '600031.SH',
                         '600036.SH', '600038.SH', '600048.SH', '600050.SH', '600061.SH', '600066.SH', '600068.SH',
                         '600074.SH', '600085.SH', '600089.SH', '600100.SH', '600104.SH', '600109.SH', '600111.SH',
                         '600115.SH', '600118.SH', '600153.SH', '600157.SH', '600170.SH', '600177.SH', '600188.SH',
                         '600196.SH', '600208.SH', '600219.SH', '600221.SH', '600233.SH', '600271.SH', '600276.SH',
                         '600297.SH', '600309.SH', '600332.SH', '600340.SH', '600352.SH', '600362.SH', '600369.SH',
                         '600372.SH', '600373.SH', '600376.SH', '600383.SH', '600390.SH', '600406.SH', '600415.SH',
                         '600436.SH', '600482.SH', '600485.SH', '600489.SH', '600498.SH', '600518.SH', '600519.SH',
                         '600522.SH', '600535.SH', '600547.SH', '600549.SH', '600570.SH', '600583.SH', '600585.SH',
                         '600588.SH', '600606.SH', '600637.SH', '600649.SH', '600660.SH', '600663.SH', '600674.SH',
                         '600682.SH', '600685.SH', '600688.SH', '600690.SH', '600703.SH', '600704.SH', '600705.SH',
                         '600739.SH', '600741.SH', '600795.SH', '600804.SH', '600816.SH', '600820.SH', '600827.SH',
                         '600837.SH', '600871.SH', '600886.SH', '600887.SH', '600893.SH', '600895.SH', '600900.SH',
                         '600909.SH', '600919.SH', '600926.SH', '600958.SH', '600959.SH', '600977.SH', '600999.SH',
                         '601006.SH', '601009.SH', '601012.SH', '601018.SH', '601021.SH', '601088.SH', '601099.SH',
                         '601111.SH', '601117.SH', '601118.SH', '601155.SH', '601163.SH', '601166.SH', '601169.SH',
                         '601186.SH', '601198.SH', '601211.SH', '601212.SH', '601216.SH', '601225.SH', '601228.SH',
                         '601229.SH', '601288.SH', '601318.SH', '601328.SH', '601333.SH', '601336.SH', '601375.SH',
                         '601377.SH', '601390.SH', '601398.SH', '601555.SH', '601600.SH', '601601.SH', '601607.SH',
                         '601608.SH', '601611.SH', '601618.SH', '601628.SH', '601633.SH', '601668.SH', '601669.SH',
                         '601688.SH', '601718.SH', '601727.SH', '601766.SH', '601788.SH', '601800.SH', '601818.SH',
                         '601857.SH', '601866.SH', '601872.SH', '601877.SH', '601878.SH', '601881.SH', '601888.SH',
                         '601898.SH', '601899.SH', '601901.SH', '601919.SH', '601933.SH', '601939.SH', '601958.SH',
                         '601966.SH', '601985.SH', '601988.SH', '601989.SH', '601991.SH', '601992.SH', '601997.SH',
                         '601998.SH', '603160.SH', '603799.SH', '603833.SH', '603858.SH', '603993.SH']

        # 設定在運作前是否緩存日線,分鐘線等各個周期資料
        self.daily_data_cache = True
        print(self.universe)

        # 回測滑點設定,按固定值0.01,20-0.01 = 19.99;百分比0.01,20*(1-0.01) = 19.98;平倉時用"+"
        self.set_slippage(stock_type=StockType.STOCK.value, slippage_type=SlippageType.SLIPPAGE_FIX.value, value=0.01)

        # 回測股票手續費和印花稅,賣出印花稅,千分之一;開倉手續費,萬分之三;平倉手續費,萬分之三,最低手續費,5元
        # 滬市,賣出有萬分之二的過戶費,加入到賣出手續費
        self.set_commission(stock_type=StockType.STOCK_SH.value, tax=0.001, open_commission=0.0003,
                            close_commission=0.0003,
                            close_today_commission=0, min_commission=5)
        # 深市不加過戶費
        self.set_commission(stock_type=StockType.STOCK_SZ.value, tax=0.001, open_commission=0.0003,
                            close_commission=0.0005,
                            close_today_commission=0, min_commission=5)

    def handle_bar(self, event):
        # 取目前bar的持倉情況
        available_position_dict = {}
        for position in Environment.bar_position_data_list:
            available_position_dict[position.instrument + "." + position.exchange] = position.position - position.frozen
        # 目前bar的具體時間戳
        current_date = data_transfer.millisecond_to_date(millisecond=self.timetag, format="%Y-%m-%d")
        # 時間戳轉換成int,友善後面取資料
        current_date_int = data_transfer.date_str_to_int(current_date)
        print(current_date)
        # 取資料執行個體
        data_class = GetData()
        # 循環周遊股票池
        for stock in self.universe:
            # 取目前股票的收盤價
            close_price = data_class.get_market_data(Environment.daily_data, stock_code=[stock], field=["close"],
                                                     end=current_date)
            # print(self.start, current_date)
            close_array = np.array(close_price)
            if len(close_array) > 0:
                # 利用talib計算MA
                ma5 = talib.MA(np.array(close_price), timeperiod=5)
                ma20 = talib.MA(np.array(close_price), timeperiod=20)
                # print(type(close_price.keys()))
                # 過濾因為停牌沒有資料
                if current_date_int in close_price.keys():
                    # 如果5日均線突破20日均線,并且沒有持倉,則買入這隻股票100股,以收盤價為指定價交易
                    if ma5[-1] > ma20[-1] and stock not in available_position_dict.keys():
                        Trade(self).order_shares(stock_code=stock, shares=100, price_type="fix",
                                                 order_price=close_price[current_date_int],
                                                 account=self.account[0])
                        print("buy", stock, 1, "fix", close_price[current_date_int], self.account)
                    # 如果20日均線突破5日均線,并且有持倉,則賣出這隻股票100股,以收盤價為指定價交易
                    elif ma5[-1] < ma20[-1] and stock in available_position_dict.keys():
                        Trade(self).order_shares(stock_code=stock, shares=-100, price_type="fix",
                                                 order_price=close_price[current_date_int],
                                                 account=self.account[0])
                        print("sell", stock, -1, "fix", close_price[current_date_int], self.account)


if __name__ == "__main__":
    # 測試運作完整個政策所需時間,目前沒有做過多優化,
    # 300隻股票,日線資料,一年的時間區間,4000多次交易記錄,在我的虛拟機大概80s,換個性能稍好點的機器,應該會快很多
    from AmazingQuant.utils.performance_test import Timer

    time_test = Timer(True)
    with time_test:
        # 運作政策,設定是否儲存委托,成交,資金,持倉
        MaStrategy().run(save_trade_record=True)
           

4.回測結果分析

自動生成回測結果

産生的委托,成交,資金,持倉的cvs檔案寫入到政策所在檔案夾

自動生成回測報告

回測報告是html格式,可在浏覽器中打開檢視,效果如下圖:

Python量化交易開源架構:AmazingQuant

5.實盤交易

目前已實作根據vnpy的方式封裝的使用boost對CTP的C++接口進行python3.5的封裝,後續将實作與broker_engine的對接

6.已實作和即将實作的功能

已實作

資料庫搭建

讀取資料

政策運作回測

回測交易記錄的儲存和分析

實盤CTP接口的封裝

即将實作

各種資料的對接

例如股票的分鐘資料、股票财務資料、股票闆塊成分股、期貨分鐘資料、日線資料等

CTP等交易接口與broker_engine對接

CTP、xSpeed等

對回測區間的每一根bar的交易和持倉情況可視化

回測分析子產品的豐富

增加brison、FAMA等各種績效歸因模型的分析和可視化

原文釋出時間為:2018-07-15

本文作者:gao

本文來自雲栖社群合作夥伴“

Python中文社群

”,了解相關資訊可以關注“