<< . .

. 15
( : 30)

. . >>

time it steeply rises until the end of the year. On a more detailed level, rapid gains
seem to occur throughout most of January, the first half of April, and the first half
of June. A peak can be seen on October 8, and a very steep decline that leads to a
bottom on October 24. When the tables and chart for this publication were gener-
ated, extreme movements were clipped at +2 percent to prevent them from having
undue influence on the results. Consequently, the steep decline in October, and the
other patterns mentioned, cannot be attributed to events in specific years, for
instance, the crash in 1987. For some dates, there were incredibly consistent pat-
terns; e.g., if an entry occurred on the close of April 14 and the trade was exited
one day later, over 90% of the time a small profit would have been made. Entry on
May 6, with exit one day later, resulted in a profit 100% of the time, as did entry
on July 13. The market declined 90% of the time from October 18 to 19, and 89%
of the time from October 16 to 17. Although the crash may have involved a much
greater than normal amount of movement, the presence of a decline at the time
when the crash occurred was not at all unexpected. In an attempt to capture high-
probability, short-term movements, the Calendar Effects Chart could have been
used to enter trades that last one or two days. For example, such a methodology
would have caused a trader to go short at the close on October 16 and exit on
October 19, thus capturing the crash. The data contained in this publication could
also have been used to help maintain positions during periods of steep ascent or
There have been other studies indicating the presence of strong seasonal effects
in the market that can be exploited for profitable trading. An investigation we con-
ducted (Katz and McCormick, April 1997) found that short-term seasonal behavior
could be used to trade the S&P 500: The system used fairly fast moving average
crossovers that were computed on seasonally anticipated prices. Because the antici-
pated prices could be computed at least one year ahead, lag in the moving average
crossover was easily compensated for with a displacement that enabled the system
to take trades at crossovers occurring several days after the fact. The trades taken by
the system typically lasted between 7 and 8 days, a fairly short-term seasonal trad-
ing model. The system was profitable: It pulled an astonishing $329,900 from the
S&P 500 between January 3.1986, and November 8, 1996. The test did not include
transaction costs, but even with $15 round-turn commissions and $75 per trade slip-
page, a profit of $298,310 (about a 10% reduction) resulted. The return on account
was 732%, not annualized; assuming fixed contract trading, this amounted to over
70% per year, annualized, on a constant one-contract, no-reinvestment basis. There
were 351 trades taken, of which 60% were winners. Both the longs and shorts were
profitable. The average trade pulled $939 from the market-not bad for a simple,
seasonality-based trading model, Findings like these suggest there are strong sea-
sonal patterns in the markets producing inefficiencies that can be exploited by
traders, and that are worthy of investigation.
For our current purposes, seasonaliry is defined as cyclic or recurrent phe-
nomena that are consistently linked to the calendar. The term is being used in a
broad sense to mean market behavior related to the time of the year or to particular
dates, including anniversaries of critical events (e.g., the October 16, 1987, crash).
In short, seasonality is being construed as calendar-related cyclic phenomena. It
should be made clear, however, that while all seasonality is cyclic, not all cycles are

There are many ways to time entries using seasonal rhythms. Two basic approaches
will be examined: momentum and crossover. To calculate momentum, a series of
price changes is computed and centered smoothing (a smoothing that induces no
delays or phase shifts, in this case, a centered triangular moving average) is applied.
Each price change (or difference) in the series of price changes is then normalized:
It is divided by the 50.day average true range. For every bar, the date is determined.
Instances of the same date are then found in the past (or perhaps future). For each
such instance, the momentum is examined. The average of the momentums becomes
the value placed in the seasonal momentum series for the current bar. The seasonal
momentum series measures the expected rate of change (or momentum) in prices at
a given time. It is based on the historical movement of prices on the specified date
in different years. The number in the seasonal momentum series for the current bar
is determined only by events about 1 year or more ago. This is why it is possible to
use the centered moving average and other techniques that look ahead in time, rela-
tive to the bar bei˜ng considered. Entries are taken as follows: When the seasonal
momentum crosses above some positive threshold, a buy is posted. When the

momentum crosses below some negative threshold, a sell is posted. Buying or sell-
ing can happen on any of the standard three orders: at open, on limit, or on stop.
Entries may also be generated by computing the price differences, normalizing
them, applying an integration or summing procedure to the series (to obtain a kind
of pseudo-price series, based on previous instances of each date), and then applying
a moving average crossover model to the series. Because the value at any bar in the
series is determined only by bars that are about 1 year old or older, the delay in the
crossovers can be compensated for by simply looking ahead a small number of bars.
Both of the methods described above arc somewhat adaprive in nature; i.e.,
they do not require specific information about which dates a buy or sell order
should be placed. The adaptive quality of the aforementioned methods is impor-
tant since different markets respond to seasonal influences in different ways, a fact
that logic, as well as our earlier research, supports.
In the current study, several rules for handling confirmations and inversions
are also tested to determine whether better results can be obtained over the basic
models. Confirmarion means additional data is available that supports the signals
produced by the model. For example, suppose a model generated a buy signal
for a given bar. If everything is behaving as it should, the market should be form-
ing a bottom around the time of the buy. If, however, the market is forming a top,
the buy signal might be suspect, in that the market may not be adhering to its typ-
ical seasonal timing. When such apparently contradictory circumstances exist, it
would be helpful to have additional criteria to use in deciding whether to act upon
the signal, in determining if it is correct. The crossover-with-con˜rmation model
implements the crossover model with an additional rule that must be satisfied
before the signal to buy or sell can be acted upon: If a buy signal is issued, the
Slow %K on the signal bar must be less than 25%, meaning the market is at or near
the bottom of its recent range. If a sell signal is issued, Slow %K must be greater
than 75%, indicating that the market is at or near the top of its range, as would be
expected if following its characteristic seasonal behavior. The conjinnation-und-
inversion model adds yet another element: If a buy signal is issued by the basic
model, and the market is near the top of its range (Slow %K greater than 75%),
then it is assumed that an inversion has occurred and, instead of issuing a buy sig-
nal, a sell signal is posted. If a sell signal is generated, but the market is near the
bottom of its range (Slow %K less than 25%), a buy signal is issued.

Consider trading a simple moving average crossover system. Such a system is
usually good at capturing trends, but it lags the market and experiences frequent
whipsaws. If slower moving averages are used, the whipsaws can be avoided,
but the lag is made worse. Now add seasonality to the equation, The trend-fol-
lowing moving average system is applied, not to a series of prices, but to a
series that captures the seasonal ebb and flow of the market. Then compute the
seasonal series so it represents that ebb and flow, as it will be several days from
now-just far enough ahead to cancel out the annoying lag! The result: A sys-
tem without lag (despite the use of slow, smooth, moving averages) that follows
seasonal trends. The ability to remove lag in this way stems from one of the
characteristics of seasonality: Seasonal patterns can be estimated far in
advance. In other words, seasonality-based models are predictive, as opposed
to merely responsive.
Since seasonality-based models are predictive, and allow turning points to be
identified before their occurrence, seasonal-based trading lends itself to coun-
tertrend trading styles. Moreover, because predictions can be made far in advance,
very high quality smoothing can be applied. Therefore, the kind of whipsaw trad-
ing encountered in responsive models is reduced or eliminated. Another nice char-
acteristic of seasonality is the ability to know days, weeks, months, or even years
in advance when trades will occur--certainly a convenience.
Seasonality also has a downside. The degree to which any given market may
be predicted using a seasonal model may be poor. Although there may be few
whipsaws, the typical trade may not be very profitable or likely to win. If inver-
sions do occur, but the trading model being used was not designed to take them
into account, sharp losses could be experienced because the trader could end up
going short at an exact bottom, or long at an exact top.
The extent to which seasonal models are predictive and useful and the pos-
sibility that inversion phenomena do exist and need to be considered are questions
for empirical study.

Entries based on seasonality may be effected in at least three ways: with stops,
limits, or market orders. While a particular entry option may work especially well
with a particular model, any entry may be used with any model.
Entry orders themselves have their own advantages and disadvantages. The
advantage of a market or&r is that no signaled entry will be missed. Stop orders
ensure that no significant trends (in a trend-following model) will elude the trader,
and that entry will not occur without confirmation by movement in favor of the
trade (possibly beneficial in some countertrend models). The disadvantages are
greater slippage and less favorable entry prices, A limit order gets the trader the
best price and minimizes transaction costs. However, important trends may be
missed while waiting indefinitely for a retracement to the limit price. In coun-
tertrend models, a limit order may occasionally worsen the entry price. The entry
order may be tilled at the limit price, rather than at a price determined by the neg-
ative slippage that sometimes occurs when the market is moving against the trade
at the time of entry!

The data sample used throughout the tests of seasonal entry methods extends from
August 1, 1985, to December 31, 1994 (the in-sample period), and from January
1, 1995, through February 1, 1999 (the out-of-sample period). For seasonality
studies, an in-sample period of only 10 years means there is a shortage of data on
which to develop the model. When generating seasonal entries was discussed,
mention was made about calculating seasonal momentum (or average price behav-
ior) based on equivalent dates in previous years. Because of the data shortage,
when considering the in-sample data, calculations will be based not only on past
years, but also on future years. This is accomplished using fhe “jackknife.”
Target dates are run throughout the series, bar after bar. If only past years are
included, for the early data points, there are very few past years or none at all.
Since it takes at least 6 years of past data to get a reasonable seasonal average,
there would be no seasonality calculations for most of the in-sample period, which
itself is only 10 years. Consequently, there is very little data on which to optimize
essential parameters or determine how seasonal models perform on the in-sample
data. The jackknife, a well-known statistical technique (also known as the “leave-
one-out method”), helps solve the data shortage problem
Suppose a seasonality estimate for June 1, 1987, is being calculated. If
only past data from the in-sample period is used, the estimate would be based on
data from 1986 and 1985. If, however, the jackknife is applied, not only would
data from the past be available, but so would data from the “future,” i.e., the
other years of the in-sample period (1988 through 1994). If the year (1987) that
serves as the target bar for the calculations is removed from the in-sample period,
the seasonality estimate for that bar would now be based on 9 years of data, a
reasonably adequate sample. The jackknife procedure is justified because the
data being examined to make the prediction is fairly independent of the data
actually being predicted by the seasonality estimate. Since the data used in gen-
erating the prediction is at least 1 year away from the target date, it is not con-
taminated with current market behavior. The process™provides an effectively
larger sample than could otherwise be obtained, and does so without seriously
compromising the available number of degrees of freedom.
For bars in the out-of-sample period, all past years are used to generate the sea-
sonal&y estimates. For example, to calculate the seasonality for January 14, 1999,
the &past-years technique is used: Data from 1998 all the way back to 1985 are
included in the analysis. In this way, no calculation for the out-of-sample period is
ever based on any future or current data.
All the tests that follow are performed using seasonal entries to trade a diversi-
fied portfolio of commodities. The exits are the standard ones, used throughout this
book to study entry models. Trades are closed out either when an entry in the oppos-
ing direction occurs or when the standard exit closes the trade, whichever comes first.
The test platform is also standard. Here is the code for the seasonal trading tests:
CHAFlER 8 Scasonality 159

/I cro88ove* avg
MovAvglma2,mal,matype,aVglen,nb) ;
// stochastic osc
if(modeltype == 3 11 modeltype == 4)
s-bar m*t %K
StochOac(stoch,hi,lo,cls,1,9,nb); //
default: nrerrorl"TRAPSMOD: invalid modeltype"1;
/I step through bare (days) to simulate actual trading
forlcb = 1; cb L- nb; cb++) (

// take no trades before the in-sample period
// ,.. same aa Tradestation's MaxBarsBack setting
if(dt[cbl < IS-DATE) ( eqcls[cb] = 0.0; continue; )

/f execute any pending orders and save closing equity
rc 3 ts.updaee,opnIcbl, bilcbl, loIcbl. clelcbl, cb);
if(rc I= 0) nrerror("Trade buffer overflow");
eqcls[cbl = te.curr.nte˜ify(EQ_CLOSETOTAL);

// avoid placing orders on possibly limit-locked days
if(hi[cb+ll == lo[cb+ll) continue;

/! generate entry aignala, stop prices and limit prices
// for all seasonality-based entry models
signal - 0;
switchtmodeltype) (
case 1: // basic thresholded momentum entry model
k = cb + disp;
tmp = thresh * mallkl;
ifleavglk] 5 tmp &(r savglk-11 c= tmp)
signal = 1;
else if(savg[kl < -tmp &h aavglk-II >= -tmp)
signal * -1;
case 2: // basic crossover entry model
k - cb + disp;
} // process next bar


After declaring local variables and arrays, the first major block of code
copies various parameters to local variables for more convenient and understand-
able reference. The parameters are described in comments in this block of code.
The next block of code performs all computations that are carried out on
complete time series. The 50-bar average true range is calculated and saved in a
vector (exiratr); it will be used later for the placement of money management stops
and profit targets in the standard exit strategy. The average true range in this vec-
tor (or data series) is also used to normalize the price changes in the code that
immediately follows.
After calculating the average true range, normalized and clipped price
changes are calculated. Each bar in the seriespchg reflects the change in price from
the close of the previous bar to the close of the current bar. The price changes are
normalized by dividing them by the average true range. They are then clipped to
limit the influence of sharp spikes or statistical oudiers. Normalization is performed
because markets change in their volatility over time, sometimes very dramatically.
For example, the current S&P 500 has a price almost five or more times its price 15
years ago, with a corresponding increase in the size of the average daily move. If
the price changes were not normalized and represented in terms of recent volatili-
ty, any seasonal estimate conducted over a number of years would be biased. The
years with greater volatility would contribute more to the estimate than the years
with lesser volatility. In the case of the S&P 500, the most recent years would
almost totally dominate the picture. Using normalized price changes, each year
contributes about equally. Clipping to remove outhers is performed so the occa-
sional, abnormal price change does not skew the estimates. Clipping is performed
at -2 and f2 average true range units.
The modekype selection then determines which calculations occur next. A
modeltype of 1 selects the basic momentum model. The seasonals are computed
from the clipped and normalized price changes, the jackknife is used on the in-
sample period, and the all-past-years technique is used for the out-of-sample period.
These calculations are accomplished with a call to the function called
SeasonalAvg. The series of seasonal estimates is then smoothed using a moving
average of the type, specified by the parameter matype, and of a length set by
avglen, another parameter. A series of average absolute deviations of the seasonal
momentums is then computed. This series is nothing more than a lOO-bar simple
moving average of the absolute values of seasonal momentum, which is used in
later computations of threshold values. The modeltypes of 2,3, and 4 all represent
variations of the crossover model. The seasonals are computed, and then the sea-
sonal estimates of price change for every bar are integrated (a running sum is cal-
culated), creating a new series that behaves almost like a price series. The
synthesized, price-like series represents the movement in prices based on typical
behavior in previous and perhaps future years. Two moving averages are then
computed: ma1 (a moving average of the integrated seasonal time series of
CHAPTER 8 Seamnality 165

matype, having a length of avglen) and ma2 (used as a signal line for detecting
crossovers, calculated by taking a moving average of mal; the kind of average
taken is again specified by matype and the length by avglen). If the modeltype is
3 or 4, additional calculations are performed for models in which confirmation
and/or inversions are detected; in the current study, a 9-bar Fast %K is calculated
and saved in the vector sroch.
The next block of code consists of a loop that steps sequentially through all
bars in the data series. This loop is the same one that has been seen in every pre-
vious chapter on entry strategies. The first few lines of code deal with such issues
as updating the simulator, calculating the number of contracts to trade, and avoid-
ing limit-locked days. The next few lines generate entry signals for all the season-
ality-based entry models. Depending on the value of the modeltype parameter,
either of four different approaches is used to generate entry signals.
A modeltype of 1 represents the basic momentum threshold entry model. A
threshold is calculated by multiplying a threshold-determining parameter (thresh)
by the average absolute deviation of the seasonal momentum over the past 100 bars,
A long signal is issued if the seasonal momentum (savg), on the current bar plus a
displacement parameter (disp), crosses above the threshold. If the seasonal mornen-
turn, at the current bar plus the displacement, crosses below the negative of the
threshold, a sell signal is generated. In other words, if sufficiently strong seasonal
momentum is predicted for a given date, plus or minus some number of days or bars
(disp), then a trade is taken in the direction of the expected movement.
For modeltype 2, which represents the basic crossover entry model, the tnov-
ing averages of the integrated seasonals, at the current bar plus a displacement fac-
tor, are calculated. If the first moving average crosses above the second, a buy is
generated. If it crosses below, a sell is generated. The displacement factor allows
the model to look for such crossings some number of days down the line (ahead
in time). In this manner, the displacement can neutralize the lag involved in the
moving averages. Because the seasonal averages are based on data that is usually
a year old, it is perfectly acceptable to look ahead several days.
A modelrype of 3 represents the same crossover model, but with the addition
of confirmation. Confirmation is achieved by checking the Stochastic oscillator of
the actual price series to determine whether it is consistent with what one would
be expected if the market were acting in a seasonal fashion.
If modeltype is 4, the crossover model, with the addition of confirmation and
inversion, is selected. When there is a modeltype of 4, a buy signal is issued if the
first moving average crosses above the second, and the seasonal pattern is con-
firmed by a Stochastic of less than 25. The model assumes that an inversion has
occurred and issues a sell signal if the Stochastic is over 75. If the first moving
average crosses below the second moving average, and the normal seasonal pat-
tern is confirmed by a Stochastic that is over 75, a sell signal is issued. Inversion
is assumed and a buy signal issued if the Stochastic is less than 25.
Finally, the limit price (limprice) is set at the midpoint of the current bar. The
stop price (slppn™ce), for entry on a stop, is set at the close of the current bar plus
(if entering long) or minus (if entering short) one-half of the 50-bar average true
range. The remaining code blocks are identical to those in previous chapters: They
involve actually posting trades using the specified order (ordertype) and instruct-
ing the simulator to employ the standard exit strategy.

Tests are performed on two seasonality-based entry models: the crossover model
(both with and without confirmation and inversions) and the momentum model.
Each model is examined using the usual three entry orders: enter at open, on limit,
and on stop.
Tables 8-l and 8-2 provide information on the specific commodities that the
model traded profitably, and those that lost, for the in-sample (Table 8-l) and out-
of-sample (Table 8-2) runs. The SYM column represents the market being studied.
The rightmost column (COUNT) contains the number of profitable tests for a given
market. The numbers in the first row represent test identifiers. The last row
(COUNT) contains the number of markets on which a given model was profitable.
The data in these tables provide relatively detailed information about which markets
are and are not profitable when traded by each of the models: One dash (-) indicates
a moderate loss per trade, i.e., $2,000 to $4,ooO, two dashes (--) represent a large loss
per trade, i.e., $4,ooO or more; one plus sign (+) means a moderate profit per trade,
i.e., $1,000 to $2,000, two pluses (+ +) indicate a large gain per trade, i.e., $2,000
or more; and a blank cell means that the loss was between $0 and $1,999 or the prof-
it was between $0 and $1,000 per trade. (For information about the various markets
and their symbols, see Table II-1 in the “Introduction” to Part II.)

Tests of the Basic Crossover Model
A simple moving average (maI) of a specified length (av&n) was computed for the
integrated, price-like seasonality series. A second moving average (ma2) was taken of
the first moving average. A buy signal was generated when ma1 crossed above ma2.
A sell signal was generated when maI crossed below ma2. (This is the same moving-
average crossover model discussed in the chapter on moving averages, except here it
is computed on a predicted, seasonal series, rather than on prices.) The entries were
effected by either a market at open (Test l), a limit (Test 2), or a stop order (Test 3).
Optimization for these tests involved stepping the length of the moving aver-
ages (avglen) from 5 to 20 in increments of 5 and the displacement (disp) from 0
to 20 in increments of 1. For entry at the open, the best performance (in terms of
in-sample risk-to-reward ratio) was achieved with a moving average length of 20
and a displacement of 5. Entry on a limit was best with a length of 20 and a dis-

In-Sample Performance Broken Down by Test and Market

placement of 8. Entry on a stop required a length of 20 and a displacement of 6.
The model seemed to prefer longer moving averages (more smoothing), and some-
what earlier signals were required by the limit order when compared with the stop
or market-at-open orders.
In-sample, none of the results were profitable when both long and short posi-
tions were traded. However, the losses were much smaller on a per-trade basis than
those observed in many of the other tests presented in earlier chapters. The stop
order performed best. The market-at-open order performed worst. The limit order
came in not too far behind the stop. For both the stop and limit orders, trading was
Out-of-Sample Performance Broken Down by Test and Market

i_ i_ i_ i_ /_ i- i- i_ i+ i++ I_ I++ 1
. . ++ ++ ++ _ - - ++ + -

<< . .

. 15
( : 30)

. . >>