Python量化交易進階講堂-擇時策略融入ATR動態倉位管理

歡迎你們訂閱《Python實戰-構建基於股票的量化交易系統》小冊子,小冊子會陸續推出與小冊內容相關的專欄文章,對涉及到的知識點進行更全面的擴展介紹。本篇專欄爲小冊子內容的加推篇!!!bash

前言

在《股票交易策略:擇時策略融入ATR風險管理》節中咱們在海龜交易法則的N日突破擇時策略基礎上引入風險管理因子——ATR指標。微信

ATR指標主要是用來衡量市場波動的強烈度,即爲了顯示市場變化率的指標,當市場波動劇烈那麼ATR的值就會變大,當市場趨於平穩或波動較小那麼ATR值就會變小。所以在資金管理中,根據ATR值實現動態倉位的計算,能夠與當前市場的波動率相關聯。ui

實際上,在海龜交易法則中,ATR指標是資金管理的核心,風險管理策略的判斷某種程度上也是對於資金的保護。spa

本節咱們多個角度來介紹下基於ATR指標的動態倉位管理的原理和實現方法。code

ATR資金管理的原理

真正的資金管理是在買入某個股票時,決定如何分批入場,又如何止損/止贏離場的策略。資金管理模塊由如下四部分組成:cdn

  • 資金分配
  • 頭寸規模
  • 止盈止損價位
  • 加減倉規模

不管是資金分配、頭寸規模、止盈止損價位仍是加減倉規模,都是將ATR指標做爲基準值。 接下來咱們以合理分配資金爲例,介紹下ATR在資金管理中的原理。blog

一般交易者都會同時持有多隻股票,那麼如何在多個股票之間分配資金呢?接口

比方手頭有10萬元資金,準備同時買股票A和股票B,如何分配資金呢?最簡單的,也是大多數人選擇的方法是均分法,也就是二者各買5萬元。這種方法雖然簡單,但卻忽略了一個問題,也就是不一樣的股票股性並不相同,也就是說有的波動很大,有的波動很小。get

若是這兩類股票用一樣的資金購買,那麼股性活躍的股票帶來的虧損和盈利都會超過股性相對不活躍的。假若股性相對不活躍的股票漲得少,股性活躍的股票跌的多,那麼總資金依舊會虧損。string

所以能夠利用ATR來分配資金解決這個問題,即讓全部資金的固定百分比與某個股票1個ATR的波動對應。 1月1日股票A的收盤價爲4.12元, 14日ATR爲0.15元,至關於收盤價的3.64%;1月1日股票B的收盤價爲30.85元,14日ATR爲2.74元,至關於收盤價的8.88%;顯而後者股性比前者更活躍。

假設手頭有10萬元資金,咱們就能夠設定讓上述兩個股票1個ATR的波動等價於總資金1%的波動,那麼10萬元的1%爲1000元。

股票A:1000÷0.15=6666,即咱們應當買入6666股,按照當日4.12元收盤價計算,涉及資金2. 74萬元; 與此同時,1000÷2.74=364,即咱們應當買入364股股票B,按照當日30.85元收盤價計算,涉及資金1. 125萬元。

經過資金分配的不一樣,咱們大致可使這兩個股票的正常波動對投資組合的影響大體相等,不會過度受到股票B的影響。

ATR頭寸管理的實現

關於頭寸管理的原理與資金分配大致相同。《海龜交易法則》建議第一筆倉位的一個ATR波動與總資金1%波動相對應。即:買入股票數量 * ATR = 資金 * 1%

假如1月1日股票A向上突破4.12元出現買入點,手上有10萬元資金,那麼10萬資金的1%波動就是1000元。截止1月1日,股票A的14日ATR爲0.15元,1000元÷0.15元=6666股。也就是說,頭寸規模應該是買入6666股,耗資2. 74萬元。

首先建立帳戶類ST_Account,該類中提供了當前帳戶的剩餘資金、持倉股數、總資產、交易操做等接口,以下所示:

class ST_Account:

    def __init__(
            self,
            init_hold={},
            init_cash=1000000,
            commission_coeff=0,
            tax_coeff= 0):
        """ :param [dict] init_hold 初始化時的股票資產 :param [float] init_cash: 初始化資金 :param [float] commission_coeff: 交易佣金 :默認 萬2.5(float類型 0.00025) 此處例程設定爲0 :param [float] tax_coeff: 印花稅 :默認 千1.5(float類型 0.001) 此處例程設定爲0 """
        self.hold = init_hold
        self.cash = init_cash

    def hold_available(self, code=None):
        """可用持倉"""
        if code in self.hold:
            return self.hold[code]

    def cash_available(self):
        """可用資金"""
        return self.cash

    def latest_assets(self, price):
        # return the lastest hold 總資產
        assets_val = 0
        for code_hold in self.hold.values():
            assets_val += code_hold * price
        assets_val += self.cash
        return assets_val

    def send_order(self, code=None, amount=None, price=None, order_type=None):
        if order_type == 'buy':
            self.cash = self.cash - amount * price
            self.hold[code] = amount
        else:
            self.cash = self.cash + amount * price
            self.hold[code] -= amount
            if self.hold[code] == 0:
                del self.hold[code]  # 刪除該股票


複製代碼

此處爲了側重介紹資金管理,簡化了帳戶中的一些細節,暫時不考慮佣金和印花稅。 咱們分別設立兩個帳戶,以海龜交易法則中N日通道突破策略爲例,對比下全倉買入和ATR頭寸規模買入的資金收益。

self.account_a = ST_Account(dict(), 100000) # 帳戶A 持股數目和初始資金

self.account_b = ST_Account(dict(), 100000) # 帳戶B 持股數目和初始資金


複製代碼

買入部分代碼更改以下所示:

self.account_a.send_order(code = "600410.SS",
                          amount = int(self.account_a.cash_available() / today.Close),
                          price = today.Close, order_type='buy')
self.account_b.send_order(code = "600410.SS",
                          amount = int(self.account_b.cash_available() * 0.01 / today.atr14),
                          price = today.Close, order_type='buy')

複製代碼

賣出部分代碼更改以下所示:

self.account_a.send_order(code = "600410.SS",
                          amount= self.account_a.hold_available(code = "600410.SS"),
                          price = today.Close, order_type='sell')
self.account_b.send_order(code="600410.SS",
                          amount = self.account_b.hold_available(code = "600410.SS"),
                          price = today.Close, order_type='sell')

複製代碼

對比回測效果以下圖所示,從收益曲線能夠看出增長頭寸管理以後曲線波動幅度趨緩:

完整代碼可參考小冊子《加推篇!擇時策略融入ATR動態倉位管理》。

ATR動態倉位調整

當咱們以一個ATR波動與總資金1%波動相對應的策略買入了6666股。假如買完以後股票長期盤整,既無大漲也無大跌,此時ATR會進一步下跌,好比由0.15元降低至0.12元時,投資者即可從新計算倉位。依舊按照1%資金=1ATR波動計算,則可持有8333股,此前已經買入6666股,則投資者還可加倉1667股。

實現代碼以下所示:

if((posit_num_wave - self.account_b.hold_available(code = "600410.SS")) >= self.adjust_hold): # 波動後加倉

    print("adjust buy", kl_index)
    self.account_b.send_order(code="600410.SS",
                              amount=int(posit_num_wave - self.account_b.hold_available(code = "600410.SS")),
                              price=today.Close, order_type='buy')
elif (self.account_b.hold_available(code = "600410.SS") - posit_num_wave) > self.adjust_hold:
    print("adjust sell", kl_index)
    self.account_b.send_order(code="600410.SS",
                              amount=int(self.account_b.hold_available(code="600410.SS")- posit_num_wave),
               
              price=today.Close, order_type='sell')
複製代碼

完整代碼可參考小冊子《加推篇!擇時策略融入ATR動態倉位管理》。

總結

本小節咱們從頭寸管理和動態加減倉這兩個角度介紹了基於ATR指標的動態資金管理的原理和實現方法。同窗們能夠再結合《股票交易策略:擇時策略融入ATR風險管理》中關於ATR止贏止損的機制,將頭寸管理、動態加減倉、止贏止損系統地結合爲一個完整的資金管理模塊。

更多的量化交易內容歡迎你們訂閱小冊閱讀!!同時也歡迎你們關注個人微信公衆號【元宵大師帶你用Python量化交易】瞭解更多Python量化交易相關內容

相關文章
相關標籤/搜索