SuperTrend Indicator

I recently completed a client project that utilizes the SuperTrend indicator. The indicator is basically a variation on other types of volatility bands, using a multiple of ATR to define the define the band above and below the current average price. The SuperTrend line is the lower band when the price is in an up trend (has most recently broken the upper band), and is the upper band when the price is in a down trend (has most recently broken the lower band).

I have not used the indicator enough to have a strong opinion on its usefulness, although it seems to be particularly popular with traders from India. However, I had a hard time finding written definitions of the indicator, and the one that I did find was incorrect. I finally resorted to creating a definition by reverse engineering some code written by Rajandran R at www.marketcalls.in. I then wrote my own version in AmiBroker AFL in a way that makes it easy to use on a chart or in an exploration. In addition, the SuperTrend function could be easily copied to another AFL used for back testing or other AmiBroker analysis.

Here is the definition of the SuperTrend indicator that I derived from Rajandran’s code:

SuperTrend requires two parameters:

  1. lenATR: The number of periods used to calculate ATR
  2. width: The factor by which to multiply the ATR value when determining upper and lower bands

We begin by calculating preliminary values for the upper and lower bands as follows:

UpperBand = (High + Low) / 2 + (width * ATR(lenATR))
LowerBand = (High + Low) / 2 - (width * ATR(lenATR))

Next we examine the bands and the Close of each bar in the series to determine the trend:

If Current Close > Previous UpperBand Then Trend is UP
Else If Current Close < Previous LowerBand Then Trend is DOWN
Else Trend is unchanged from previous bar

The direction of the trend allows us to modify the preliminary band values, and also determine whether the SuperTrend line is currently following the upper or lower band:

If UP trend Then 
    Current LowerBand = max(Current LowerBand , Previous LowerBand )
    Current Supertrend = Current LowerBand
If DOWN trend Then 
    Current UpperBand = min(Current UpperBand , Previous UpperBand )
    Current Supertrend = Current UpperBand

Here is the AmiBroker AFL for the SuperTrend indicator:

/////////////////////////////////////////////////////////////////////////////
// Supertrend Indicator
//
// AmiBroker implementation by Matt Radtke, www.quantforhire.com
//
// History
// v1: Initial Implementation
/////////////////////////////////////////////////////////////////////////////

function SuperTrend(lenATR, width)
{
    nATR = ATR(lenATR);
    pAvg = (H+L) / 2;

    upperBand = pAvg + width * nATR;
    lowerBand = pAvg - width * nATR;
    isUpTrend = True;
    dn = DateNum();

    for (i=lenATR; i<BarCount; ++i)
    {
        if (C[i] > upperBand[i-1])
            isUpTrend[i] = True;
        else if (C[i] < lowerBand[i-1])
            isUpTrend[i] = False;
        else
            isUpTrend[i] = isUpTrend[i-1];

        if (isUpTrend[i])
            lowerBand[i] = Max(lowerBand[i], lowerBand[i-1]);
        else
            upperBand[i] = Min(upperBand[i], upperBand[i-1]);
    }

    super = IIf(isUpTrend, lowerBand, upperBand); 
    return super;
}

lengthATR = Param("ATR Length", 10, 1, 100, 1);
widthBands = Param("Band Width", 3, 1, 20, 0.1);
st = Supertrend(lengthATR,widthBands);

Plot(st, "Supertrend("+lengthATR+","+widthBands+")", ParamColor( "Color", colorCycle ), ParamStyle("Style") );

Filter = True;
AddColumn(O,"Open");
AddColumn(H,"High");
AddColumn(L,"Low");
AddColumn(C,"Close");
AddColumn((H+L)/2,"Avg");
AddColumn(ATR(lengthATR), "ATR("+lengthATR+")");
AddColumn(st, "Supertrend("+lengthATR+","+widthBands+")");

Recent Projects

In addition to my thriving consulting business, other activities have been keeping me quite busy lately. I’ve been working with my friend and colleague, Cesar Alvarez, to roll out a new trading strategy named Snap Dragon. You can read more about it here: https://www.tranquilitytrading.com/snap-dragon-main/

Cesar is offering a 10% discount to anyone who signs up before the end of July 2018.

I also helped with the research for Larry Connors’ new book, Buy The Fear, Sell The Greed – 7 Behavioral Quant Strategies For Traders.  Larry is providing a free preview of the first chapter if you’re interested in taking a look.

 

Cesar’s First Rule

Much of what I know about the practical aspects of backtesting I learned from two of my colleagues at Connors Research, Cesar Alvarez and David Weilmunster. One particularly important lesson was Cesar’s observation that “if the results seem too good to be true, they probably are”. This situation comes up often enough that I now think of it as “Cesar’s First Rule”.

Not long ago, a client asked me to verify some very strong backtesting results produced by another researcher. I began by looking through the other developer’s AmiBroker AFL code, but didn’t immediately find any errors. However, as any of you who’ve done a significant amount of coding are aware, it can be challenging to dive into someone else’s work and fully grasp all the nuances.

Next I started to rewrite the strategy using my own coding templates, and sure enough, my results were not nearly as good as those from the other developer. It turned out that he was always exiting at the profit target price, even when the price had declined and the trade should have resulted in a stop loss! Since AmiBroker’s default behavior is to restrict the price based on the high and low of the exit bar, some trades still came through as losers  but with a smaller loss than they should have. This had the effect of masking the problem, because almost anyone would have recognized that 100% winners must be an error.

Sometimes even my own results are too good to be true. Recently I was working on a presentation about building adaptive strategies: quantified trading systems that use different rule parameters depending on the current market condition. I was quite pleased when the adaptive version of the strategy outperformed every variation of the static-parameter version over the same time period (2013-2016). But then, Cesar’s first rule started nagging at me. I checked all my code, and all the adaptive parameters, but everything looked OK. Finally I realized that I had selected the adaptive parameters using results from the current time period (2013-2016), which is basically “cheating” by looking into the future. When I selected the parameters based on past results (2000-2012) as I should have done, my adaptive strategy did not perform nearly as well.

Everyone wants to find their own silver bullet of trading. We all hope that we have the ability to make a brilliant discovery. The cold, hard truth is that in most cases if the results seem too good to be true, then there’s a mistake lurking somewhere. Thanks for the lesson, Cesar!

Strategy Tuning with Market Types

In a previous post we examined how back test results could be summarized for different market types. In today’s post, we’ll look at how we can use that information to tune our strategy for live trading.

As the basis for this exercise, we will use a modified version of the short mean reversion strategy known to Trading Markets customers as Bear Over-Reaction. While I cannot divulge all the specifics of this proprietary system, the basic rules are as follows:

A Setup occurs when:

  1. Stock is a current member of the Russell 1000
  2. Closing price is greater than $10
  3. 21-day average volume is greater than 2.5M
  4. The stock has closed higher for [3,4,5] days in a row
  5. Today’s close is greater that [50,75] % of the range between today’s low and high

Short the stock on the day following Setup using  a limit order  [2,4,6,8] % above the Setup close. Up to 5 open positions are allowed, with 20% of available equity allocated to each position.

When any of the following conditions occur on the close, Cover the position at the next open:

  1. Two-period RSI is less than 30
  2. An EOD Stop Loss [10,25] % above the entry price
  3. An EOD Profit Target [5,10,15] % below the entry price
  4. A Time Stop when the trade has been open for 15 trading days

The values shown inside square brackets are the parameters that we will test during our AmiBroker optimization. Note that 3 x 2 x 4 x 2 x 3 gives us 144 unique parameter combinations or strategy variations.

To begin, we will test each of the 144 variations from 1/1/2000 through 12/31/2010. Summary results for the 10 variations with the highest Compound Annual Return (CAR) are shown in the table below.

Results-All-2000
Table 1: 2000-2010

While the return numbers are not bad, the Max Drawdown (MDD) values are pretty scary. Not too many traders have the stomach to lose 60-70% of their trading capital. Even so, this gives us a place to start.

Now let’s jump ahead and see how these top performers did over the next 5+years, from January 1, 2001 through January 31, 2016:

Results-All-2011
Table 2: 2011 – Jan. 2016, Results for Top 10 from 2000-2010

Uh oh! Here we see proof of the ever-popular warning “past performance is not a guarantee of future results”. Of the Top 10 variations for our initial 11-year test period, only one of those variations was still in the top ten over the next 5 years (variation 179). The new Top 10, shown below, uses different combinations of the parameter values:

Results-All-20110-Top10
Table 3: 2011- Jan 2016, Top 10

The worst part is that we had no way to predict which variations would be the most successful following our initial testing. The best CAR was produced by the variation that ranked 19th over the previous test period! This is where looking at different market conditions or types can help.

Going back to our results from 2000-2011, we will now add columns for each of six market types: Bear, Neutral, or Bull for market price action, and Quiet or Volatile for market volatility. For each market type, we have summarized the total dollars of Profit/Loss for trades whose Setup occurred when that market type was in effect.

Results-MktType-2000
Table 4: 2000-2010, Top 10 with Market Types

Notice that variation 275, which produced the highest overall CAR, also produced a decent amount of profit in Bear markets as well as Quiet Bull markets. However, it was more or less break even in Volatile Neutral markets, and lost lots of money in Quiet Neutral and Volatile Bull markets.

Instead of selecting one set of input parameters (i.e. one variation) to trade in all markets, what if we tried to use the best parameters for each market type. You could define “best” any number of ways, but for now we’ll stick with the very simple metric of total dollars of profit. If we re-sort our results to show the variations with the highest total P/L for V. Bear markets, we get:

Results-2000-VBear
Table 5: 2000-2010, Highest V. Bear P/L

In our strategy optimized for market type, on any day classified as Volatile Bear we would use an Up Close Streak of 3 days and a Closing Range of 75% for the Setup. We would then enter the trade on a 2% limit order, and use a stop loss of 25% and a profit target of 10%.

Repeating the process for the Quiet Bear market type, we see:

Results-2000-QBear
Table 6: 2000-2010, Highest Q. Bear P/L

Therefore, on Quiet Bear days our Setup would also require an Up Close Streak of 3 days and a Closing Range of 75%, just like the Volatile Bear Setup. However, the limit entry would be 4% above the Setup close, and the stop loss would be at 25% and the profit target at 15%.

Repeating yet again for the Quiet Neutral market type, our results show:

Results-2000-QNeutral
Table 7: 2000-2010, Highest Q. Neutral P/L

Now we can see that there are actually variations that have done well in this market type. On Quiet Neutral days, our Setup would be defined by a 4-day Up Close streak and a 75% Closing range. We would enter on a 6% limit order, with stops and targets of 25% and 5% respectively.

We continue this process for the remaining market types, and then combine the strategy parameters for each market type into one optimized strategy. Keep in mind that all of our strategy parameters were selected based on the back test results from 2000-2010.

So how does our optimized strategy perform from 2011 through January 2016?

Results-Optimized
Table 8: 2011-Jan. 2016, Optimized Strategy

The Neutral market types still lost money. However, compare these results to Table 2, which showed how the former Top 10 from 2000-2010 performed from 2011 through January 2016. The optimized results shown in Table 8 had a higher CAR than any shown in Table 2, and had lower MDD than all but one of those variations. Best of all, we actually had a systematic way of selecting our strategy parameters.

In this example, we used a very simple method for defining the “best” results for each market type: the largest profit. We did not take into account drawdowns or any other factors that might be important to you when you trade. With additional thought and testing, it’s likely that we could improve on how to select the best variations for each market type. In addition, we would probably repeat the baselining process on a periodic basis rather than doing it just once and then using those “optimized” parameters for the next five years. Hopefully this article has given you some ideas on how to tune your own strategies for market conditions. As always, you can  contact me if you need assistance.

 

Reporting By Market Type

One of the many interesting ideas put forth by Dr. Van K. Tharp is that you should not try to find a trading strategy that works in every type of market. Instead, he advises trading only those strategies that have performed well in the past under conditions similar to the current ones.

If you choose to adopt this approach to trading system development and selection, then the first step is to define a set of market types or conditions. One way to do this is to combine price action (bullish, neutral, bearish) with volatility (quiet, normal, volatile). For example, in today’s article I will use a six-month lookback on the S&P 500 index (SPX) to determine whether the market is bullish, neutral or bearish, and the CBOE Volatility Index (VIX) to determine whether the market is quiet or volatile (we won’t use “normal” as a volatility type here). The factors you choose to incorporate into your own market type definition will depend on your beliefs about the market and how you think those factors impact your trading results. Similarly, the timeframe over which you calculate your market type will be influenced by the type of trading you do. A day trader will likely have a very different way of defining the market type than a swing trader or momentum trader.

To illustrate the concept of reporting by market type, let’s consider a very simple mean reversion system based on the 2-period RSI, or RSI(2). The entry rules for long trades are:

  1. Stock is a member of the S&P 500 Index
  2. Market Value (Closing Price x Volume) > $5M
  3. RSI(2) < [5,10,15,20]

And the exit condition is:

  1. RSI(2) > [60,70,80]

Both entry and exit will take place at the close of the day on which the signal occurs, and the back tests will cover the 10-year period from 1/1/2006 through 12/31/2015.

The table below shows a few key metrics for each of the 12 strategy variations: 4 RSI(2) entry values combined with 3 RSI(2) exit values. This was an “all trades” test, meaning that we took every available entry signal without regard to portfolio considerations like position sizing or capital constraints. The only restriction was that only one open trade per symbol was allowed at any given time.

LongSummary

We can see that the percentage of profitable trades (% of Winners) was very close to 69% for every variation. Therefore, let’s focus on the average gain per trade. The table entries are sorted from highest to lowest Avg % P/L, with the best performing variation (No. 21) producing a 0.83% gain by entering trades on an RSI(2) value below 5 and exiting when RSI(2) moves above 80. As we move across the top row from left to right, we see that variation 21 did not perform equally in all market types. In Bear and Neutral markets, the gain per trade was usually around 1.0%, but in Bull markets the gain fell to 0.44% when the market was Volatile and 0.79% when the Bull market was Quiet. So, if variation 21 was the only one we were trading, we might choose not to trade in Bull market types.

Now let’s focus on the column for each market type. In each of these six columns, the highest Avg % P/L is highlighted green. For the Volatile Bear market type, the highest Avg % P/L was produced by the same variation (21) that generated the best overall Avg % P/L. However, for the Quiet Bear market type, variation 24 produced a superior gain per trade of 1.62%. Although this is a simplified example which focuses on only one metric, it’s clear that we can extend this concept to help us to determine when to trade our base strategy, when to tweak our rule parameters, and when to consider sitting out altogether.

If we reverse the long rules to create a short system, we observe even more differentiation between the market types. On an overall basis, none of these variations comes out much above break even, despite the fact that the test did not account for commissions. However, the two Bear market types each identified some interesting variations of the strategy, while both Neutral market types and the Quiet Bull type would clearly not be worth trading as the strategy is currently written.

ShortSummary

Please feel free to contact me if you’d like a copy of the Excel spreadsheet or if you need assistance adding this type of reporting to your AmiBroker back tests and optimizations.