You are welcome to subscribe to Python In Action: Building a Stock-based Quantitative Trading System. We will publish columns that will expand on the topics covered in the booklet and include selected topics in the booklet for easy access. This column is a supplement to the brochure content!!

preface

In the section of “Stock Trading Strategy: Timing Strategy into ATR Risk Management”, we introduce a risk management factor — ATR index on the basis of n-day breakout timing strategy of Turtle trading law.

ATR index is mainly used to measure the intensity of market volatility, that is, to show the rate of market change. When the market volatility is severe, THE VALUE of ATR will increase; when the market tends to be stable or the volatility is small, the VALUE of ATR will decrease. Therefore, in fund management, the calculation of dynamic positions based on ATR values can be associated with the volatility of the current market.

In fact, in the turtle trading rules, ATR index is the core of capital management, and the judgment of risk management strategy is also the protection of capital to some extent.

In this section, we introduce the principle and implementation method of dynamic position management based on ATR index from multiple perspectives.

Principles of ATR fund management

Real money management is the strategy of deciding how to buy a stock in batches and how to stop loss/win and get out. The fund management module consists of the following four parts:

  • Capital allocation
  • Position size
  • Stop profit and loss level
  • Add or subtract the size of the position

Whether it is fund allocation, position size, stop-profit and stop-loss level or size of add or subtract positions, ATR indicators are used as a reference value. Next, we take reasonable allocation of funds as an example to introduce the principle of ATR in capital management.

It is common for traders to hold more than one stock at a time, so how do you divide your money among multiple stocks?

For example, if you have 100,000 yuan in hand and want to buy both stock A and stock B, how do you allocate the money? The simplest, and most people choose the method is equal division, that is, both buy 50 thousand yuan each. This method is simple, but it ignores the fact that different stocks are not the same, which means that some are very volatile and some are very volatile.

If the two classes of stocks were bought with the same amount of money, the active stocks would produce more losses and gains than the less active ones. If the relatively inactive stock rises less and the sexually active stock falls more, the total fund will still lose money.

This problem can therefore be solved by using ATR to allocate funds, i.e. a fixed percentage of all funds corresponds to a fluctuation of one ATR for a particular stock. The closing price of stock A on January 1 was 4.12 yuan, and the ATR on January 14 was 0.15 yuan, equivalent to 3.64% of the closing price. The closing price of stock B on January 1 was 30.85 yuan, and the ATR on January 14 was 2.74 yuan, equivalent to 8.88% of the closing price. Obviously the latter is more active than the former.

Assuming that we have 100,000 yuan capital in hand, we can set that the fluctuation of one ATR of the above two stocks is equivalent to 1% of the total capital fluctuation, so 1% of 100,000 yuan is 1000 yuan.

Stock A: 1000÷0.15=6666, that is, we should buy 6666 shares, according to the day 4.12 yuan closing price calculation, involving capital 27,400 yuan; At the same time, 1000÷2.74=364, that is, we should buy 364 shares B, according to the closing price of 30.85 yuan on that day, involving capital of 11,250 yuan.

By allocating money differently, we can make the normal fluctuations of the two stocks have roughly equal impact on the portfolio, without being overly influenced by stock B.

ATR position management implementation

The principle of position management is much the same as capital allocation. Turtle Trading rules suggest that one ATR move in the first position corresponds to a 1% move in the total fund. That is: number of shares purchased * ATR = capital * 1%

If stock A breaks through 4.12 yuan to appear to buy A point upward on January 1, there is 100 thousand yuan capital on the hand, so the 1% fluctuation of 100 thousand capital is 1000 yuan. As of January 1, the 14-day ATR of stock A was 0.15 yuan, 1000 yuan ÷0.15 yuan =6666 shares. In other words, the size of the position should be to buy 6,666 shares, costing 27,400 yuan.

First, create the account class ST_Account, which provides interfaces such as the remaining fund, number of shares held, total assets and trading operations of the current account, as shown below:

class ST_Account:

    def __init__(
            self,
            init_hold={},
            init_cash=1000000,
            commission_coeff=0,
            tax_coeff= 0):
        """:param [dict] init_hold Stock assets for initialization :param [float] init_cash: Funds for initialization :param [float] commission_coeff: Param [float] tax_COeff: Stamp Duty: Default thousand 1.5(float 0.001) Here routine is set to 0"""
        self.hold = init_hold
        self.cash = init_cash

    def hold_available(self, code=None):
        """Available positions"""
        if code in self.hold:
            return self.hold[code]

    def cash_available(self):
        """Available funds"""
        return self.cash

    def latest_assets(self, price):
        # return the lastest hold total assets
        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]  # Delete the stock


Copy the code

In order to focus on the introduction of fund management, some details in the account are simplified here. Commission and stamp duty are not considered for the time being. We set up two accounts respectively, take the n-day channel breakout strategy in the Turtle trading rule as an example, and compare the capital returns of full-position buying and ATR position size buying.

self.account_a = ST_Account(dict(), 100000) Number of shares and initial capital of Account A

self.account_b = ST_Account(dict(), 100000) # Number of shares and initial capital of Account B


Copy the code

Buy some code changes as shown below:

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')

Copy the code

Sell some code changes as shown below:

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')

Copy the code

The return test effect is shown in the figure below. It can be seen from the yield curve that the fluctuation range of the curve slows down after the addition of position management:

The complete code can be found in the booklet “Add Tweets! Timing into ATR Dynamic Positioning management”.

ATR dynamic position adjustment

When we bought 6,666 shares with a strategy where the ATR move corresponded to the 1% move in total funds. If buy after the stock long-term consolidation, neither rise nor fall, right now ATR will further fall, such as by 0.15 yuan dropped to 0.12 yuan, investors can recalculate positions. Based on the volatility of 1% capital =1ATR, investors can hold 8333 shares. If they have bought 6666 shares before, investors can add 1667 shares.

The implementation code is as follows:

if((posit_num_wave - self.account_b.hold_available(code = "600410.SS")) >= self.adjust_hold): # Add positions after volatility

    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')
Copy the code

The complete code can be found in the booklet “Add Tweets! Timing into ATR Dynamic Positioning management”.

conclusion

In this section, we introduce the principle and implementation method of dynamic fund management based on ATR index from the perspective of position management and dynamic addition and reduction of positions. Students can combine position management, dynamic increase and decrease, win and stop loss systematically into a complete fund management module based on the stop-loss mechanism of “Stock Trading Strategy: Timing Strategy into ATR Risk Management”.

Subscribe for more quantitative trading contentSmall volumesRead!!!!! You are also welcome to follow my wechat official account to learn more about Python quantitative trading