Get Specific Months For Seasonality

tdespenza

New member
VIP
I've trying to replicate the seasonality with labels from Stockcharts but I'm having trouble accessing the specific months. Can someone point me in the right direction?

$NFLX example => https://stockcharts.com/freecharts/seasonality.php?symbol=nflx&compare=

Here's what I have so far:

Code:
Assert(GetAggregationPeriod() == AggregationPeriod.MONTH, "The `MonthlySeasonality` study is designed for monthly charts only");

def month = GetMonth();

def currentMoney = close - open;
def currentPercentage = (currentMoney / close) * 100;
AddLabel(visible = Yes, text = "Current: " + AsText(currentMoney, format = NumberFormat.DOLLAR) + "/" + AsText(currentPercentage) + "%", color = Color.LIGHT_GRAY);

def janDifference = Average(data = close[1]) - Average(data = open[1]);
def janPercentage = Average(janDifference) / Average(data = close[1]) * 100;
def janPostive = Average(janPercentage > 0) * 100;
AddLabel(visible = Yes, text = "Jan: " + AsText(value = janPostive) + "%+|Avg: " + AsText(janPercentage) + "%", color = Color.WHITE);
 
Last edited:

XeoNoX

Well-known member
VIP
You can do this easier by:

23moback = aggregate to monthly and scan within last 23 months since TOS scan wont go 24 months back

Code:
score = if  close > open then plus 1 else 0
finalscore = sum of score

reference for scoring ( https://usethinkscript.com/threads/basic-scoring-system.4954/#post-46304 )

final_scan = final score percent forumula

if you want help repeat this pattern below until you get to month1 and post the code back ( just repeat the countdown till you hit 1, should be a total of 23 lines that look similar)

Code:
def month21 = if (open(period = AggregationPeriod.MONTH)[21]) < (close(period = AggregationPeriod.MONTH)[21]) then 1 else 0;
def month22 = if (open(period = AggregationPeriod.MONTH)[22]) < (close(period = AggregationPeriod.MONTH)[22]) then 1 else 0;
def month23 = if (open(period = AggregationPeriod.MONTH)[23]) < (close(period = AggregationPeriod.MONTH)[23]) then 1 else 0;
 
Last edited:

XeoNoX

Well-known member
VIP
@tdespenza You were looking for something like this? One shows the percentage of higher closes over 48 months and the other shows number of consecutive bars over 48 months plotted (non percent) or were u looking for year over year same month comparison 4 years back?

Capture.png
 

tdespenza

New member
VIP
Unfortunately, I don't have a better one.

But what I'm looking for are labels to add to the chart. Whereas it displays the seasonality of a specific month.
 

bp805

New member
Giving this a bump. Im interested in trying to get this to work as well.

Basically what we're looking for is a chart label for every month displayed on a monthly time frame that gives the historical % that a given stock is up during that month, and an average % gain for that month. Ideally we'd be able to have the label show this for the life of the stock, but if that wont work, at least 10 years worth would be good.
 

Slippage

Well-known member
Giving this a bump. Im interested in trying to get this to work as well.

Basically what we're looking for is a chart label for every month displayed on a monthly time frame that gives the historical % that a given stock is up during that month, and an average % gain for that month. Ideally we'd be able to have the label show this for the life of the stock, but if that wont work, at least 10 years worth would be good.

10+ years x 12 months = minimum 120 labels on the chart per stock. I doubt you're really going to want that. You should take a look at the built-in MonthlySeasonality study if you want that much data.

Like that study, for any custom solution you'll be limited to use on a monthly chart. You can't access enough data via ThinkScript for 10 years from a daily chart.

You can access the same month in a prior year by using an index of 12. For multiple years ago, multiply by twelve.

I wrote the code below for you to use as an example. It calculates the average return for each month over the last 10 years. Note, the way TOS averaging works, if there's not 10 years of data then you'll get nothing.

Again, This will only work on a monthly chart.
Ruby:
Assert(GetAggregationPeriod() == AggregationPeriod.MONTH, "The `Seasonality` study is designed for monthly charts only");

def return = close / open;
def r = Round(if return > 1 then (return - 1) * 100 else if return < 1 then (1 - return) * -100 else 1, 2);
def factor = 12;
def avg = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;


# display the month-to-date return
AddLabel(yes, "MTD: " + r + "%", Color.LIGHT_GRAY);

def m = GetMonth();

# display the average return for this month
AddLabel(
  yes,
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec") + ": " + Round(avg, 2) + "%",
  Color.LIGHT_GRAY
);

# display the average return for next month
AddLabel(
  yes,
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec") + ": " + Round(avg[-1], 2) + "%",
  Color.LIGHT_GRAY
);
 

bp805

New member
10+ years x 12 months = minimum 120 labels on the chart per stock. I doubt you're really going to want that. You should take a look at the built-in MonthlySeasonality study if you want that much data.

Like that study, for any custom solution you'll be limited to use on a monthly chart. You can't access enough data via ThinkScript for 10 years from a daily chart.

You can access the same month in a prior year by using an index of 12. For multiple years ago, multiply by twelve.

I wrote the code below for you to use as an example. It calculates the average return for each month over the last 10 years. Note, the way TOS averaging works, if there's not 10 years of data then you'll get nothing.

Again, This will only work on a monthly chart.
Ruby:
Assert(GetAggregationPeriod() == AggregationPeriod.MONTH, "The `Seasonality` study is designed for monthly charts only");

def return = close / open;
def r = Round(if return > 1 then (return - 1) * 100 else if return < 1 then (1 - return) * -100 else 1, 2);
def factor = 12;
def avg = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;


# display the month-to-date return
AddLabel(yes, "MTD: " + r + "%", Color.LIGHT_GRAY);

def m = GetMonth();

# display the average return for this month
AddLabel(
  yes,
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec") + ": " + Round(avg, 2) + "%",
  Color.LIGHT_GRAY
);

# display the average return for next month
AddLabel(
  yes,
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec") + ": " + Round(avg[-1], 2) + "%",
  Color.LIGHT_GRAY
);

@Slippage I guess I should have explained more clearly. Not looking for one label per month for each year for 10 years (total of 120 labels) but one label for each month, total of 12, displayed on a monthly chart that would show the total average return for that month. I'd also want a second label that shows the % of time that that given month has a positive return (50%, 60%, 70% etc.). Essentially trying to replicate what stockcharts.com has on their seasonality charts here: https://stockcharts.com/freecharts/seasonality.php?symbol=aapl&compare=

See the below screenshot for what I've tried to achieve.

LkrcvY8.jpg


I've also started a post a couple days ago with the code that I'm using that I'm having issues with. See the link below for that post....

https://usethinkscript.com/threads/monthly-average-labels-problem.6456/

Thanks!
 

bp805

New member
10+ years x 12 months = minimum 120 labels on the chart per stock. I doubt you're really going to want that. You should take a look at the built-in MonthlySeasonality study if you want that much data.

Like that study, for any custom solution you'll be limited to use on a monthly chart. You can't access enough data via ThinkScript for 10 years from a daily chart.

You can access the same month in a prior year by using an index of 12. For multiple years ago, multiply by twelve.

I wrote the code below for you to use as an example. It calculates the average return for each month over the last 10 years. Note, the way TOS averaging works, if there's not 10 years of data then you'll get nothing.

Again, This will only work on a monthly chart.
Ruby:
Assert(GetAggregationPeriod() == AggregationPeriod.MONTH, "The `Seasonality` study is designed for monthly charts only");

def return = close / open;
def r = Round(if return > 1 then (return - 1) * 100 else if return < 1 then (1 - return) * -100 else 1, 2);
def factor = 12;
def avg = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;


# display the month-to-date return
AddLabel(yes, "MTD: " + r + "%", Color.LIGHT_GRAY);

def m = GetMonth();

# display the average return for this month
AddLabel(
  yes,
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec") + ": " + Round(avg, 2) + "%",
  Color.LIGHT_GRAY
);

# display the average return for next month
AddLabel(
  yes,
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec") + ": " + Round(avg[-1], 2) + "%",
  Color.LIGHT_GRAY
);
@Slippage....So I used your above code and saved two different scripts, one for 5 years worth of data and one for 10 years (as posted above). I edited the 5 year script to remove years 6-10. The script seems to always show "Dec" no matter what month it is (appears to be the case in the code).

Anyway, I manually calculated the total average for AAPL in December for 5 years and or 10 years. The 5 year average is 1.91% and the 10 year average is -1.28%, however the script returns a 5 year average of 3.31% and a 10 year average of .16%. 5 year is the light gray label and 10 year is the cyan label in below screen shot. The script shows the return for the current "MTD" accurately however (which as of today, 5/9/21) is -1.39%.

CFh3sZg.jpg


I've tried this on both 5 year and 10 year monthly charts and the label values stay constant. The script doesn't seem to be calculating correctly. Any thoughts? Thanks!
 

Slippage

Well-known member
@Slippage....So I used your above code and saved two different scripts, one for 5 years worth of data and one for 10 years (as posted above). I edited the 5 year script to remove years 6-10. The script seems to always show "Dec" no matter what month it is (appears to be the case in the code).

Anyway, I manually calculated the total average for AAPL in December for 5 years and or 10 years. The 5 year average is 1.91% and the 10 year average is -1.28%, however the script returns a 5 year average of 3.31% and a 10 year average of .16%. 5 year is the light gray label and 10 year is the cyan label in below screen shot. The script shows the return for the current "MTD" accurately however (which as of today, 5/9/21) is -1.39%.

CFh3sZg.jpg


I've tried this on both 5 year and 10 year monthly charts and the label values stay constant. The script doesn't seem to be calculating correctly. Any thoughts? Thanks!

Since the script is looking back by specifying an index, the length of time in the chart won't matter. You could set it to just show a couple of bars and it'll still pull data for the 5 or 10 years.

I should have time in the next couple of days to work on debugging this. What I'll probably do, if you decide to work on it sooner, is add labels or maybe a plot to show each of the past r values and see if they're correct for the calendar months expected. If not, then see what months it is matching and adjust as needed.
 

Slippage

Well-known member
@Slippage....So I used your above code and saved two different scripts, one for 5 years worth of data and one for 10 years (as posted above). I edited the 5 year script to remove years 6-10. The script seems to always show "Dec" no matter what month it is (appears to be the case in the code).

Anyway, I manually calculated the total average for AAPL in December for 5 years and or 10 years. The 5 year average is 1.91% and the 10 year average is -1.28%, however the script returns a 5 year average of 3.31% and a 10 year average of .16%. 5 year is the light gray label and 10 year is the cyan label in below screen shot. The script shows the return for the current "MTD" accurately however (which as of today, 5/9/21) is -1.39%.

CFh3sZg.jpg


I've tried this on both 5 year and 10 year monthly charts and the label values stay constant. The script doesn't seem to be calculating correctly. Any thoughts? Thanks!

This new code should fix that. However, in debugging I found the open and close values TOS stores may sometimes have 3 or 4 decimal places so the results may not match your manual calculation exactly but they should be very, very close.

I made it so this single study automatically switches between 5 and 10 yr depending on how much data is available and hides the labels if there's less than 5 years of data. For my own use, I'm slightly considering adding a 3 yr level and if there's not 3 yrs then just showing last year's return.

I left in my debug labels with an input to turn them on and off, defaulted to off.

Ruby:
declare hide_on_intraday;
input debug = no;

DefineGlobalColor("FirstColor", CreateColor(50,200,250));
DefineGlobalColor("SecondColor", CreateColor(50,240,200));

Assert(GetAggregationPeriod() == AggregationPeriod.MONTH,
"The `MonthlySeasonality` study is designed for monthly charts only");

def r = close / open - 1;
def up = close > open;
def factor = 12;

def avg5 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
) / 5;

def avg10 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;

def percentUp5 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
) / 5;

def percentUp10 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
) / 10;

AddLabel(debug,r[factor], Color.CYAN);
AddLabel(debug,r[factor*2], Color.CYAN);
AddLabel(debug,r[factor*3], Color.CYAN);
AddLabel(debug,r[factor*4], Color.CYAN);
AddLabel(debug,r[factor*5], Color.CYAN);
AddLabel(debug,r[factor*6], Color.CYAN);
AddLabel(debug,r[factor*7], Color.CYAN);
AddLabel(debug,r[factor*8], Color.CYAN);
AddLabel(debug,r[factor*9], Color.CYAN);
AddLabel(debug,r[factor*10], Color.CYAN);

AddLabel(debug,close[factor], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*2], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*3], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*4], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*5], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*6], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*7], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*8], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*9], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*10], Color.LIGHT_GRAY);

def m = GetMonth();

# display the month-to-date return
AddLabel(yes, "MTD: " + AsPercent(r), Color.LIGHT_GRAY);

# display the average return for this month
AddLabel(
  !IsNaN(avg5),
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec")
    + " " + (if !isNaN(avg10) then "10" else "5") + "yr"
    + " Average: " + AsPercent(if !isNaN(avg10) then avg10 else avg5)
    + " | Up: " + AsPercent(if !isNaN(percentUp10) then percentUp10 else percentUp5)
  ,
  GlobalColor("FirstColor")
);

# display the average return for next month
AddLabel(
  !IsNaN(avg5),
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec")
    + " " + (if !isNaN(avg10[-1]) then "10" else "5") + "yr"
    + " Average: " + AsPercent(if !isNaN(avg10[-1]) then avg10[-1] else avg5[-1])
    + " | Up: " + AsPercent(if !isNaN(percentUp10[-1]) then percentUp10[-1] else percentUp5[-1])
  ,
  GlobalColor("SecondColor")
);
 
Last edited:

8Nick8

Active member
2019 Donor
VIP
This new code should fix that. However, in debugging I found the open and close values TOS stores may sometimes have 3 or 4 decimal places so the results may not match your manual calculation exactly but they should be very, very close.

I made it so this single study automatically switches between 5 and 10 yr depending on how much data is available and hides the labels if there's less than 5 years of data. For my own use, I'm slightly considering adding a 3 yr level and if there's not 3 yrs then just showing last year's return.

I left in my debug labels with an input to turn them on and off, defaulted to off.

Ruby:
declare hide_on_intraday;
input debug = no;

DefineGlobalColor("FirstColor", CreateColor(50,200,250));
DefineGlobalColor("SecondColor", CreateColor(50,240,200));

Assert(GetAggregationPeriod() == AggregationPeriod.MONTH,
"The `MonthlySeasonality` study is designed for monthly charts only");

def r = close / open - 1;
def up = close > open;
def factor = 12;

def avg5 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
) / 5;

def avg10 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;

def percentUp5 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
) / 5;

def percentUp10 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
) / 10;

AddLabel(debug,r[factor], Color.CYAN);
AddLabel(debug,r[factor*2], Color.CYAN);
AddLabel(debug,r[factor*3], Color.CYAN);
AddLabel(debug,r[factor*4], Color.CYAN);
AddLabel(debug,r[factor*5], Color.CYAN);
AddLabel(debug,r[factor*6], Color.CYAN);
AddLabel(debug,r[factor*7], Color.CYAN);
AddLabel(debug,r[factor*8], Color.CYAN);
AddLabel(debug,r[factor*9], Color.CYAN);
AddLabel(debug,r[factor*10], Color.CYAN);

AddLabel(debug,close[factor], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*2], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*3], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*4], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*5], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*6], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*7], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*8], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*9], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*10], Color.LIGHT_GRAY);

def m = GetMonth();

# display the month-to-date return
AddLabel(yes, "MTD: " + AsPercent(r), Color.LIGHT_GRAY);

# display the average return for this month
AddLabel(
  !IsNaN(avg5),
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec")
    + " " + (if !isNaN(avg10) then "10" else "5") + "yr"
    + " Average: " + AsPercent(if !isNaN(avg10) then avg10 else avg5)
    + " | Up: " + AsPercent(if !isNaN(percentUp10) then percentUp10 else percentUp5)
  ,
  GlobalColor("FirstColor")
);

# display the average return for next month
AddLabel(
  !IsNaN(avg5),
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec")
    + " " + (if !isNaN(avg10[-1]) then "10" else "5") + "yr"
    + " Average: " + AsPercent(if !isNaN(avg10[-1]) then avg10[-1] else avg5[-1])
    + " | Up: " + AsPercent(if !isNaN(percentUp10[-1]) then percentUp10[-1] else percentUp5[-1])
  ,
  GlobalColor("SecondColor")
);

@Slippage Thank you for you contribution and seasonality is one of the ways I am learning how to incorporate them as part of my trading plan. Currently, I am using the data from https://charts.equityclock.com/apple-inc-nasdaqaapl-seasonal-chart-2 to get the seasonal data for the stock on monthly basis. See attached pic below...
hj4ozKn.jpg


I installed your script on my chart AAPL and attempting to compare both pic but realised your data looks back only 10years whereas Equality clock looks back 20year. Like to check if based on your current calculations, will your Monthly Average returns be close to equality clock results ie monthly Average returns if it is changed to 20yrs?

Pp1edP0.jpg


Thanks for your contributions
 

Slippage

Well-known member
@Slippage Thank you for you contribution and seasonality is one of the ways I am learning how to incorporate them as part of my trading plan. Currently, I am using the data from https://charts.equityclock.com/apple-inc-nasdaqaapl-seasonal-chart-2 to get the seasonal data for the stock on monthly basis. See attached pic below...
hj4ozKn.jpg


I installed your script on my chart AAPL and attempting to compare both pic but realised your data looks back only 10years whereas Equality clock looks back 20year. Like to check if based on your current calculations, will your Monthly Average returns be close to equality clock results ie monthly Average returns if it is changed to 20yrs?

Pp1edP0.jpg


Thanks for your contributions

Yeah, the way TOS works the period of the chart won't have any effect on these calculations. That's preferable to me, though, as I'd rather just load a few years in my month chart which takes up a very small portion of my screen.

I added more code so we can compare 20 yr AAPL with the data you posted. The result TOS comes up with is +3.27% for May, up 65% of the time. That's clearly different from the 3.9% that website gives you.

The next logical step is to try to validate the data source. NASDAQ is the exchange AAPL is listed on and is the highest authority for what we should consider accurate open and close prices for AAPL. They make data available here https://www.nasdaq.com/market-activity/stocks/aapl/historical but unfortunately only a rolling 10 years of daily prices. That limits how far back we can validate. The following are the opening prices for the first day of each May and the closing prices from the last day of each May.

OpenCloseReturn
2020​
71.56​
79.49​
11.08%​
2019​
52.7​
43.77​
-16.94%​
2018​
41.6​
46.72​
12.31%​
2017​
36.28​
38.19​
5.26%​
2016​
23.49​
24.97​
6.30%​
2015​
31.53​
32.57​
3.30%​
2014​
22.61​
21.14​
-6.50%​
2013​
15.87​
16.06​
1.20%​
2012​
20.89​
20.63​
-1.24%​
2011​
12.42​

These open and close prices match perfectly with the data TOS is providing except the NASDAQ data is rounded to 2 decimal places while TOS often has 3 or 4.

2021-05-11-23-50-57-AAPL-AAPL-AAPL-Active-Trader-490509867-Main-thinkorswim-build-1969.png


This screenshot displays the values the script is using and the % return results for each of the 20 Mays which are then averaged to get 3.27%. Since the 10 years of data NASDAQ provides matches TOS, I trust the open and close prices. That only leaves my math as yet to be validated. You're welcome to double-check it. The formula I'm using is close / open - 1. In Excel, for the table above, it's =C2/B2-1.

One thing to note is that some of the websites that provide stock data are using free data feeds which are known to be less accurate than sources they would have to pay to get the data. TradingView even warns you about this if you use their free data. It's entirely possible the website you're referencing is wrong.

Here's new code that handles 20, 10, 5, 3, 1 yr, showing you whatever is the longest period for which there is enough data. Yes, it says "1yr Average" in the 1yr case which is dumb but I'm too lazy to fix that small cosmetic issue.

Ruby:
declare hide_on_intraday;
input debug = no;

DefineGlobalColor("FirstColor", CreateColor(50,200,250));
DefineGlobalColor("SecondColor", CreateColor(50,240,200));

Assert(GetAggregationPeriod() == AggregationPeriod.MONTH,
 "The `MonthlySeasonality` study is designed for monthly charts only");

def r = close / open - 1;
def up = close > open;
def factor = 12;

def avg3 = (
  r[factor] + r[factor * 2] + r[factor * 3]
) / 3;

def avg5 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
) / 5;

def avg10 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;

def avg20 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
  + r[factor * 11] + r[factor * 12] + r[factor * 13] + r[factor * 14] + r[factor * 15]
  + r[factor * 16] + r[factor * 17] + r[factor * 18] + r[factor * 19] + r[factor * 20]
) / 20;

def percentUp3 = (
  up[factor] + up[factor * 2] + up[factor * 3]
) / 3;

def percentUp5 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
) / 5;

def percentUp10 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
) / 10;

def percentUp20 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
  + up[factor * 11] + up[factor * 12] + up[factor * 13] + up[factor * 14] + up[factor * 15]
  + up[factor * 16] + up[factor * 17] + up[factor * 18] + up[factor * 19] + up[factor * 20]
) / 20;

AddLabel(debug,close[factor] + " / " + open[factor] + " - 1 = " + r[factor], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*2] + " / " + open[factor*2] + " - 1 = " + r[factor*2], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*3] + " / " + open[factor*3] + " - 1 = " + r[factor*3], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*4] + " / " + open[factor*4] + " - 1 = " + r[factor*4], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*5] + " / " + open[factor*5] + " - 1 = " + r[factor*5], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*6] + " / " + open[factor*6] + " - 1 = " + r[factor*6], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*7] + " / " + open[factor*7] + " - 1 = " + r[factor*7], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*8] + " / " + open[factor*8] + " - 1 = " + r[factor*8], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*9] + " / " + open[factor*9] + " - 1 = " + r[factor*9], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*10] + " / " + open[factor*10] + " - 1 = " + r[factor*10], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*11] + " / " + open[factor*11] + " - 1 = " + r[factor*11], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*12] + " / " + open[factor*12] + " - 1 = " + r[factor*12], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*13] + " / " + open[factor*13] + " - 1 = " + r[factor*13], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*14] + " / " + open[factor*14] + " - 1 = " + r[factor*14], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*15] + " / " + open[factor*15] + " - 1 = " + r[factor*15], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*16] + " / " + open[factor*16] + " - 1 = " + r[factor*16], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*17] + " / " + open[factor*17] + " - 1 = " + r[factor*17], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*18] + " / " + open[factor*18] + " - 1 = " + r[factor*18], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*19] + " / " + open[factor*19] + " - 1 = " + r[factor*19], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*20] + " / " + open[factor*20] + " - 1 = " + r[factor*20], Color.LIGHT_GRAY);

def m = GetMonth();

# display the month-to-date return
AddLabel(yes, "MTD: " + AsPercent(r), Color.LIGHT_GRAY);

# display the average return for this month
AddLabel(
  !IsNaN(r[12]),
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec")
    + " " + (
      if !isNaN(avg20) then "20"
      else if !isNaN(avg10) then "10"
      else if !isNaN(avg5) then "5"
      else if !isNaN(avg3) then "3"
      else "1"
    ) + "yr"
    + " Average: " + AsPercent(
      if !isNaN(avg20) then avg20
      else if !isNaN(avg10) then avg10
      else if !isNaN(avg5) then avg5
      else if !isNaN(avg3) then avg3
      else r[12]
    )
    + " | Up: " + AsPercent(
      if !isNaN(percentUp20) then percentUp20
      else if !isNaN(percentUp10) then percentUp10
      else if !isNaN(percentUp5) then percentUp5
      else if !isNaN(percentUp3) then percentUp3
      else up[12]
    )
  ,
  GlobalColor("FirstColor")
);

# display the average return for next month
AddLabel(
  !IsNaN(r[11]),
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec")
    + " " + (
      if !isNaN(avg20[-1]) then "20"
      else if !isNaN(avg10[-1]) then "10"
      else if !isNaN(avg5[-1]) then "5"
      else if !isNaN(avg3[-1]) then "3"
      else "1"
    ) + "yr"
    + " Average: " + AsPercent(
      if !isNaN(avg20[-1]) then avg20[-1]
      else if !isNaN(avg10[-1]) then avg10[-1]
      else if !isNaN(avg5[-1]) then avg5[-1]
      else if !isNaN(avg3[-1]) then avg3[-1]
      else r[11]
    )
    + " | Up: " + AsPercent(
      if !isNaN(percentUp20[-1]) then percentUp20[-1]
      else if !isNaN(percentUp10[-1]) then percentUp10[-1]
      else if !isNaN(percentUp5[-1]) then percentUp5[-1]
      else if !isNaN(percentUp3[-1]) then percentUp3[-1]
      else up[11]
    )
  ,
  GlobalColor("SecondColor")
);
 

bp805

New member
Yeah, the way TOS works the period of the chart won't have any effect on these calculations. That's preferable to me, though, as I'd rather just load a few years in my month chart which takes up a very small portion of my screen.

I added more code so we can compare 20 yr AAPL with the data you posted. The result TOS comes up with is +3.27% for May, up 65% of the time. That's clearly different from the 3.9% that website gives you.

The next logical step is to try to validate the data source. NASDAQ is the exchange AAPL is listed on and is the highest authority for what we should consider accurate open and close prices for AAPL. They make data available here https://www.nasdaq.com/market-activity/stocks/aapl/historical but unfortunately only a rolling 10 years of daily prices. That limits how far back we can validate. The following are the opening prices for the first day of each May and the closing prices from the last day of each May.

OpenCloseReturn
2020​
71.56​
79.49​
11.08%​
2019​
52.7​
43.77​
-16.94%​
2018​
41.6​
46.72​
12.31%​
2017​
36.28​
38.19​
5.26%​
2016​
23.49​
24.97​
6.30%​
2015​
31.53​
32.57​
3.30%​
2014​
22.61​
21.14​
-6.50%​
2013​
15.87​
16.06​
1.20%​
2012​
20.89​
20.63​
-1.24%​
2011​
12.42​

These open and close prices match perfectly with the data TOS is providing except the NASDAQ data is rounded to 2 decimal places while TOS often has 3 or 4.

2021-05-11-23-50-57-AAPL-AAPL-AAPL-Active-Trader-490509867-Main-thinkorswim-build-1969.png


This screenshot displays the values the script is using and the % return results for each of the 20 Mays which are then averaged to get 3.27%. Since the 10 years of data NASDAQ provides matches TOS, I trust the open and close prices. That only leaves my math as yet to be validated. You're welcome to double-check it. The formula I'm using is close / open - 1. In Excel, for the table above, it's =C2/B2-1.

One thing to note is that some of the websites that provide stock data are using free data feeds which are known to be less accurate than sources they would have to pay to get the data. TradingView even warns you about this if you use their free data. It's entirely possible the website you're referencing is wrong.

Here's new code that handles 20, 10, 5, 3, 1 yr, showing you whatever is the longest period for which there is enough data. Yes, it says "1yr Average" in the 1yr case which is dumb but I'm too lazy to fix that small cosmetic issue.

Ruby:
declare hide_on_intraday;
input debug = no;

DefineGlobalColor("FirstColor", CreateColor(50,200,250));
DefineGlobalColor("SecondColor", CreateColor(50,240,200));

Assert(GetAggregationPeriod() == AggregationPeriod.MONTH,
"The `MonthlySeasonality` study is designed for monthly charts only");

def r = close / open - 1;
def up = close > open;
def factor = 12;

def avg3 = (
  r[factor] + r[factor * 2] + r[factor * 3]
) / 3;

def avg5 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
) / 5;

def avg10 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;

def avg20 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
  + r[factor * 11] + r[factor * 12] + r[factor * 13] + r[factor * 14] + r[factor * 15]
  + r[factor * 16] + r[factor * 17] + r[factor * 18] + r[factor * 19] + r[factor * 20]
) / 20;

def percentUp3 = (
  up[factor] + up[factor * 2] + up[factor * 3]
) / 3;

def percentUp5 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
) / 5;

def percentUp10 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
) / 10;

def percentUp20 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
  + up[factor * 11] + up[factor * 12] + up[factor * 13] + up[factor * 14] + up[factor * 15]
  + up[factor * 16] + up[factor * 17] + up[factor * 18] + up[factor * 19] + up[factor * 20]
) / 20;

AddLabel(debug,close[factor] + " / " + open[factor] + " - 1 = " + r[factor], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*2] + " / " + open[factor*2] + " - 1 = " + r[factor*2], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*3] + " / " + open[factor*3] + " - 1 = " + r[factor*3], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*4] + " / " + open[factor*4] + " - 1 = " + r[factor*4], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*5] + " / " + open[factor*5] + " - 1 = " + r[factor*5], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*6] + " / " + open[factor*6] + " - 1 = " + r[factor*6], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*7] + " / " + open[factor*7] + " - 1 = " + r[factor*7], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*8] + " / " + open[factor*8] + " - 1 = " + r[factor*8], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*9] + " / " + open[factor*9] + " - 1 = " + r[factor*9], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*10] + " / " + open[factor*10] + " - 1 = " + r[factor*10], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*11] + " / " + open[factor*11] + " - 1 = " + r[factor*11], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*12] + " / " + open[factor*12] + " - 1 = " + r[factor*12], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*13] + " / " + open[factor*13] + " - 1 = " + r[factor*13], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*14] + " / " + open[factor*14] + " - 1 = " + r[factor*14], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*15] + " / " + open[factor*15] + " - 1 = " + r[factor*15], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*16] + " / " + open[factor*16] + " - 1 = " + r[factor*16], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*17] + " / " + open[factor*17] + " - 1 = " + r[factor*17], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*18] + " / " + open[factor*18] + " - 1 = " + r[factor*18], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*19] + " / " + open[factor*19] + " - 1 = " + r[factor*19], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*20] + " / " + open[factor*20] + " - 1 = " + r[factor*20], Color.LIGHT_GRAY);

def m = GetMonth();

# display the month-to-date return
AddLabel(yes, "MTD: " + AsPercent(r), Color.LIGHT_GRAY);

# display the average return for this month
AddLabel(
  !IsNaN(r[12]),
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec")
    + " " + (
      if !isNaN(avg20) then "20"
      else if !isNaN(avg10) then "10"
      else if !isNaN(avg5) then "5"
      else if !isNaN(avg3) then "3"
      else "1"
    ) + "yr"
    + " Average: " + AsPercent(
      if !isNaN(avg20) then avg20
      else if !isNaN(avg10) then avg10
      else if !isNaN(avg5) then avg5
      else if !isNaN(avg3) then avg3
      else r[12]
    )
    + " | Up: " + AsPercent(
      if !isNaN(percentUp20) then percentUp20
      else if !isNaN(percentUp10) then percentUp10
      else if !isNaN(percentUp5) then percentUp5
      else if !isNaN(percentUp3) then percentUp3
      else up[12]
    )
  ,
  GlobalColor("FirstColor")
);

# display the average return for next month
AddLabel(
  !IsNaN(r[11]),
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec")
    + " " + (
      if !isNaN(avg20[-1]) then "20"
      else if !isNaN(avg10[-1]) then "10"
      else if !isNaN(avg5[-1]) then "5"
      else if !isNaN(avg3[-1]) then "3"
      else "1"
    ) + "yr"
    + " Average: " + AsPercent(
      if !isNaN(avg20[-1]) then avg20[-1]
      else if !isNaN(avg10[-1]) then avg10[-1]
      else if !isNaN(avg5[-1]) then avg5[-1]
      else if !isNaN(avg3[-1]) then avg3[-1]
      else r[11]
    )
    + " | Up: " + AsPercent(
      if !isNaN(percentUp20[-1]) then percentUp20[-1]
      else if !isNaN(percentUp10[-1]) then percentUp10[-1]
      else if !isNaN(percentUp5[-1]) then percentUp5[-1]
      else if !isNaN(percentUp3[-1]) then percentUp3[-1]
      else up[11]
    )
  ,
  GlobalColor("SecondColor")
);
@Slippage, thanks for putting the work into this and for responding to my other thread with the other code. I ended up using parts of your code here with parts of my code from the other thread to create something that is FINALLY working right! I appreciate the help!
 

bp805

New member
Yeah, the way TOS works the period of the chart won't have any effect on these calculations. That's preferable to me, though, as I'd rather just load a few years in my month chart which takes up a very small portion of my screen.

I added more code so we can compare 20 yr AAPL with the data you posted. The result TOS comes up with is +3.27% for May, up 65% of the time. That's clearly different from the 3.9% that website gives you.

The next logical step is to try to validate the data source. NASDAQ is the exchange AAPL is listed on and is the highest authority for what we should consider accurate open and close prices for AAPL. They make data available here https://www.nasdaq.com/market-activity/stocks/aapl/historical but unfortunately only a rolling 10 years of daily prices. That limits how far back we can validate. The following are the opening prices for the first day of each May and the closing prices from the last day of each May.

OpenCloseReturn
2020​
71.56​
79.49​
11.08%​
2019​
52.7​
43.77​
-16.94%​
2018​
41.6​
46.72​
12.31%​
2017​
36.28​
38.19​
5.26%​
2016​
23.49​
24.97​
6.30%​
2015​
31.53​
32.57​
3.30%​
2014​
22.61​
21.14​
-6.50%​
2013​
15.87​
16.06​
1.20%​
2012​
20.89​
20.63​
-1.24%​
2011​
12.42​

These open and close prices match perfectly with the data TOS is providing except the NASDAQ data is rounded to 2 decimal places while TOS often has 3 or 4.

2021-05-11-23-50-57-AAPL-AAPL-AAPL-Active-Trader-490509867-Main-thinkorswim-build-1969.png


This screenshot displays the values the script is using and the % return results for each of the 20 Mays which are then averaged to get 3.27%. Since the 10 years of data NASDAQ provides matches TOS, I trust the open and close prices. That only leaves my math as yet to be validated. You're welcome to double-check it. The formula I'm using is close / open - 1. In Excel, for the table above, it's =C2/B2-1.

One thing to note is that some of the websites that provide stock data are using free data feeds which are known to be less accurate than sources they would have to pay to get the data. TradingView even warns you about this if you use their free data. It's entirely possible the website you're referencing is wrong.

Here's new code that handles 20, 10, 5, 3, 1 yr, showing you whatever is the longest period for which there is enough data. Yes, it says "1yr Average" in the 1yr case which is dumb but I'm too lazy to fix that small cosmetic issue.

Ruby:
declare hide_on_intraday;
input debug = no;

DefineGlobalColor("FirstColor", CreateColor(50,200,250));
DefineGlobalColor("SecondColor", CreateColor(50,240,200));

Assert(GetAggregationPeriod() == AggregationPeriod.MONTH,
"The `MonthlySeasonality` study is designed for monthly charts only");

def r = close / open - 1;
def up = close > open;
def factor = 12;

def avg3 = (
  r[factor] + r[factor * 2] + r[factor * 3]
) / 3;

def avg5 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
) / 5;

def avg10 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
) / 10;

def avg20 = (
  r[factor] + r[factor * 2] + r[factor * 3] + r[factor * 4] + r[factor * 5]
  + r[factor * 6] + r[factor * 7] + r[factor * 8] + r[factor * 9] + r[factor * 10]
  + r[factor * 11] + r[factor * 12] + r[factor * 13] + r[factor * 14] + r[factor * 15]
  + r[factor * 16] + r[factor * 17] + r[factor * 18] + r[factor * 19] + r[factor * 20]
) / 20;

def percentUp3 = (
  up[factor] + up[factor * 2] + up[factor * 3]
) / 3;

def percentUp5 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
) / 5;

def percentUp10 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
) / 10;

def percentUp20 = (
  up[factor] + up[factor * 2] + up[factor * 3] + up[factor * 4] + up[factor * 5]
  + up[factor * 6] + up[factor * 7] + up[factor * 8] + up[factor * 9] + up[factor * 10]
  + up[factor * 11] + up[factor * 12] + up[factor * 13] + up[factor * 14] + up[factor * 15]
  + up[factor * 16] + up[factor * 17] + up[factor * 18] + up[factor * 19] + up[factor * 20]
) / 20;

AddLabel(debug,close[factor] + " / " + open[factor] + " - 1 = " + r[factor], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*2] + " / " + open[factor*2] + " - 1 = " + r[factor*2], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*3] + " / " + open[factor*3] + " - 1 = " + r[factor*3], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*4] + " / " + open[factor*4] + " - 1 = " + r[factor*4], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*5] + " / " + open[factor*5] + " - 1 = " + r[factor*5], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*6] + " / " + open[factor*6] + " - 1 = " + r[factor*6], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*7] + " / " + open[factor*7] + " - 1 = " + r[factor*7], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*8] + " / " + open[factor*8] + " - 1 = " + r[factor*8], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*9] + " / " + open[factor*9] + " - 1 = " + r[factor*9], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*10] + " / " + open[factor*10] + " - 1 = " + r[factor*10], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*11] + " / " + open[factor*11] + " - 1 = " + r[factor*11], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*12] + " / " + open[factor*12] + " - 1 = " + r[factor*12], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*13] + " / " + open[factor*13] + " - 1 = " + r[factor*13], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*14] + " / " + open[factor*14] + " - 1 = " + r[factor*14], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*15] + " / " + open[factor*15] + " - 1 = " + r[factor*15], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*16] + " / " + open[factor*16] + " - 1 = " + r[factor*16], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*17] + " / " + open[factor*17] + " - 1 = " + r[factor*17], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*18] + " / " + open[factor*18] + " - 1 = " + r[factor*18], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*19] + " / " + open[factor*19] + " - 1 = " + r[factor*19], Color.LIGHT_GRAY);
AddLabel(debug,close[factor*20] + " / " + open[factor*20] + " - 1 = " + r[factor*20], Color.LIGHT_GRAY);

def m = GetMonth();

# display the month-to-date return
AddLabel(yes, "MTD: " + AsPercent(r), Color.LIGHT_GRAY);

# display the average return for this month
AddLabel(
  !IsNaN(r[12]),
  (if m == 1 then "Jan"
    else if m == 2 then "Feb"
    else if m == 3 then "Mar"
    else if m == 4 then "Apr"
    else if m == 5 then "May"
    else if m == 6 then "Jun"
    else if m == 7 then "Jul"
    else if m == 8 then "Aug"
    else if m == 9 then "Sep"
    else if m == 10 then "Oct"
    else if m == 11 then "Nov"
    else "Dec")
    + " " + (
      if !isNaN(avg20) then "20"
      else if !isNaN(avg10) then "10"
      else if !isNaN(avg5) then "5"
      else if !isNaN(avg3) then "3"
      else "1"
    ) + "yr"
    + " Average: " + AsPercent(
      if !isNaN(avg20) then avg20
      else if !isNaN(avg10) then avg10
      else if !isNaN(avg5) then avg5
      else if !isNaN(avg3) then avg3
      else r[12]
    )
    + " | Up: " + AsPercent(
      if !isNaN(percentUp20) then percentUp20
      else if !isNaN(percentUp10) then percentUp10
      else if !isNaN(percentUp5) then percentUp5
      else if !isNaN(percentUp3) then percentUp3
      else up[12]
    )
  ,
  GlobalColor("FirstColor")
);

# display the average return for next month
AddLabel(
  !IsNaN(r[11]),
  (if m[-1] == 1 then "Jan"
    else if m[-1] == 2 then "Feb"
    else if m[-1] == 3 then "Mar"
    else if m[-1] == 4 then "Apr"
    else if m[-1] == 5 then "May"
    else if m[-1] == 6 then "Jun"
    else if m[-1] == 7 then "Jul"
    else if m[-1] == 8 then "Aug"
    else if m[-1] == 9 then "Sep"
    else if m[-1] == 10 then "Oct"
    else if m[-1] == 11 then "Nov"
    else "Dec")
    + " " + (
      if !isNaN(avg20[-1]) then "20"
      else if !isNaN(avg10[-1]) then "10"
      else if !isNaN(avg5[-1]) then "5"
      else if !isNaN(avg3[-1]) then "3"
      else "1"
    ) + "yr"
    + " Average: " + AsPercent(
      if !isNaN(avg20[-1]) then avg20[-1]
      else if !isNaN(avg10[-1]) then avg10[-1]
      else if !isNaN(avg5[-1]) then avg5[-1]
      else if !isNaN(avg3[-1]) then avg3[-1]
      else r[11]
    )
    + " | Up: " + AsPercent(
      if !isNaN(percentUp20[-1]) then percentUp20[-1]
      else if !isNaN(percentUp10[-1]) then percentUp10[-1]
      else if !isNaN(percentUp5[-1]) then percentUp5[-1]
      else if !isNaN(percentUp3[-1]) then percentUp3[-1]
      else up[11]
    )
  ,
  GlobalColor("SecondColor")
);
I've also noticed that when looking at the seasonality charts function on stockcharts.com, that data did not match that of the TOS study I used that I validated manually. I agree that some of these websites may not be showing accurate data.
 

Similar threads

Top