Simple Moving Average Strategy with a Volatility Filter: Follow-Up Part 1

Analyzing transactions in quantstrat

This post will be part 1 of a follow up to the original post, Simple Moving Average Strategy with a Volatility Filter. In this follow up, I will take a closer look at the individual trades of each strategy. This may provide valuable information to explain the difference in performance of the SMA Strategy with a volatility filter and without a volatility filter.

Thankfully, the creators of the quantstrat package have made it very easy to view the transactions with a simple function and a single line of code.

getTxns(Portfolio, Symbol, Dates)

For the rest of the post, I will refer to the strategies as:

  • Strategy 1 =  Simple Moving Average Strategy with a Volatility Filter
  • Strategy 2 = Simple Moving Average Strategy without a Volatility Filter

It is evident from the equity curves in the last post that neither strategy did much from the year 2000 to 2012. For that reason, I will analyze the period from 1990 to 2000

Strategy 1 Transactions

                    Txn.Qty Txn.Price Txn.Fees  Txn.Value Txn.Avg.Cost Net.Txn.Realized.PL
1900-01-01 00:00:00       0      0.00        0       0.00         0.00                0.00
1992-10-23 00:00:00     410    414.10        0  169781.00       414.10                0.00
1994-04-08 00:00:00    -410    447.10        0 -183311.00       447.10            13530.00
1994-06-10 00:00:00     531    458.67        0  243553.77       458.67                0.00
1994-06-17 00:00:00    -531    458.45        0 -243436.95       458.45             -116.82
1995-05-19 00:00:00     247    519.19        0  128239.93       519.19                0.00
1998-09-04 00:00:00    -247    973.89        0 -240550.83       973.89           112310.90
1999-09-10 00:00:00      45   1351.66        0   60824.70      1351.66                0.00
1999-10-22 00:00:00     -45   1301.65        0  -58574.25      1301.65            -2250.45
1999-11-26 00:00:00      82   1416.62        0  116162.84      1416.62                0.00

Strategy 2 Transactions

                    Txn.Qty Txn.Price Txn.Fees  Txn.Value Txn.Avg.Cost Net.Txn.Realized.PL
1900-01-01 00:00:00       0      0.00        0       0.00         0.00                0.00
1992-10-23 00:00:00     410    414.10        0  169781.00       414.10                0.00
1994-04-08 00:00:00    -410    447.10        0 -183311.00       447.10            13530.00
1994-06-10 00:00:00     531    458.67        0  243553.77       458.67                0.00
1994-06-17 00:00:00    -531    458.45        0 -243436.95       458.45             -116.82
1994-08-19 00:00:00     593    463.68        0  274962.24       463.68                0.00
1994-09-30 00:00:00    -593    462.71        0 -274387.03       462.71             -575.21
1994-10-07 00:00:00     562    455.10        0  255766.20       455.10                0.00
1994-10-14 00:00:00    -562    469.10        0 -263634.20       469.10             7868.00
1994-10-21 00:00:00     560    464.89        0  260338.40       464.89                0.00
1994-12-02 00:00:00    -560    453.30        0 -253848.00       453.30            -6490.40
1995-01-13 00:00:00     548    465.97        0  255351.56       465.97                0.00
1998-09-04 00:00:00    -548    973.89        0 -533691.72       973.89           278340.16
1998-10-02 00:00:00      66   1002.60        0   66171.60      1002.60                0.00
1998-10-09 00:00:00     -66    984.39        0  -64969.74       984.39            -1201.86
1998-10-23 00:00:00      68   1070.67        0   72805.56      1070.67                0.00
1999-10-22 00:00:00     -68   1301.65        0  -88512.20      1301.65            15706.64
1999-10-29 00:00:00      70   1362.93        0   95405.10      1362.93                0.00

For ease of comparison, I exported the transactions for each strategy to excel and aligned the trades as close I could by date.

First, lets look at the trades highlighted by the red rectangle. Strategy 2 executed a trade for 548 units on 1/13/1995 and closed on 9/4/1998 for a total profit of $278340.16. By comparison, Strategy 1 executed a trade  for 247 units on 5/19/1995 (about 4 months later) and closed on 9/4/1998 for a total profit of $112,310.90. This is a significant difference of $166,029. It is clear that this single trade is critical to the performance of the strategy.

Now, lets look at the trade highlighted by the yellow rectangle. Both trades were closed on 10/22/1999. Strategy 1 resulted in a loss of $2,250.45 and Strategy 2 resulted in a gain of $15,706.64… a difference of $17,957.09.

The equity curve of Strategy 1 compared with Strategy 2 shows a clearer picture of the outperformance.

rbresearch

Why such a big difference?

For an even closer look, we will need to take a look at the measure of volatility we use as a filter. I will make a few modifications to the RB function so we can see the volatility measure and median.

#Function that calculates the n period standard deviation of close prices.
#This is used in place of ATR so that I can use only close prices.
SDEV <- function(x, n){
  sdev <- runSD(x, n, sample = FALSE)
  colnames(sdev) <- "SDEV"
  reclass(sdev,x)
}

#Custom indicator function 
RB <- function(x,n){
  x <- x
  roc <- ROC(x, n=1, type="discrete")
  sd <- runSD(roc,n, sample= FALSE)
  #sd[is.na(sd)] <- 0
  med <- runMedian(sd,n)
  #med[is.na(med)] <- 0
  mavg <- SMA(x,n)
  signal <- ifelse(sd < med & x > mavg,1,0)
  colnames(signal) <- "RB"
  ret <- cbind(x,roc,sd,med,mavg,signal)
  colnames(ret) <- c("close","roc","sd","med","mavg","RB")
  reclass(ret,x)
  }

data <- cbind(RB(Ad(GSPC),n=52),SDEV(Ad(GSPC),n=52)) #RB is the volatility signal indicator and SDEV is used for position sizing
Created by Pretty R at inside-R.org
> data['1995']
                     close           roc          sd        med     mavg RB      SDEV
1995-01-13 00:00:00 465.97  0.0114830251 0.013545475 0.01088292 459.7775  0  8.924008
...
1995-05-19 00:00:00 519.19 -0.0121016078 0.012412166 0.01259515 472.6006  1 21.161032


The sd for 1995-01-13 is 0.0135 while the SDEV is 8.924. The sd for 1995-05-19 is 0.0124 while the SDEV is 21.16… the SDEV is almost 3 times larger even though our volatility measure is indicating a period of low volatility! (note: SDEV has a direct impact on position sizing)

Perhaps we should take a second look at our choice of volatility measure.

If you want to incorporate a volatility filter into your system, choose the volatility measure wisely…

3 thoughts on “Simple Moving Average Strategy with a Volatility Filter: Follow-Up Part 1

  1. Thanks for the post, I’m looking forward to more. I’m new to both R programming and trend trading. My trend trading exposure has mostly come from reading Michael Covel’s books. I’m wondering what’s the best way to learn trend trading systems. I haven’t found many details other than the donchian channel breakout system. What’s the best/fastest way to learn the tactical systems of trend trading in your opinion?

    • jnoble,

      I’m glad you liked the post. Welcome to world of trend trading and R programming. Reading books is a good way to get started and gain background knowledge of trading, markets, etc. The best way to learn trading systems is… start developing, backtesting, and paper trading your systems.

      Ross

  2. Pingback: Simple Moving Average Strategy with a Volatility Filter: Follow-Up Part 2 | rbresearch

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s