量化投資:第3節 滑點策略與交易手續費

来源:http://www.cnblogs.com/abupy/archive/2017/10/18/7689531.html
-Advertisement-
Play Games

作者: 阿布 阿布量化版權所有 未經允許 禁止轉載 "abu量化系統github地址(歡迎+star,你的支持是我更新的動力!)" "本節ipython notebook" 上一節使用AbuFactorBuyBreak和AbuFactorSellBreak且混入基本止盈止損策略AbuFactorAt ...


作者: 阿布

阿布量化版權所有 未經允許 禁止轉載

abu量化系統github地址(歡迎+star,你的支持是我更新的動力!)

本節ipython notebook

上一節使用AbuFactorBuyBreak和AbuFactorSellBreak且混入基本止盈止損策略AbuFactorAtrNStop,
風險控制止損策略AbuFactorPreAtrNStop,利潤保護止盈策略AbuFactorCloseAtrNStop來提高交易的盈利效果。

本節將繼續在上一節回測的基礎上示例擇時策略其它使用方法,首先完成上一節的回測準備,如下所示:

from abupy import AbuFactorBuyBreak, AbuFactorSellBreak
from abupy import AbuFactorAtrNStop, AbuFactorPreAtrNStop, AbuFactorCloseAtrNStop
from abupy import ABuPickTimeExecute, AbuBenchmark, AbuCapital

# buy_factors 60日向上突破,42日向上突破兩個因數
buy_factors = [{'xd': 60, 'class': AbuFactorBuyBreak}, 
               {'xd': 42, 'class': AbuFactorBuyBreak}]
# 四個賣出因數同時並行生效
sell_factors = [
    {
        'xd': 120,
        'class': AbuFactorSellBreak
    },
    {
        'stop_loss_n': 0.5,
        'stop_win_n': 3.0,
        'class': AbuFactorAtrNStop
    },
    {
        'class': AbuFactorPreAtrNStop,
        'pre_atr_n': 1.0
    },
    {
        'class': AbuFactorCloseAtrNStop,
        'close_atr_n': 1.5
    }]
benchmark = AbuBenchmark()
capital = AbuCapital(1000000, benchmark)

1 滑點買入賣出價格確定及策略實現

第一節中實現的買入策略和賣出策略的編寫,買入策略中確定買入只是通過make_buy_order函數,確定買單生成,賣出策略確定賣出訂單
也只是通過fit_sell_order來提交賣單,那麼執行訂單,應該使用的什麼價格買入或者賣出呢,abupy在預設的策略都是使用當天的均價買入賣出,

當然你可以實現多種複雜的當日交易策略,設置限價單、市價單,獲取當日的分時數據再次進行策略分析執行操作,但是如果你的回測數量足夠多的情況下,比如全市場回測,按照大數定理,這個均值執行其實是最好的模擬,而且簡單、運行速度快。

滑點買入賣出價格確定具體實現代碼請閱讀AbuSlippageBuyMean和AbuSlippageSellMean,它們的實現都很簡單

在買入滑點AbuSlippageBuyMean中有一個小策略噹噹天開盤價格直接下探7%時,放棄買單,看上一節回測結果中如下圖這次交易,從圖上就可以發現雖然是突破買入,但明顯第二天執行買單時的價格是直線下跌的,且下跌不少,但還是成交了這筆交易。因為開盤下跌幅度沒有達到7%的閥值,下麵我們就過擬合這次交易避免買入,只為示例

下麵編寫一個獨立的Slippage策略,只簡單修改g_open_down_rate的值為0.02

from abupy import AbuSlippageBuyBase, slippage
# 修改買入下跌閥值為0.02
g_open_down_rate = 0.02

class AbuSlippageBuyMean2(AbuSlippageBuyBase):
    """示例日內滑點均價買入類"""

    @slippage.sbb.slippage_limit_up
    def fit_price(self):
        """
        取當天交易日的最高最低均價做為決策價格
        :return: 最終決策的當前交易買入價格
        """
        # TODO 基類提取作為裝飾器函數,子類根據需要選擇是否裝飾,並且添加上根據order的call,put明確細節邏輯
        if self.kl_pd_buy.pre_close == 0 or (self.kl_pd_buy.open / self.kl_pd_buy.pre_close) < (1 - g_open_down_rate):
            # 開盤就下跌一定比例閥值,放棄單子
            return np.inf
        # 買入價格為當天均價,即最高,最低的平均,也可使用高開低收平均等方式計算
        self.buy_price = np.mean([self.kl_pd_buy['high'], self.kl_pd_buy['low']])
        # 返回最終的決策價格
        return self.buy_price

上面編寫的AbuSlippageBuyMean2類實現即為滑點買入類的實現:

  1. 滑點買入類需要繼承自AbuSlippageBuyBase
  2. 滑點買入類需要實現fit_price來確定交易單執行當日的最終買入價格
  3. slippage_limit_up裝飾器是針對a股漲停板買入價格決策的裝飾器,處理買入成功概率,根據概率決定是否能買入,及漲停下的買入價格決策,漲停下買入價格模型為,越靠近漲停價格買入成交概率越大,即在漲停下預期以靠近漲停價格買入,

備註:slippage_limit_up及slippage_limit_down具體實現可閱讀源代碼,後面的章節有示例演示使用

但是滑點類時什麼時候被實例化使用的呢,怎麼使用我們自己寫的這個滑點類呢?首先看買入因數基類AbuFactorBuyBase,在每個買入因數初始化的時候即把預設的滑點類以及倉位管理類(稍後講解)賦值,如下片段代碼所示:

詳情請查看AbuFactorBuyBas源代碼

class AbuFactorBuyBase(six.with_metaclass(ABCMeta, ABuParamBaseClass)):
    def __init__(self, capital, kl_pd, **kwargs):
        # 走勢數據
        self.kl_pd = kl_pd
        # 資金情況數據
        self.capital = capital
        # 滑點類,預設AbuSlippageBuyMean
        self.slippage_class = kwargs['slippage'] \
            if 'slippage' in kwargs else AbuSlippageBuyMean
        # 倉位管理,預設AbuAtrPosition
        self.position_class = kwargs['position'] \
            if 'position' in kwargs else AbuAtrPosition
        if 'win_rate' in kwargs:
            self.win_rate = kwargs['win_rate']
        if 'gains_mean' in kwargs:
            self.gains_mean = kwargs['gains_mean']
        if 'losses_mean' in kwargs:
            self.losses_mean = kwargs['losses_mean']
        self._init_self(**kwargs)

之後因數在每次生效產生買單的時候會觸發AbuOrder實例對象的fit_buy_order()函數,fit_buy_order()中將滑點類,倉位管理類實例化後,執行買入價格及數量確定,代碼片段如下所示,詳情請查看源代碼。

def fit_buy_order(self, day_ind, factor_object):
    kl_pd = factor_object.kl_pd
    # 要執行買入當天的數據
    kl_pd_buy = kl_pd.iloc[day_ind + 1]
    # 買入因數名稱
    factor_name = factor_object.factor_name \
        if hasattr(factor_object, 'factor_name') else 'unknown'
    # 滑點類設置
    slippage_class = factor_object.slippage_class
    # 倉位管理類設置
    position_class = factor_object.position_class
    # 初始資金,也可修改策略使用剩餘資金
    read_cash = factor_object.capital.read_cash
    # 實例化滑點類
    fact = slippage_class(kl_pd_buy, factor_name)
    # 執行fit_price(), 計算出買入價格
    bp = fact.fit_price()
    # 如果滑點類中決定不買入,撤單子,bp就返回正無窮
    if bp < np.inf:
        # 實例化倉位管理類
        position = position_class(kl_pd_buy, factor_name, bp, 
                                  read_cash)
        # 執行fit_position(),通過倉位管理計算買入的數量
        buy_stock_cnt = int(position.fit_position(factor_object))
        if buy_stock_cnt < 1:
            return

賣出因數的滑點操作及倉位管理與買入類似,讀者可以自行閱讀源代碼。

由以上代碼我們可以發現通過buy_factors的字典對象中傳入slippage便可以自行設置滑點類,由於上圖顯示的交易是60日突破產生的買單,所以我們只修改60日突破的字典對象,執行後可以看到如下圖所示,過濾了兩個60日突破的買單,即過濾了上圖所示的交易,代碼如下所示:

備註:實際上如果只是修改g_open_down_rate的值,可以通過模塊全局變數直接修改,本節只為示例使用流程

# 針對60使用AbuSlippageBuyMean2
buy_factors2 = [{'slippage': AbuSlippageBuyMean2, 'xd': 60,
                 'class': AbuFactorBuyBreak},
                {'xd': 42, 'class': AbuFactorBuyBreak}]
capital = AbuCapital(1000000, benchmark)
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
                                                                            benchmark,
                                                                            buy_factors2,
                                                                            sell_factors,
                                                                            capital,
                                                                            show=True)

2. 交易手續費的計算以及自定義手續費

交易必然會產生手續費,手續費的計算在ABuCommission模塊中,比如本例中使用的的美股交易回測,使用的手續費計算代碼如下所示:

def calc_commission_us(trade_cnt, price):
    """
    美股計算交易費用:每股0.01,最低消費2.99
    :param trade_cnt: 交易的股數(int)
    :param price: 每股的價格(美元)(暫不使用,只是保持介面統一)
    :return: 計算結果手續費
    """
    # 每股手續費0.01
    commission = trade_cnt * 0.01
    if commission < 2.99:
        # 最低消費2.99
        commission = 2.99
    return commission
    

針對不同市場美股,a股,港股,比特幣,期貨有不同計算手續費的方法,更多詳情請閱讀ABuCommission模塊源代碼

下麵先看看之前的回測交易中產生的手續費情況,查看代碼如下所示:

capital.commission.commission_df

如果你想把自己的計算手續費的方法使用在回測中,只需要編寫手續費函數,示例如下所示:

def calc_commission_us2(trade_cnt, price):
    """
        手續費統一7美元
    """
    return 7

如上編寫的手續費函數統一每次買入賣出都是7美元手續費,手續費函數有兩個參數一個trade_cnt代表買入(賣出)股數,
另一個參數是price,代表買入(賣出)價格,下麵使用這個自定義的手續費方法做回測,代碼如下所示:

# 構造一個字典key='buy_commission_func', value=自定義的手續費方法函數
commission_dict = {'buy_commission_func': calc_commission_us2}
# 將commission_dict做為參數傳入AbuCapital
capital = AbuCapital(1000000, benchmark, user_commission_dict=commission_dict)
# 除了手續費自定義外,回測其它設置不變,show=False不可視化回測交易
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
                                                                            benchmark,
                                                                            buy_factors2,
                                                                            sell_factors,
                                                                            capital,
                                                                            show=False)
# 回測完成後查看手續費情況
capital.commission.commission_df

從上面回測交易手續費結果可以看到,買入的手續費都變成了7元,賣出手續費還是之前的演算法,下麵的回測將買入賣出手續費計算方法都變成使用自定義的方法,代碼如下所示:

# 賣出字典key='sell_commission_func', 指向同一個手續費方法,當然也可以定義不同的方法
commission_dict = {'buy_commission_func': calc_commission_us2, 'sell_commission_func': calc_commission_us2}
# 將commission_dict做為參數傳入AbuCapital
capital = AbuCapital(1000000, benchmark, user_commission_dict=commission_dict)
# 除了手續費自定義外,回測其它設置不變,show=False不可視化回測交易
orders_pd, action_pd, _ = ABuPickTimeExecute.do_symbols_with_same_factors(['usTSLA'],
                                                                            benchmark,
                                                                            buy_factors2,
                                                                            sell_factors,
                                                                            capital,
                                                                            show=False)
# 回測完成後查看手續費情況
capital.commission.commission_df

從回測結果即可以看到所有買入賣出的手續費都是7美元

abu量化文檔目錄章節

  1. 擇時策略的開發
  2. 擇時策略的優化
  3. 滑點策略與交易手續費
  4. 多支股票擇時回測與倉位管理
  5. 選股策略的開發
  6. 回測結果的度量
  7. 尋找策略最優參數和評分
  8. A股市場的回測
  9. 港股市場的回測
  10. 比特幣,萊特幣的回測
  11. 期貨市場的回測
  12. 機器學習與比特幣示例
  13. 量化技術分析應用
  14. 量化相關性分析應用
  15. 量化交易和搜索引擎
  16. UMP主裁交易決策
  17. UMP邊裁交易決策
  18. 自定義裁判決策交易
  19. 數據源
  20. A股全市場回測
  21. A股UMP決策
  22. 美股全市場回測
  23. 美股UMP決策

abu量化系統文檔教程持續更新中,請關註公眾號中的更新提醒。

更多阿布量化量化技術文章

更多關於量化交易相關請閱讀《量化交易之路》

更多關於量化交易與機器學習相關請閱讀《機器學習之路》

更多關於abu量化系統請關註微信公眾號: abu_quant


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 很多C 的初學者都會有這麼一個疑問, .Net程式代碼是如何被機器載入執行的? 最簡單的解答是, C 會通過編譯器(CodeDom, Roslyn)編譯成IL代碼, 然後CLR(.Net Framework, .Net Core, Mono)會把這些IL代碼編譯成目標機器的機器代碼並執行. 相信大多 ...
  • 30分鐘?不需要,輕鬆讀懂IL http://www.cnblogs.com/brookshi/p/5225801.html IL指令詳細 http://www.cnblogs.com/zery/p/3368460.html 進階篇:以IL為劍,直指async/await http://www.cn ...
  • 前言:去年剛工作的時候,也是剛剛正式接觸.net,當時瞭解了EF以及三種開發模式,Database First、Model First 、Code First。公司用的開發模式是Database First,由於公司有一套成熟的框架,我只需要按部就班的開發即可,因此就沒有詳細學習過這些開發模式,總覺 ...
  • C#多線程 一、使用線程的理由 1、可以使用線程將代碼同其他代碼隔離,提高應用程式的可靠性。 2、可以使用線程來簡化編碼。 3、可以使用線程來實現併發執行。 二、基本知識 1、進程與線程:進程作為操作系統執行程式的基本單位,擁有應用程式的資源,進程包含線程,進程的資源被線程共用,線程不擁有資源。 2 ...
  • 自己上網查了好多種方法,最後還是選了這種不收費,還挺好用的方法 為了用戶有一個好的體驗我將word、excel、ppt轉Pdf,Pdf轉Swf寫在服務上,因為我當時做的時候Pdf轉Swf會執行pdf2swf.exe彈出黑框,對用戶體驗不好,還有就是ppt轉swf時會有一個彈出框,提示正在發佈,我沒搞 ...
  • 1. JMS基本概念 JMS(Java Message Service) 即Java消息服務。它提供標準的產生、發送、接收消息的介面簡化企業應用的開發。 它支持兩種消息通信模型:點到點(point-to-point)(P2P)模型和發佈/訂閱(Pub/Sub)模型。 P2P 模型規定了一個消息只能有 ...
  • 之前沒課的時候寫過安居客的爬蟲,但那也是小打小鬧,那這次呢, 還是小打小鬧 哈哈,現在開始正式進行爬蟲書寫 首先,需要分析一下要爬取的網站的結構: 作為一名河南的學生,那就看看鄭州的二手房信息吧! 在上面這個頁面中,我們可以看到一條條的房源信息,從中我們發現了什麼,發現了連鄭州的二手房都是這麼的貴, ...
  • 在web.xml中配置載入spring時,發現項目無法運行;而去掉spring的配置時,項目可以被初始化。 此時應考慮到spring的配置文件中存在錯誤,以至於web容器無法對項目成功初始化,在web.xml中配置log4j, 根據列印的信息對spring的配置進行修改。 <context-para ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...