One of the TOS studies I had been holding back is SeaPro, Seasonal Projection of price. This study averages the fractional seasonal moves from a reference date and projects the average into the future. Here's an image of SeaPro5 in action:

*How todays price might move if this was last year or two years ago*

*projection average*, the solid blue line.

**Theoretically, seasonality should be factored into the implied volatility**

*projection average*can be said to be predictive, which is why it plots to the right of the prices in the chart. If you use this study on a 1day/1year chart you will need to adjust your settings to show 252 or so bars to the right to see a full years projection. Theoretically, seasonality should be factored into the implied volatility, in that traders could know this information and bid the price of options accordingly. So this study just gives you a way to visualize seasonality better when some commentator says there is a seasonal bias in play.

**The area between the projection average and the flat line is high probability for recurrance**.

*flat line,*which is obvious, but until I actually plotted that line it did not occur to me take notice of the area between the

*flat line*and the

*projection average*.

*If the*

*projection average*represents even odds for recurrance then the area between the

*projection average*and the

*flat line*is high probability for recurrance.

**What track through the high probability area, between flat line and projection average, is important for my trading?**

**62% of the individual seasonal projections track above this lower HPI**

*flat line*and

*projection average*is shown and only when it tracks 2%, by default, or more away from the

*flat line*. So when I see a swath of green from the HPI I know that it is saying that there is a relatively strong bullish seasonal edge in play. If there is just a few splashes of green here and there then there is a weak case for seasonality.

*A Trio Of Studys*

#########################

# sdi_seaPro5: 5-Season Seasonal Projection Of Price

#hint: Displays a seasonal projection of price based on the average fractional price move between the anchor date and same seasonal dates in the past. Also shows an indicator of high probability of exceeding-on-date (hpi.) Triangles decorate the HPI when 3 or more seasons exceed it. rev:1.9.1 http://www.smalldoginvestor.com

# author: allen everhart

# date: 17Dec2010

#

# copylefts reserved. This is free software. That means you are free

# to use or modify it for your own usage but not for resale.

# Help me get the word out about my blog by keeping this header

# in place.

input trailAnchor = 0; #hint trailAnchor: Sets Moving anchor date to n-bars ago. Takes precedence over anchorDate.

input anchorDate = 0; #hint anchorDate: Sets fixed anchor date. Format: YYYYMMDD.

input seasonLen = 252 ; #hint seasonLen: Sets number of bars in a season. <br>252=1yr on US-equity, daily charts. <br>63=3mo qtr on US-equity, daily charts. <br> 260=1yr FX & Futures daily charts. <br>52=1yr on weekly chart.

input hpIsoline = { "54%", default "62%", "73%", "84%", "90%", "hide" }; #hint hpIsoline: Sets exceed-on-date probability for hpi.

input hpiMinPct = 2.0 ; #hint hpiMinPct: Sets profit filter for hpi.

input individualSeasons = { default hide, show}; #hint individualSeasons: show the projection of individual seasons. Most recent 3 are lime-colored, oldest are grey.

input stdMultiple = 0.0; #hint stdMultiple: Multiple of the standard deviation to show. Zero to hide.

#input version = { hide, default show }; #hint version: show script version as a chart label.

#AddChartLabel( version == version.show, "sdi_seaPro5 v:1.7.0" );

# v:1.9.1 - 5/19/2012 clsy(n>0) was referencing close from 1 bar too recent. fixed.

# v:1.9.0 - 3/30/2010 hide bubbles - prevent bloat.

# v:1.8.0 - 8/30/11 deprecate the version label - version in hint

# v:1.7.0 - simplify - remove envelope and spike analysis

# v:1.6.0 - expand the choice on standard deviation multiples.

# v:1.5.2 - fixes bug w. originDate not propagating forward correctly

# v:1.5.1 - fixes spurious incorrect color on hpi

def x = if hpIsoline == hpIsoline."54%" then 0.1

else if hpIsoline == hpIsoline."62%" then 0.3

else if hpIsoline == hpIsoline."73%" then 0.6

else if hpIsoline == hpIsoline."84%" then 1.0

else 1.3;

rec originDate =

if trailAnchor > 0 && IsNaN(close[-trailAnchor]) && IsNaN(close[-trailAnchor - 1]) then

getYyyyMmDd()

else if trailAnchor > 0 && originDate[1] > 0 then # 1.5.2 added [1] to originDate

originDate[1]

else

anchorDate

;

#plot od = originDate;

# pn is the number of bars past the originDate

rec pn =

if !pn[1] && getYyyyMmDd()[1] < originDate && getYyyyMmDd() >= originDate then

1

else if !pn[1] && IsNaN(close) && !IsNaN(close[1]) then

1

else if pn[1] > 0 then

pn[1] + 1

else

0

;

#plot p=pn;

rec clsy0 =

if pn == 1 then close[1]

else if pn > 1 then clsy0[1]

else 0;

plot fl = if pn > 0 then clsy0 else double.NaN; # flat line

fl.SetStyle(curve.SHORT_DASH) ;

fl.setDefaultColor(color.CYAN);

fl.hidebubble();

rec clsy1 =

if pn == 1 then close[seasonLen+1]

else if pn > 1 then clsy1[1]

else 0;

#plot fl1 = if clsy1 > 0 then clsy1 else double.NaN;

rec clsy2 =

if pn == 1 then close[(2 * seasonLen) +1]

else if pn > 1 then clsy2[1]

else 0;

#plot fl2 = if clsy2 > 0 then clsy2 else double.NaN;

rec clsy3 =

if pn == 1 then close[(3 * seasonLen) +1]

else if pn > 1 then clsy3[1]

else 0;

#plot fl3 = if clsy3 > 0 then clsy3 else double.NaN;

rec clsy4 =

if pn == 1 then close[(4 * seasonLen) +1]

else if pn > 1 then clsy4[1]

else 0;

#plot fl4 = if clsy4 > 0 then clsy4 else double.NaN;

rec clsy5 =

if pn == 1 then close[(5 * seasonLen) +1]

else if pn > 1 then clsy5[1]

else 0;

#plot fl5 = if clsy5 > 0 then clsy5 else double.NaN;

def y1 = close[1 * seasonLen] / clsy1 ;

def y2 = close[2 * seasonLen] / clsy2 ;

def y3 = close[3 * seasonLen] / clsy3 ;

def y4 = close[4 * seasonLen] / clsy4 ;

def y5 = close[5 * seasonLen] / clsy5 ;

plot p1 = if pn > 0 then clsy0 * y1 else double.NaN;

plot p2 = if pn > 0 then clsy0 * y2 else double.NaN;

plot p3 = if pn > 0 then clsy0 * y3 else double.NaN;

plot p4 = if pn > 0 then clsy0 * y4 else double.NaN;

plot p5 = if pn > 0 then clsy0 * y5 else double.NaN;

p1.setHiding(individualSeasons == individualSeasons.hide);

p2.setHiding(individualSeasons == individualSeasons.hide);

p3.setHiding(individualSeasons == individualSeasons.hide);

p4.setHiding(individualSeasons == individualSeasons.hide);

p5.setHiding(individualSeasons == individualSeasons.hide);

p1.SetDefaultColor(color.LIME);

p2.SetDefaultColor(color.LIME);

p3.SetDefaultColor(color.LIGHT_GRAY);

p4.SetDefaultColor(color.LIGHT_GRAY);

p5.SetDefaultColor(color.LIGHT_GRAY);

p1.hidebubble();

p2.hidebubble();

p3.hidebubble();

p4.hidebubble();

p5.hidebubble();

p1.SetLineWeight(2);

p2.SetLineWeight(2);

#p3.SetLineWeight(2);

def yavg = (y1 + y2 + y3 + y4 + y5 ) / 5;

plot pa =

if pn > 0 then

(p1 + p2 + p3 + p4 + p5 ) / 5

else

double.NaN

;

pa.SetLineWeight(1);

pa.SetDefaultColor(color.CYAN);

pa.hidebubble();

def hpiUpTarg = clsy0 * (1 + (hpiMinPct / 100));

def hpiDnTarg = clsy0 * (1 - (hpiMinPct / 100));

def pstd = Sqrt((Sqr(p1 - pa) + Sqr(p2 - pa) + Sqr(p3 - pa)

+ Sqr(p4 - pa) + Sqr(p5 - pa) ) / 5);

plot psdu = pa + (pstd * stdMultiple);

psdu.setHiding(stdMultiple==0);

psdu.hidebubble();

plot psdd = pa - (pstd * stdMultiple);

psdd.setHiding(stdMultiple==0);

psdd.hidebubble();

def hpul = pa - (x * pstd);

def hpll = pa + (x * pstd);

plot hpi = # High Probability isoline

if pn > 0 && pa > clsy0 && hpul >= hpiUpTarg then

hpul

else if pn > 0 && pa < clsy0 && hpll <= hpiDnTarg then

hpll

else

double.NaN

;

#hpi.setpaintingStrategy(paintingStrategy.LINE_VS_TRIANGLES);

hpi.AssignValueColor( if hpi > fl then color.GREEN else color.RED );

AddCloud( hpi, fl, color.GREEN, color.RED );

hpi.SetLineWeight(1);

hpi.SetStyle(curve.POINTS);

hpi.setHiding(hpisoline == hpisoline.hide);

hpi.hidebubble();

def nup =

(if p1 >= hpi then 1 else 0)

+ (if p2 >= hpi then 1 else 0)

+ (if p3 >= hpi then 1 else 0)

+ (if p4 >= hpi then 1 else 0)

+ (if p5 >= hpi then 1 else 0)

;

#plot pnup = if pn>0 then nup else double.NaN ;

def ndn =

(if p1 <= hpi then 1 else 0)

+ (if p2 <= hpi then 1 else 0)

+ (if p3 <= hpi then 1 else 0)

+ (if p4 <= hpi then 1 else 0)

+ (if p5 <= hpi then 1 else 0)

;

plot n =

if pn > 0 && yavg > 1 && nup > 3 && hpi >= hpiUpTarg then

hpi

else if pn > 0 && yavg < 1 && ndn > 3 && hpi <= hpiDnTarg then

hpi

else

double.NaN

;

n.SetPaintingStrategy(PAIntingStrategy.LINE_VS_TRIANGLES);

n.AssignValueColor(

if n > clsy0 && nup > 4 then color.MAGENTA

else if n < clsy0 && ndn > 4 then color.MAGENTA

else if n > clsy0 then color.GREEN

else color.RED

);

n.SetLineWeight(1);

n.setHiding(hpisoline == hpisoline.hide);

n.hidebubble();

###########################################

_

Thank you for sharing this indicator. I've plotted it on my TOS chart and have allotted a 23 day expansion to the right of the chart. What do the green dots and green arrows on top of the "splash of green" on the chart mean?

ReplyDeleteAm trying to spread trade weeklys. What would be the "safe" zone to place a credit spread? Below the "flat line"? Thanks again!

Or above the "projection" line as well?

DeleteThe green splash is the area between the flat line and the lower bollinger-like line of the projection average when it rises 2% or more above the flat line. In the default settings I use a multiplier of 0.3 std for the bands because it can be shown, mathematically, that 64% of the seasonality projects to higher values than this lower band. For me this represents minimal reliability to be actionable for trading, after all one can draw an average line through any set of randomly selected prices. The triangles represent where 4 or 5 of the projections exceed (or subceed on bearish seasonality) the projection. I don't find the triangles to be terribly more actionable than the splash indicator, though.

DeleteThis is great! A previous teacher advocated a lot of manual research like this to take advantage of earnings plays. Now I am a convert to TastyTrade and your indicator is a huge help to maximize POP. Is there a way to do a similar code to forecast IV rank and pending IV rank collapses? Seems that seasonality may apply.

ReplyDeleteInteresting idea. I might get around to writing something like that eventually.

Delete