Category Archives: back testing

A Simple Way To Trade Seasonality


In “A Simple Way To Trade Seasonality” in the September 2019 Stocks & Commodities, author Perry Kaufman describes methods he uses for measuring the seasonality in markets and approaches he uses for trading these patterns

Editors note: The full article can be obtained from Stocks & Commodities magazine at
http://technical.traders.com/sub/sublog2.asp#Sep the system rules are from the article and are based on these rules

1. Average the monthly frequency of the past 4 years.

2. Find the last occurrence of the highest frequency and the last occurrence of the lowest frequency using the average frequency in step 1. That is, if both March and April have a frequency of 70, we use April.

3. Only trade if the high frequency is 75% or greater and the low frequency is 25% or lower.

4. If the high frequency comes first, sell short at the end of the month with the high frequency. Cover the short at the end of the month with the low frequency.

5. If the low frequency comes first, buy at the end of the month with the low frequency. Sell to exit at the end of the month with the high frequency

The importable AIQ EDS file and Excel spreadsheet for Perry Kaufman’s article can be obtained on request via email to info@TradersEdgeSystems.com. The code is also shown below

!A Simple Way to Trade Seasonality
!Author: Perry Kaufman, TASC September 2019
!Coded by: Richard Denning, 07/21/2019
!www.TradersEdgeSystem.com

C is [close].
year is 2019.
len is 4000.
OSD is offsettodate(month(),day(),year()).
FirstDate is firstdatadate().

EOM1 if Month()=2 and valresult(month(),1)=1 and year()=year.
EOMos1 is scanany(EOM1,len) then OSD+1.
EOMc1 is valresult(C,^EOMos1).
EOM2 if Month()=3 and valresult(month(),1)=2 and year()=year.
EOMos2 is scanany(EOM2,len) then OSD+1.
EOMc2 is valresult(C,^EOMos2).
EOM3 if Month()=4 and valresult(month(),1)=3 and year()=year.
EOMos3 is scanany(EOM3,len) then OSD+1.
EOMc3 is valresult(C,^EOMos3).
EOM4 if Month()=5 and valresult(month(),1)=4 and year()=year.
EOMos4 is scanany(EOM4,len) then OSD+1.
EOMc4 is valresult(C,^EOMos4).
EOM5 if Month()=6 and valresult(month(),1)=5 and year()=year.
EOMos5 is scanany(EOM5,len) then OSD+1.
EOMc5 is valresult(C,^EOMos5).
EOM6 if Month()=7 and valresult(month(),1)=6 and year()=year.
EOMos6 is scanany(EOM6,len) then OSD+1.
EOMc6 is valresult(C,^EOMos6).
EOM7 if Month()=8 and valresult(month(),1)=7 and year()=year.
EOMos7 is scanany(EOM7,len) then OSD+1.
EOMc7 is valresult(C,^EOMos7).
EOM8 if Month()=9 and valresult(month(),1)=8 and year()=year.
EOMos8 is scanany(EOM8,len) then OSD+1.
EOMc8 is valresult(C,^EOMos8).
EOM9 if Month()=10 and valresult(month(),1)=9 and year()=year.
EOMos9 is scanany(EOM9,len) then OSD+1.
EOMc9 is valresult(C,^EOMos9).
EOM10 if Month()=11 and valresult(month(),1)=10 and year()=year.
EOMos10 is scanany(EOM10,len) then OSD+1.
EOMc10 is valresult(C,^EOMos10).
EOM11 if Month()=12 and valresult(month(),1)=11 and year()=year.
EOMos11 is scanany(EOM11,len) then OSD+1.
EOMc11 is valresult(C,^EOMos11).
EOM12 if Month()=1 and valresult(month(),1)=12 and valresult(year(),1)=year.
EOMos12 is scanany(EOM12,len) then OSD+1.
EOMc12 is valresult(C,^EOMos12).
YEARavg is (EOMc1+EOMc2+EOMc3+EOMc4+EOMc5+EOMc6+EOMc7+EOMc8+EOMc9+EOMc10+EOMc11+EOMc12)/12.

AR1 is (EOMc1 / YEARavg-1)*100.
AR2 is (EOMc2 / YEARavg-1)*100.
AR3 is (EOMc3 / YEARavg-1)*100.
AR4 is (EOMc4 / YEARavg-1)*100.
AR5 is (EOMc5 / YEARavg-1)*100.
AR6 is (EOMc6 / YEARavg-1)*100.
AR7 is (EOMc7 / YEARavg-1)*100.
AR8 is (EOMc8 / YEARavg-1)*100.
AR9 is (EOMc9 / YEARavg-1)*100.
AR10 is (EOMc10 / YEARavg-1)*100.
AR11 is (EOMc11 / YEARavg-1)*100.
AR12 is (EOMc12 / YEARavg-1)*100.

EOMc if firstdate < makedate(1,20,2019-20).
AR if EOMc.

The EDS code is not a trading system but a way to get the data needed into an Excel spreadsheet to enable you to make the seasonal calculations. The EDS file should be run on a date after the end of the year being calculated. Each year for which data is needed must be run separately by setting the “year” variable. Multiple symbols can be run at the same time by using a list of the desired symbols. Each time a year is run, the “AR” report must be saved as a “.csv” file. Once all the years needed have been run and saved to separate “.csv” files, they all should be cut and pasted to a single Excel sheet. They then can be sorted by symbol and each symbol can be copied and pasted to a tab for that symbol.

Figure 6 shows the rolling four-year frequency for the S&P 500 ETF (SPY) and Figure 7 shows the annual trades resulting from applying the seasonal rules to the frequency data.

Sample Chart

FIGURE 6: AIQ. Shown here is the rolling four-year frequency for the SPY.

Sample Chart

FIGURE 7: AIQ. Shown here are the annual trades resulting from applying the seasonal rules to the frequency data for SPY.

—Richard Denning
info@TradersEdgeSystems.com
for AIQ Systems

Backtesting A Mean-Reversion Strategy In Python

The importable AIQ EDS file based on Anthony Garner’s article in May 2019 Stocks & Commodities “Backtesting A Mean-Reversion Strategy In Python,” can be obtained on request via email to info@TradersEdgeSystems.com. The code is also shown below.

I backtested the author’s mean-reversion system (MeanRev.eds) using both the EDS module, which tests every trade on a one-share basis, and also via the Portfolio Manager, which performs a trading simulation.

The short side strategy showed a loss overall in the EDS test so I tested only the long side in the Portfolio Manager. I selected trades using the z-score, taking the lowest values.

For capitalization, I used max of three trades per day with a max total of 10 open trades at one time, 10% allocated to each position. I did not deduct slippage but did deduct commissions. I used a recent list of the NASDAQ 100 stocks to run the test. The equity curve and account statistics report are shown in Figure 7.

Sample Chart

FIGURE 7: AIQ. This shows the equity curve (blue line) from long-only trading the NASDAQ 100 list of stocks from 1999 to March 15, 2019. The red line is the NDX index.

!Backtesting a Mean-Reversion Strategy In Python !Author: Anthony Garner, TASC May 2019 !Coded by: Richard Denning 3/14/19 !www.TradersEdgeSystems.com 

!ABBREVIATIONS:
C is [close].

!INPUTS:
meanLen is 10.
longZmult is -1.
shortZmult is 1.
meanMult is 10.

!FORMULAS:

SMA is simpleavg(C,meanLen).
LMA is simpleavg(C,meanLen*meanMult).
STD is sqrt(variance(C,meanLen)).
zScore is (C - SMA) / STD.

!TRADING SIGNALS & EXITS:

buyLong if zScore < longZmult and SMA > LMA.
sellShort if zScore > shortZmult and SMA < LMA.
exitLong if valresult(zScore,1) < -0.5 and zScore > 0.5.
exitShort if valresult(zScore,1) > 0.5 and zScore < -0.5.

showValues if 1.

—Richard Denning
info@TradersEdgeSystems.com
for AIQ Systems

The Agony and Ecstasy of Trend-Following

Let’s face it, many investors have a problem with riding a trend.  When things are going well they fret and worry about every blip in interest rates, housing starts, earnings estimates and the price of tea in China, which often keeps them from maximizing their profitability.  Alternatively, when things really do fall apart they suddenly become “long-term investors” (in this case “long-term” is defined roughly as the time between the current time and the time they “puke” their portfolio – just before the bottom).

Which reminds me to invoke:

Jay’s Trading Maxim #6: Human nature is a detriment to investment success and should be avoided as much as, well, humanly possible.

So, it can help to have a few “go to” indicators, to help one objectively tilt to the bullish or bearish side.  And we are NOT talking about “pinpoint precision timing” types of things here. Just simple, objective clues.  Like this one.

Monthly MACD

1

Figure 1 displays the S&P 500 index monthly chart with the monthly MACD Indicator at the bottom.Figure 1 – Monthly S&P 500 Index with MACD (Courtesy AIQ TradingExpert)

The “trading rules” we will use are pretty simple:

*If the Monthly MACD closes a month above 0, then hold the S&P 500 Index the next month

*If the Monthly MACD closes a month below 0, then hold the Barclays Treasury Intermediate Index the next month

*We start our test on 11/30/1970.

*For the record, data for the Barclays Treasury Intermediate Index begins in January 1973 so prior to that we simply used an annual interest rate of 1% as a proxy.

Figure 2 displays the equity curves for:

*The strategy just explained (blue line)

*Buying and holding the S&P 500 Index (orange) line

2

Figure 2 – Growth of $1,000 using MACD System versus Buy-and-Hold

Figure 3 displays some “Facts and Figure” regarding relative performance.

3

Figures 3 – Comparative Results

For the record:

*$1,000 invested using the “System” grew to $143,739 by 6/30/2019

*$1,000 invested using buy-and-hold grew to $102,569 by 6/30/2019

*The “System” experienced a maximum drawdown (month-end) of -23.3% and the Worst 5-year % return was +7.3% (versus a maximum drawdown of -50.9% and a Worst 5-year % return of -29.1% for Buy-and-Hold)

So, from the chart in Figure 2 and the data in Figure 3 it is “obvious” that using MACD to decide when to be in or out of the market is clearly “better” than buy-and-hold.  Right?  Here is where it “gets interesting” for a couple of reasons.

First off, the MACD Method outperforms in the long run by virtue of missing a large part of severe bear markets every now and then.  It also gets “whipsawed” more often than it “saves your sorry assets” during a big bear market.  So, in reality it requires ALOT of discipline (and self-awareness) to actually follow over time.

Consider this: if you were actually using just this one method to decide when to be in or out of the market (which is NOT what I am recommending by the way) you would have gotten out at the end of October 2018 with the S&P 500 Index at 2,711.74.  Now nine months later you would be sitting here with the S&P 500 Index flirting with 3,000 going “what the heck was I thinking about!?!?!?”  In other words, while you would have missed the December 2018 meltdown, you also would have been sitting in treasuries throughout the entire 2019 rally to date.

Like I said, human nature, it’s a pain.

To fully appreciate what makes this strategy “tick”, consider Figures 4 and 5. Figure 4 displays the growth of equity when MACD is > 0 (during these times the S&P 500 Index is held).

4

Figure 4 – Growth of $1,000 invested in S&P 500 Index when MACD > 0.

Sort of the “When things are swell, things are great” scenario.

Figure 5 displays the growth of $1,000 for both intermediate-term treasuries AND the S&P 500 Index during those times when MACD > 0.

5

Figure 5 – Growth of $1,000 invested in Intermediate-term treasuries (blue) and the S&P 500 (orange) when MACD < 0.

Essentially a “Tortoise and the Hare” type of scenario.

Summary

Simple trend-following methods – whether they involve moving average using price, trend lines drawn on charts or the MACD type of approach detailed herein – can be very useful over time.

*They can help an investor to reduce that “Is this the top?” angst and sort of force them to just go with the flowing while the flowing is good.

*They can also help an investor avoid riding a major bear market all the way to the bottom – which is a good thing both financially and emotionally.

But everything comes with a cost.  Trend-following methods will never get you in at the bottom nor out at the top, and you WILL experience whipsaws – i.e., times when you sell at one price and then are later forced to buy back at a higher price.

Consider it a “cost of doing business.”

Jay Kaeppel

Disclaimer:  The data presented herein were obtained from various third-party sources.  While I believe the data to be reliable, no representation is made as to, and no responsibility, warranty or liability is accepted for the accuracy or completeness of such information.  The information, opinions and ideas expressed herein are for informational and educational purposes only and do not constitute and should not be construed as investment advice, an advertisement or offering of investment advisory services, or an offer to sell or a solicitation to buy any security.

Where We Are

One of the best pieces of advice I ever got was this: “Don’t tell the market what it’s supposed to do, let the market tell you what you’re supposed to do.”

That is profound.  And it really makes me wish I could remember the name of the guy who said it.  Sorry dude.  Anyway, whoever and wherever you are, thank you Sir.

Think about it for a moment.  Consider all the “forecasts”, “predictions” and “guides” to “what is next for the stock market” that you have heard during the time that you’ve followed the financial markets.  Now consider how many of those actually turned out to be correct.  Chances are the percentage is fairly low.

So how do you “let the market tell you what to do?”  Well, like everything else, there are lots of different ways to do it.  Let’s consider a small sampling.

Basic Trend-Following

Figure 1 displays the Dow Industrials, the Nasdaq 100, the S&P 500 and the Russell 2000 clockwise form the upper left.  Each displays a 200-day moving average and an overhead resistance point.

1

Figure 1 – Dow/NDX/SPX/RUT (Courtesy AIQ TradingExpert)

The goal is to move back above the resistance points and extend the bull market.  But the real key is for them to remain in an “uptrend”, i.e.,:

*Price above 200-day MA = GOOD

*Price below 200-day MA = BAD

Here is the tricky part.  As you can see, a simple cross of the 200-day moving average for any index may or may not be a harbinger of trouble.  That is, there is nothing “magic” about any moving average.  In a perfect world we would state that: “A warning sign occurs when the majority of indexes drop below their respective 200-day moving average.”

Yet in both October 2018 and May 2019 all four indexes dropped below their MA’s and still the world did not fall apart, and we did not plunge into a major bear market.  And as we sit, all four indexes are now back above their MA’s.  So, what’s the moral of the story?  Simple – two things:

  1. The fact remains that major bear markets (i.e., the 1 to 3 year -30% or more variety) unfold with all the major averages below their 200-day moving averages.  So, it is important to continue to pay attention.
  2. Whipsaws are a fact of life when it comes to moving averages.

The problem then is that #2 causes a lot of investors to forget or simply dismiss #1.

Here is my advice: Don’t be one of those people.  While a drop below a specific moving average by most or all the indexes may not mean “SELL EVERYTHING” now, it will ultimately mean “SEEK SHELTER” eventually as the next major bear market unfolds.  That is not a “prediction”, that is simply math.

The Bellwethers

I have written in the past about several tickers that I like to track for “clues” about the overall market.  Once again, nothing “magic” about these tickers, but they do have a history of topping out before the major averages prior to bear markets.  So, what are they saying?  See Figure 2.

2

Figure 2 – SMH/Dow Transports/ZIV/BID (Courtesy AIQ TradingExpert)

The bellwethers don’t look great overall.

SMH (semiconductor ETF): Experienced a false breakout to new highs in April, then plunged.  Typically, not a good sign, but it has stabilized for now and is now back above its 200-day MA.

Dow Transports: On a “classic” technical analysis basis, this is an “ugly chart.” Major overhead resistance, not even an attempt to test that resistance since the top last September and price currently below the 200-day MA.

ZIV (inverse VIX ETF): Well below it’s all-time high (albeit well above its key support level), slightly above it’s 200-day MA and sort of seems to be trapped in a range.  Doesn’t necessarily scream “SELL”, but the point is it is not suggesting bullish things for the market at the moment.

BID (Sotheby’s – which holds high-end auctions): Just ugly until a buyout offer just appeared.  Looks like this bellwether will be going away.

No one should take any action based solely on the action of these bellwethers.  But the main thing to note is that these “key” (at least in my market-addled mind) things is that they are intended to be a “look behind the curtain”:

*If the bellwethers are exuding strength overall = GOOD

*If the bellwethers are not exuding strength overall = BAD (or at least not “GOOD”)

A Longer-Term Trend-Following Method

In this article I detailed a longer-term trend-following method that was inspired by an article written by famed investor and Forbes columnist Ken Fisher.  The gist is that a top is not formed until the S&P 500 Index goes three calendar months without making a new high.  It made a new high in May, so the earliest this method could trigger an “alert” would be the end of August (assuming the S&P 500 Index does NOT trade above it’s May high in the interim.

Jay Kaeppel

Disclaimer:  The data presented herein were obtained from various third-party sources.  While I believe the data to be reliable, no representation is made as to, and no responsibility, warranty or liability is accepted for the accuracy or completeness of such information.  The information, opinions and ideas expressed herein are for informational and educational purposes only and do not constitute and should not be construed as investment advice, an advertisement or offering of investment advisory services, or an offer to sell or a solicitation to buy any security.

What the Hal?

Some industries are cyclical in nature.  And there is not a darned thing you – or they – can do about it.  Within those industries there are individual companies that are “leaders”, i.e., well run companies that tend to out earn other companies in that given industry and whose stock tends to outperform other companies in that industry.

Unfortunately for them, even they cannot avoid the cyclical nature of the business they are in.  Take Halliburton (ticker HAL) for example.  Halliburton is one of the world’s largest providers of products and services to the energy industry.  And they do a good job of it. Which is nice.  It does not however, release them from the binds of being a leader in a cyclical industry.

A Turning Point at Hand?

1

A quick glance at Figure 1 clearly illustrates the boom/bust nature of the performance of HAL stock.Figure 1 – Halliburton (HAL) (Courtesy AIQ TradingExpert)

Which raises an interesting question: is there a way to time any of these massive swings?  Well here is where things get a little murky.  If you are talking about “picking timing tops and bottoms with uncanny accuracy”, well, while there are plenty of ads out there claiming to be able to do just that, in reality that is not really “a thing”.  Still, there may be a way to highlight a point in time where:

*Things are really over done to the downside, and

*For a person who is not going to get crazy and “bet the ranch”, and who understands how a stop-loss order works and is willing to use one…

..there is at least one interesting possibility.

It’s involves a little-known indicator that is based on a more well-known another indicator that was developed by legendary trader Larry Williams roughly 15 or more years ago.  William’s indicator is referred to as “VixFix” and attempts to replicate a VIX-like indicator for any market.  The formula is pretty simple, as follows  (the code is from AIQ Expert Design Studio):

*hivalclose is hival([close],22).

*vixfix is (((hivalclose-[low])/hivalclose)*100)+50.

In English, it is the highest close in the last 22-periods minus the current period low, which is then divided by the highest close in the last 22-periods. The result then gets multiplied by 100 and 50 is added.

Figure 2 displays a monthly chart of HAL with William’s VixFix in the lower clip.  In a nutshell, when price declines VixFix rises and vice versa.

2

Figure 2 – HAL Monthly with William’s VixFix (Courtesy AIQ TradingExpert)

Now let’s go one more step as follows by creating an exponentially smoothed version as follows (the code is from AIQ Expert Design Studio):

*hivalclose is hival([close],22).

*vixfix is (((hivalclose-[low])/hivalclose)*100)+50. <<<Vixfix from above

*vixfixaverage is Expavg(vixfix,3).  <<<3-period exponential MA of Vixfix

*Vixfixaverageave is Expavg(vixfixaverage,7). <<<7-period exp. MA

I refer to this as Vixfixaverageave (Note to myself: get a better name) because it essentially takes an average of an average.  In English (OK, sort of), first Vixfix is calculated, then a 3-period exponential average of Vixfix is calculated (vixfixaverage) and then a 7-period exponential average of vixfixaverage is calculated to arrive at Vixfixaverageave (got that?)

3

Anyway, this indicator appears on the monthly chart for HAL that appears in Figure 3.Figure 3 – HAL with Vixaverageave (Courtesy AIQ TradingExpert)

So here is the idea:

*When Vixfixaverageave for HAL exceeds 96 it is time to start looking for a buying opportunity.

OK, that last sentence is not nearly as satisfying as one that reads “the instant the indicator reaches 96 it is an automatic buy signal and you can’t lose”.  But it is more accurate.  Previous instances of a 96+ reading for Vixfixaverageave for HAL appear in Figure 4.

4

Figure 4 – HAL with previous “buy zone” readings from Vixfixaverageave (Courtesy  AIQ TradingExpert)

Note that in previous instances, the actual bottom in price action occurred somewhere between the time the indicator first broke above 96 and the time the indicator topped out.  So, to reiterate, Vixfixaverageave is NOT a “precision timing tool”, per se.  But it may be useful in highlighting extremes.

This is potentially relevant because with one week left in May, the monthly Vixfixaverageave value is presently above 96.  This is NOT a “call to action”.  If price rallies in the next week Vixfixaverageave may still drop back below 96 by month-end.  Likewise, even if it is above 96 at the end of May – as discussed above and as highlighted in Figure 4, when the actual bottom might occur is impossible to know.

5

Let me be clear: this article is NOT purporting to say that now is the time to buy HAL.  Figure 5 displays the largest gain, the largest drawdown and the 12-month gain or loss following months when Vixfixaverageave for HAL first topped 96.  As you can see there is alot of variation and volatility.  

Figure 5 – Previous 1st reading above 96 for HAL Vixfixaverageave

So HAL may be months and/or many % points away from an actual bottom.  But the main point is that the current action of Vixfixaverageave suggests that now is the time to start paying attention.

Jay Kaeppel

Disclaimer:  The data presented herein were obtained from various third-party sources.  While I believe the data to be reliable, no representation is made as to, and no responsibility, warranty or liability is accepted for the accuracy or completeness of such information.  The information, opinions and ideas expressed herein are for informational and educational purposes only and do not constitute and should not be construed as investment advice, an advertisement or offering of investment advisory services, or an offer to sell or a solicitation to buy any security.