ES Futures Quasi-Algo 1 Hour Out Prediction for ThinkorSwim

mashume

Well-known member
VIP
So, from the data described here:
https://usethinkscript.com/threads/es-futures-probability-at-time-market-timing-differently.6250/
I decided to build an indicator to see what would happen. This indicator is the result of that.

It may or may not be mathematically correct. If you'd like to audit my statistics, shifts, and so forth, please do.

Remember, the bounding boxes are being drawn a minimum of 1 hour before the candles are drawn. They are real predictions, based on probable movements of the market as described in the link above. These use 1st and 3rd quartile deviances from median for the range shown (for those who care).

lkyaxgz.png

Overnight projections.

pzcwUfa.png

Showing regular trading day projections.

T2w8wfw.png

This one shows the predictions in the expansion area on the right.

These are not overly accurate, but an interesting direction in indicators.

I have written a python script to "regenerate" the indicator code so I can run it weekly to update the coefficients if there is interest.

Here's the code for the indicator:
Code:
#########################################################
#
#   Next Hour ES Trading Range
#     Algorithmic Prediction
#   Values Derived on Data from
#          2021-01-12 to
#          2021-04-08
#
#   @mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version /ES (and maybe /MES) only
#  Functional on 1, 5, 10, 15, 20, 30, 60 minute charts
#
#########################################################

declare upper;

def Y = 31556926;
def M = 2629743;
def D = 86400;
def H = 3600;
def HalfHour = 1800;
def epoch = (getTime() / 1000);
def YMD = (epoch % Y) - (epoch / Y);
def month = (Floor(YMD / M) + 1);
def GMT = Floor((epoch % D) / H);
def HOUR = if GMT > 4 then GMT - 4 else if GMT < 4 then (GMT + 24) - 4 else 0;

def tf = getAggregationPeriod();

def barsPerHour = if tf == AggregationPeriod.HOUR then 1
    else if tf == AggregationPeriod.THIRTY_MIN then 2
    else if tf == AggregationPeriod.TWENTY_MIN then 3
    else if tf == AggregationPeriod.FIFTEEN_MIN then 4
    else if tf == AggregationPeriod.TEN_MIN then 6
    else if tf == AggregationPeriod.FIVE_MIN then 12
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;

def q1 =
    if HOUR == 0 then -2.25
    else if HOUR == 1 then -3.5
    else if HOUR == 2 then -3.25
    else if HOUR == 3 then -3.5
    else if HOUR == 4 then -2.0
    else if HOUR == 5 then -2.5
    else if HOUR == 6 then -2.0
    else if HOUR == 7 then -4.0
    else if HOUR == 8 then -3.75
    else if HOUR == 9 then -6.25
    else if HOUR == 10 then -4.5
    else if HOUR == 11 then -3.0
    else if HOUR == 12 then -2.812
    else if HOUR == 13 then -3.75
    else if HOUR == 14 then -6.75
    else if HOUR == 15 then -5.75
    else if HOUR == 16 then -1.75
    else if HOUR == 17 then 1.0
    else if HOUR == 18 then -3.5
    else if HOUR == 19 then -3.25
    else if HOUR == 20 then -3.5
    else if HOUR == 21 then -3.5
    else if HOUR == 22 then -2.0
    else -1.25;
def q3 =
    if HOUR == 0 then 2.25
    else if HOUR == 1 then 3.0
    else if HOUR == 2 then 3.75
    else if HOUR == 3 then 4.25
    else if HOUR == 4 then 2.75
    else if HOUR == 5 then 3.25
    else if HOUR == 6 then 3.75
    else if HOUR == 7 then 3.0
    else if HOUR == 8 then 5.312
    else if HOUR == 9 then 8.75
    else if HOUR == 10 then 7.75
    else if HOUR == 11 then 7.0
    else if HOUR == 12 then 5.5
    else if HOUR == 13 then 5.25
    else if HOUR == 14 then 6.562
    else if HOUR == 15 then 6.75
    else if HOUR == 16 then 4.0
    else if HOUR == 17 then 6.25
    else if HOUR == 18 then 3.25
    else if HOUR == 19 then 3.5
    else if HOUR == 20 then 3.75
    else if HOUR == 21 then 2.5
    else if HOUR == 22 then 2.25
    else 2.5;
def m2 =
    if HOUR == 0 then 0.0
    else if HOUR == 1 then -0.5
    else if HOUR == 2 then 0.25
    else if HOUR == 3 then 0.25
    else if HOUR == 4 then 0.25
    else if HOUR == 5 then 0.5
    else if HOUR == 6 then 0.5
    else if HOUR == 7 then -0.25
    else if HOUR == 8 then 0.5
    else if HOUR == 9 then 2.0
    else if HOUR == 10 then 2.75
    else if HOUR == 11 then 2.5
    else if HOUR == 12 then 1.5
    else if HOUR == 13 then 1.0
    else if HOUR == 14 then -0.5
    else if HOUR == 15 then 0.75
    else if HOUR == 16 then 1.0
    else if HOUR == 17 then 2.5
    else if HOUR == 18 then -0.25
    else if HOUR == 19 then 0.5
    else if HOUR == 20 then 0.25
    else if HOUR == 21 then -0.75
    else if HOUR == 22 then 0.5
    else 0.25;

def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + m2;
def upper = median + (q3);
def lower = median + (q1);

plot c = midline;
c.setStyle(CURve.SHORT_DASH);
c.setDefaultColor(getColor(7));

plot median_line = median[barsPerHour];
median_line.SetPaintingStrategy(PaintingStrategy.DASHES);
median_line.SetDefaultColor(getColor(3));
plot expected_upper = upper[barsPerHour];
expected_upper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_upper.SetDefaultColor(getColor(1));
plot expected_lower = lower[barsPerHour];
expected_lower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_lower.SetDefaultColor(getColor(5));

addcloud(expected_upper, expected_lower, color.white, color.white);
def upside = (expected_upper[(-1 * barsPerHour)] - close);
def downside = (close - expected_lower[(-1 * barsPerHour)]);
addLabel(yes, "current upside: " + upside + "  current downside: " + downside, if upside > downside then color.dark_green else if downside > upside then color.dark_red else color.dark_gray);

If you find this useful, let me know. This could, potentially, be applied to any ticker, though it would need to be for a single ticker. If you trade exclusively one symbol, it could be an interesting exercise.

REMEMBER This is just probabilities applied to prices. It's not magic, and it's not always going to be correct.

Happy Trading,
mashume
 
Last edited:

MerryDay

Administrative
Staff member
Staff
VIP
Hehehehe, @mashume, editing my professors was one of my favorite past times. I seldom caught a mistake but it is fun, trying.
I look forward to checking this out. Thank you for all your contributions.
 
Last edited:

Topas

Member
VIP
Looks very interesting to me ... Lets load it up and spin it ... great contribution to the community ... thank you
 

mashume

Well-known member
VIP
@mashume Thank you for the script, looks interesting.

Would it work correctly on /RTY, 15 minutes?
It will not, not the version above at any rate... the coefficients are derived from a statistical analysis of /es data.

This one is for RTY:
Code:
#########################################################
#
#   Next Hour RTY Trading Range
#     Algorithmic Prediction
#   Values Derived on Data from
#          2021-02-02 to
#          2021-04-14
#
#   @mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version RTY only
#  Functional on 1, 5, 10, 15, 20, 30, 60 minute charts
#
#########################################################

declare upper;

def Y = 31556926;
def M = 2629743;
def D = 86400;
def H = 3600;
def HalfHour = 1800;
def epoch = (getTime() / 1000);
def YMD = (epoch % Y) - (epoch / Y);
def month = (Floor(YMD / M) + 1);
def GMT = Floor((epoch % D) / H);
def HOUR = if GMT > 4 then GMT - 4 else if GMT < 4 then (GMT + 24) - 4 else 0;

def tf = getAggregationPeriod();

def barsPerHour = if tf == AggregationPeriod.HOUR then 1
    else if tf == AggregationPeriod.THIRTY_MIN then 2
    else if tf == AggregationPeriod.TWENTY_MIN then 3
    else if tf == AggregationPeriod.FIFTEEN_MIN then 4
    else if tf == AggregationPeriod.TEN_MIN then 6
    else if tf == AggregationPeriod.FIVE_MIN then 12
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;
 

def q1 =
    if HOUR == 0 then -1.7
    else if HOUR == 1 then -2.425
    else if HOUR == 2 then -2.025
    else if HOUR == 3 then -3.4
    else if HOUR == 4 then -1.7
    else if HOUR == 5 then -2.9
    else if HOUR == 6 then -2.0
    else if HOUR == 7 then -3.5
    else if HOUR == 8 then -4.525
    else if HOUR == 9 then -11.825
    else if HOUR == 10 then -6.8
    else if HOUR == 11 then -4.625
    else if HOUR == 12 then -4.9
    else if HOUR == 13 then -4.9
    else if HOUR == 14 then -5.125
    else if HOUR == 15 then -4.025
    else if HOUR == 16 then -2.0
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then -2.9
    else if HOUR == 19 then -2.8
    else if HOUR == 20 then -3.2
    else if HOUR == 21 then -3.6
    else if HOUR == 22 then -1.9
    else -1.6;
def q3 =
    if HOUR == 0 then 1.8
    else if HOUR == 1 then 2.3
    else if HOUR == 2 then 3.4
    else if HOUR == 3 then 2.8
    else if HOUR == 4 then 2.7
    else if HOUR == 5 then 2.4
    else if HOUR == 6 then 4.8
    else if HOUR == 7 then 3.6
    else if HOUR == 8 then 5.65
    else if HOUR == 9 then 9.0
    else if HOUR == 10 then 10.6
    else if HOUR == 11 then 6.9
    else if HOUR == 12 then 5.425
    else if HOUR == 13 then 4.525
    else if HOUR == 14 then 6.425
    else if HOUR == 15 then 7.5
    else if HOUR == 16 then 3.725
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 2.45
    else if HOUR == 19 then 2.3
    else if HOUR == 20 then 2.25
    else if HOUR == 21 then 2.2
    else if HOUR == 22 then 2.0
    else 2.0;
def m2 =
    if HOUR == 0 then -0.2
    else if HOUR == 1 then -0.25
    else if HOUR == 2 then 0.6
    else if HOUR == 3 then 0.2
    else if HOUR == 4 then 0.55
    else if HOUR == 5 then -0.1
    else if HOUR == 6 then 1.5
    else if HOUR == 7 then 0.3
    else if HOUR == 8 then 1.2
    else if HOUR == 9 then -1.7
    else if HOUR == 10 then 2.6
    else if HOUR == 11 then 1.4
    else if HOUR == 12 then 0.1
    else if HOUR == 13 then 0.3
    else if HOUR == 14 then 1.0
    else if HOUR == 15 then 1.95
    else if HOUR == 16 then 0.7
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then -0.4
    else if HOUR == 19 then -0.2
    else if HOUR == 20 then -0.4
    else if HOUR == 21 then -0.8
    else if HOUR == 22 then 0.2
    else 0.1;

def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + m2;
def upper = median + (q3);
def lower = median + (q1);

plot c = midline;
c.setStyle(CURve.SHORT_DASH);
c.setDefaultColor(getColor(7));

plot median_line = median[barsPerHour];
median_line.SetPaintingStrategy(PaintingStrategy.DASHES);
median_line.SetDefaultColor(getColor(3));
plot expected_upper = upper[barsPerHour];
expected_upper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_upper.SetDefaultColor(getColor(1));
plot expected_lower = lower[barsPerHour];
expected_lower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_lower.SetDefaultColor(getColor(5));

addcloud(expected_upper, expected_lower, color.white, color.white);
def upside = (expected_upper[(-1 * barsPerHour)] - close);
def downside = (close - expected_lower[(-1 * barsPerHour)]);
addLabel(yes, "current upside: " + upside + "  current downside: " + downside, if upside > downside then color.dark_green else if downside > upside then color.dark_red else color.dark_gray);

Let me know how it works out for you,

Happy Trading,
mashume
 
Last edited:

mashume

Well-known member
VIP
Hehehehe, @mashume, editing my professors was one of my favorite past times. I seldom caught a mistake but it is fun, trying.
I look forward to checking this out. I am in the process of sorting through a lifetime of 'stuff' and moving a couple of thousand miles.
Once I have my trading station up, I will take it for a spin. Thank you for all your contributions.
Good luck with the move!
 

john3

Active member
2019 Donor
@mashume Thank you.

Question: Just to double-check, does it adjust automatically and correctly if I switch to a different time frame, say, 30 minutes?
In the original post, you've mentioned a weekly update if there's interest...does it mean that the values in the code are not dynamically updated and are hardcoded?
 

mashume

Well-known member
VIP
@john3 You're quite welcome.

Answer: This does automatically correct if you switch to any of the listed time frames (1, 5, 10, 15, 20, 30, 60 minutes). It requires a secondary aggregation of 1 hour, and so won't work above 1 hour I believe. It is not, currently, able to work on 2, 3, or 4 minute charts, or on custom times, nor on tick charts (it is time based after all)

As for updates. The coefficient values are hard coded into the indicator. I have not come up with any way to aggregate the same way in ToS that I can in python (where I look at 1 hour p/l and then take statistics based on those p/l numbers aggregated by hour-of-day over the last 60 days.

I did however, write a python script that takes a ticker in and gives back a fully functional cut-and-paste indicator so I don't really do much work when / if people would like custom tickers (or custom p/l time projections for that matter... this is based on 1 hour, but could as easily be based on 2 hours, 30 minutes, or whatever I suppose -- my original post on statistics and time p/l probabilities is linked somewhere above).

Hope that answers some of your questions. If this made you think of more questions, just ask. :)

happy trading,
mashume
 

vro3

Member
Haven't downloaded yet - but - would this apply to SPY too?! or need seperate code? (knowing I can look at the two and compare, at worst)
 

mashume

Well-known member
VIP
Haven't downloaded yet - but - would this apply to SPY too?! or need seperate code? (knowing I can look at the two and compare, at worst)
SPY does not trade around the clock so the data may be different, certainly the prices would be different and ES trades in 1/4 point ticks while SPY is 1/100 I think and then there's the fact that the prices are about an order of magnitude apart :) You can compare the two, but I can look into creating a version of this for SPY if you can't run ES and SPY side by side.

-mashume
 

vro3

Member
SPY does not trade around the clock so the data may be different, certainly the prices would be different and ES trades in 1/4 point ticks while SPY is 1/100 I think and then there's the fact that the prices are about an order of magnitude apart :) You can compare the two, but I can look into creating a version of this for SPY if you can't run ES and SPY side by side.

-mashume
that makes sense. I'm not futures approved, so I can only trade spy during the day - no rush. ill watch this for bit! Thanks for the fast reply!
 

mashume

Well-known member
VIP
that makes sense. I'm not futures approved, so I can only trade spy during the day - no rush. ill watch this for bit! Thanks for the fast reply!
@vro3,
Here ya go. No idea how this will look... I didn't throw it into thinkorswim tonight, just ran the generator and this is what it gave me. Let me know what works and what's broken. Thanks

Code:
#########################################################
#
#   Next Hour SPY Trading Range
#     Algorithmic Future Range Probability
#   Values Derived on Data from
#          2021-01-19 to
#          2021-04-14
#
#   @mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version SPY only
#  Functional on 1, 5, 10, 15, 20, 30, 60 minute charts
#
#########################################################

declare upper;

def Y = 31556926;
def M = 2629743;
def D = 86400;
def H = 3600;
def HalfHour = 1800;
def epoch = (getTime() / 1000);
def YMD = (epoch % Y) - (epoch / Y);
def month = (Floor(YMD / M) + 1);
def GMT = Floor((epoch % D) / H);
def HOUR = if GMT > 4 then GMT - 4 else if GMT < 4 then (GMT + 24) - 4 else 0;

def tf = getAggregationPeriod();

def barsPerHour = if tf == AggregationPeriod.HOUR then 1
    else if tf == AggregationPeriod.THIRTY_MIN then 2
    else if tf == AggregationPeriod.TWENTY_MIN then 3
    else if tf == AggregationPeriod.FIFTEEN_MIN then 4
    else if tf == AggregationPeriod.TEN_MIN then 6
    else if tf == AggregationPeriod.FIVE_MIN then 12
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;
    

def q1 =
    if HOUR == 0 then 0.0
    else if HOUR == 1 then 0.0
    else if HOUR == 2 then 0.0
    else if HOUR == 3 then 0.0
    else if HOUR == 4 then -0.2
    else if HOUR == 5 then -0.23
    else if HOUR == 6 then -0.23
    else if HOUR == 7 then -0.37
    else if HOUR == 8 then -0.5
    else if HOUR == 9 then -0.51
    else if HOUR == 10 then -0.45
    else if HOUR == 11 then -0.23
    else if HOUR == 12 then -0.24
    else if HOUR == 13 then -0.381
    else if HOUR == 14 then -0.641
    else if HOUR == 15 then -0.706
    else if HOUR == 16 then -0.12
    else if HOUR == 17 then -0.17
    else if HOUR == 18 then -0.423
    else if HOUR == 19 then -0.675
    else if HOUR == 20 then 0.0
    else if HOUR == 21 then 0.0
    else if HOUR == 22 then 0.0
    else 0.0;
def q3 =
    if HOUR == 0 then 0.0
    else if HOUR == 1 then 0.0
    else if HOUR == 2 then 0.0
    else if HOUR == 3 then 0.0
    else if HOUR == 4 then 0.29
    else if HOUR == 5 then 0.3
    else if HOUR == 6 then 0.36
    else if HOUR == 7 then 0.3
    else if HOUR == 8 then 0.76
    else if HOUR == 9 then 0.92
    else if HOUR == 10 then 0.76
    else if HOUR == 11 then 0.74
    else if HOUR == 12 then 0.546
    else if HOUR == 13 then 0.49
    else if HOUR == 14 then 0.536
    else if HOUR == 15 then 0.529
    else if HOUR == 16 then 0.16
    else if HOUR == 17 then 0.25
    else if HOUR == 18 then 0.65
    else if HOUR == 19 then 0.517
    else if HOUR == 20 then 0.0
    else if HOUR == 21 then 0.0
    else if HOUR == 22 then 0.0
    else 0.0;
def m2 =
    if HOUR == 0 then 0.0
    else if HOUR == 1 then 0.0
    else if HOUR == 2 then 0.0
    else if HOUR == 3 then 0.0
    else if HOUR == 4 then 0.03
    else if HOUR == 5 then 0.05
    else if HOUR == 6 then 0.06
    else if HOUR == 7 then -0.01
    else if HOUR == 8 then 0.142
    else if HOUR == 9 then 0.19
    else if HOUR == 10 then 0.202
    else if HOUR == 11 then 0.29
    else if HOUR == 12 then 0.173
    else if HOUR == 13 then 0.07
    else if HOUR == 14 then -0.053
    else if HOUR == 15 then -0.08
    else if HOUR == 16 then 0.02
    else if HOUR == 17 then -0.005
    else if HOUR == 18 then 0.01
    else if HOUR == 19 then -0.14
    else if HOUR == 20 then 0.0
    else if HOUR == 21 then 0.0
    else if HOUR == 22 then 0.0
    else 0.0;

def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + m2;
def upper = median + (q3);
def lower = median + (q1);

plot c = midline;
c.setStyle(CURve.SHORT_DASH);
c.setDefaultColor(getColor(7));

plot median_line = median[barsPerHour];
median_line.SetPaintingStrategy(PaintingStrategy.DASHES);
median_line.SetDefaultColor(getColor(3));
plot expected_upper = upper[barsPerHour];
expected_upper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_upper.SetDefaultColor(getColor(1));
plot expected_lower = lower[barsPerHour];
expected_lower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_lower.SetDefaultColor(getColor(5));

addcloud(expected_upper, expected_lower, color.white, color.white);
def upside = (expected_upper[(-1 * barsPerHour)] - close);
def downside = (close - expected_lower[(-1 * barsPerHour)]);
addLabel(yes, "current upside: " + upside + "  current downside: " + downside, if upside > downside then color.dark_green else if downside > upside then color.dark_red else color.dark_gray);

happy trading,

-mashume
 

mashume

Well-known member
VIP
@mashume can we use this on NQ?
Here's a fresh version for you for /NQ. Now also works on 3 minute charts.

Code:
#########################################################
#
#   Next Hour NQ Trading Range
#     Algorithmic Prediction
#   Values Derived on Data from
#          2021-02-03 to
#          2021-04-15
#
#   @mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version /NQ (and maybe /MNQ) only
#  Functional on 1, 3, 5, 10, 15, 20, 30, 60 minute charts
#
#########################################################

declare upper;

def Y = 31556926;
def M = 2629743;
def D = 86400;
def H = 3600;
def HalfHour = 1800;
def epoch = (getTime() / 1000);
def YMD = (epoch % Y) - (epoch / Y);
def month = (Floor(YMD / M) + 1);
def GMT = Floor((epoch % D) / H);
def HOUR = if GMT > 4 then GMT - 4 else if GMT < 4 then (GMT + 24) - 4 else 0;

def tf = getAggregationPeriod();

def barsPerHour = if tf == AggregationPeriod.HOUR then 1
    else if tf == AggregationPeriod.THIRTY_MIN then 2
    else if tf == AggregationPeriod.TWENTY_MIN then 3
    else if tf == AggregationPeriod.FIFTEEN_MIN then 4
    else if tf == AggregationPeriod.TEN_MIN then 6
    else if tf == AggregationPeriod.FIVE_MIN then 12
    else if tf == AggregationPeriod.THREE_MIN then 20
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;
    

def q1 =
    if HOUR == 0 then -10.25
    else if HOUR == 1 then -12.75
    else if HOUR == 2 then -16.062
    else if HOUR == 3 then -17.5
    else if HOUR == 4 then -9.0
    else if HOUR == 5 then -13.25
    else if HOUR == 6 then -10.75
    else if HOUR == 7 then -17.75
    else if HOUR == 8 then -26.75
    else if HOUR == 9 then -41.0
    else if HOUR == 10 then -28.188
    else if HOUR == 11 then -20.25
    else if HOUR == 12 then -16.75
    else if HOUR == 13 then -24.625
    else if HOUR == 14 then -26.375
    else if HOUR == 15 then -21.5
    else if HOUR == 16 then -5.75
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then -14.0
    else if HOUR == 19 then -11.25
    else if HOUR == 20 then -16.562
    else if HOUR == 21 then -15.75
    else if HOUR == 22 then -8.75
    else -8.375;
def q3 =
    if HOUR == 0 then 11.25
    else if HOUR == 1 then 18.625
    else if HOUR == 2 then 21.062
    else if HOUR == 3 then 18.25
    else if HOUR == 4 then 14.75
    else if HOUR == 5 then 15.0
    else if HOUR == 6 then 16.562
    else if HOUR == 7 then 16.75
    else if HOUR == 8 then 25.25
    else if HOUR == 9 then 42.0
    else if HOUR == 10 then 37.875
    else if HOUR == 11 then 33.5
    else if HOUR == 12 then 26.312
    else if HOUR == 13 then 21.062
    else if HOUR == 14 then 33.75
    else if HOUR == 15 then 27.812
    else if HOUR == 16 then 16.0
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 13.75
    else if HOUR == 19 then 16.5
    else if HOUR == 20 then 18.562
    else if HOUR == 21 then 12.938
    else if HOUR == 22 then 8.25
    else 8.75;
def m2 =
    if HOUR == 0 then 0.75
    else if HOUR == 1 then -1.25
    else if HOUR == 2 then 0.75
    else if HOUR == 3 then -1.375
    else if HOUR == 4 then 2.0
    else if HOUR == 5 then -0.625
    else if HOUR == 6 then 3.75
    else if HOUR == 7 then 0.5
    else if HOUR == 8 then 0.0
    else if HOUR == 9 then 2.25
    else if HOUR == 10 then 7.5
    else if HOUR == 11 then 8.25
    else if HOUR == 12 then 5.5
    else if HOUR == 13 then 0.25
    else if HOUR == 14 then 2.75
    else if HOUR == 15 then 3.75
    else if HOUR == 16 then 4.5
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then -2.75
    else if HOUR == 19 then 0.625
    else if HOUR == 20 then 0.25
    else if HOUR == 21 then -2.375
    else if HOUR == 22 then 0.5
    else 2.5;

def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + m2;
def upper = median + (q3);
def lower = median + (q1);

plot c = midline;
c.setStyle(CURve.SHORT_DASH);
c.setDefaultColor(getColor(7));

plot median_line = median[barsPerHour];
median_line.SetPaintingStrategy(PaintingStrategy.DASHES);
median_line.SetDefaultColor(getColor(3));
plot expected_upper = upper[barsPerHour];
expected_upper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_upper.SetDefaultColor(getColor(1));
plot expected_lower = lower[barsPerHour];
expected_lower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_lower.SetDefaultColor(getColor(5));

addcloud(expected_upper, expected_lower, color.white, color.white);
def upside = (expected_upper[(-1 * barsPerHour)] - close);
def downside = (close - expected_lower[(-1 * barsPerHour)]);
addLabel(yes, "current upside: " + upside + "  current downside: " + downside, if upside > downside then color.dark_green else if downside > upside then color.dark_red else color.dark_gray);

As always, feedback is appreciated

Happy Trading,
-mashume
 

john3

Active member
2019 Donor
@mashume I'm not 100% clear on an update question. Can the RTY script be used going forward without any updates, or does it require an update after a certain period? The median plot, what exactly is it based on? Is it based on an hourly candle, 60 days or 60 hourly candles?

Appreciate your help.
 

mashume

Well-known member
VIP
@mashume I'm not 100% clear on an update question. Can the RTY script be used going forward without any updates, or does it require an update after a certain period? The median plot, what exactly is it based on? Is it based on an hourly candle, 60 days or 60 hourly candles?

Appreciate your help.
You can use it as long as you like, however, if the market changes behaviour drastically (seasonally, etc...) the probability will not match the coded values very well. Time drift.

The calculation goes like this:
From historical data (going back 60 days for now)
1. take the close for every time t (at 5 minute intervals), get the close price at t + 1 hour and calculate the difference.
2. aggregate that data for each integer hour of the day, so that all the differences for trades opened in the 9 o'clock hour are aggregated
3. run some statistics on that data and find:
- median
- 3rd quartile
- 1st quartile
4. take the average price for this hour (HL2, aggregated by hour)
5. create 3 lines by adding median, 3q, and 1q to the price in step 4
6. shift those lines 1 hour into the future.

Hope that helps.
-mashume
 

mashume

Well-known member
VIP
Updated the indicator to include a "distance to the median" line label. Compares the current close to the projected median. If you're below the median, the theory goes, the median may pull you up. if you're above the next median, the median may pull you down.

PS I did not update the first post with this script, as the coefficients have changed with time and new data. the version for any of these studies is to look at the date range in the header.

-mashume
Code:
#########################################################
#
#   Next Hour ES Trading Range
#     Algorithmic Prediction
#   Values Derived on Data from
#          2021-02-03 to
#          2021-04-15
#
#   @mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version /ES (and maybe /MES) only
#  Functional on 1, 3, 5, 10, 15, 20, 30, 60 minute charts
#
#########################################################

declare upper;

def Y = 31556926;
def M = 2629743;
def D = 86400;
def H = 3600;
def HalfHour = 1800;
def epoch = (getTime() / 1000);
def YMD = (epoch % Y) - (epoch / Y);
def month = (Floor(YMD / M) + 1);
def GMT = Floor((epoch % D) / H);
def HOUR = if GMT > 4 then GMT - 4 else if GMT < 4 then (GMT + 24) - 4 else 0;

def tf = getAggregationPeriod();

def barsPerHour = if tf == AggregationPeriod.HOUR then 1
    else if tf == AggregationPeriod.THIRTY_MIN then 2
    else if tf == AggregationPeriod.TWENTY_MIN then 3
    else if tf == AggregationPeriod.FIFTEEN_MIN then 4
    else if tf == AggregationPeriod.TEN_MIN then 6
    else if tf == AggregationPeriod.FIVE_MIN then 12
    else if tf == AggregationPeriod.THREE_MIN then 20
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;
    

def q1 =
    if HOUR == 0 then -2.25
    else if HOUR == 1 then -3.25
    else if HOUR == 2 then -2.812
    else if HOUR == 3 then -3.5
    else if HOUR == 4 then -1.75
    else if HOUR == 5 then -2.5
    else if HOUR == 6 then -2.0
    else if HOUR == 7 then -3.5
    else if HOUR == 8 then -3.5
    else if HOUR == 9 then -5.688
    else if HOUR == 10 then -4.0
    else if HOUR == 11 then -2.25
    else if HOUR == 12 then -2.812
    else if HOUR == 13 then -4.25
    else if HOUR == 14 then -6.5
    else if HOUR == 15 then -4.5
    else if HOUR == 16 then -1.75
    else if HOUR == 17 then 1.0
    else if HOUR == 18 then -3.25
    else if HOUR == 19 then -3.0
    else if HOUR == 20 then -3.5
    else if HOUR == 21 then -3.5
    else if HOUR == 22 then -2.0
    else -1.5;
def q3 =
    if HOUR == 0 then 2.25
    else if HOUR == 1 then 3.0
    else if HOUR == 2 then 3.75
    else if HOUR == 3 then 3.75
    else if HOUR == 4 then 2.75
    else if HOUR == 5 then 2.75
    else if HOUR == 6 then 3.25
    else if HOUR == 7 then 3.062
    else if HOUR == 8 then 5.0
    else if HOUR == 9 then 8.25
    else if HOUR == 10 then 7.062
    else if HOUR == 11 then 6.75
    else if HOUR == 12 then 5.25
    else if HOUR == 13 then 5.0
    else if HOUR == 14 then 6.25
    else if HOUR == 15 then 6.938
    else if HOUR == 16 then 3.5
    else if HOUR == 17 then 6.25
    else if HOUR == 18 then 2.812
    else if HOUR == 19 then 3.0
    else if HOUR == 20 then 3.25
    else if HOUR == 21 then 2.25
    else if HOUR == 22 then 1.75
    else 2.0;
def m2 =
    if HOUR == 0 then -0.125
    else if HOUR == 1 then -0.25
    else if HOUR == 2 then 0.25
    else if HOUR == 3 then 0.25
    else if HOUR == 4 then 0.375
    else if HOUR == 5 then 0.0
    else if HOUR == 6 then 0.5
    else if HOUR == 7 then 0.0
    else if HOUR == 8 then 0.5
    else if HOUR == 9 then 2.0
    else if HOUR == 10 then 2.25
    else if HOUR == 11 then 2.5
    else if HOUR == 12 then 1.25
    else if HOUR == 13 then 0.75
    else if HOUR == 14 then -0.5
    else if HOUR == 15 then 1.25
    else if HOUR == 16 then 0.75
    else if HOUR == 17 then 2.5
    else if HOUR == 18 then -0.5
    else if HOUR == 19 then 0.25
    else if HOUR == 20 then 0.25
    else if HOUR == 21 then -0.5
    else if HOUR == 22 then 0.25
    else 0.25;

def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + m2;
def upper = median + (q3);
def lower = median + (q1);

plot c = midline;
c.setStyle(CURve.SHORT_DASH);
c.setDefaultColor(getColor(7));

plot median_line = median[barsPerHour];
median_line.SetPaintingStrategy(PaintingStrategy.DASHES);
median_line.SetDefaultColor(getColor(3));
plot expected_upper = upper[barsPerHour];
expected_upper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_upper.SetDefaultColor(getColor(1));
plot expected_lower = lower[barsPerHour];
expected_lower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_lower.SetDefaultColor(getColor(5));

addcloud(expected_upper, expected_lower, color.white, color.white);
def upside = (expected_upper[(-1 * barsPerHour)] - close);
def downside = (close - expected_lower[(-1 * barsPerHour)]);
addLabel(yes, "current upside: " + upside + "  current downside: " + downside, if upside > downside then color.dark_green else if downside > upside then color.dark_red else color.dark_gray);

def dist_to_median = (median_line[(-1 * barsPerHour)] - close);
addLabel(yes, "Distance to Median: " + dist_to_median, 
if dist_to_median > 5 then color.green 
else if dist_to_median > 1 then color.dark_green 
else if dist_to_median < -5 then color.red
else if dist_to_median < -1 then color.dark_red 
else color.gray);
 

VictusJogi

Member
VIP
Updated the indicator to include a "distance to the median" line label. Compares the current close to the projected median. If you're below the median, the theory goes, the median may pull you up. if you're above the next median, the median may pull you down.

PS I did not update the first post with this script, as the coefficients have changed with time and new data. the version for any of these studies is to look at the date range in the header.

-mashume
Code:
#########################################################
#
#   Next Hour ES Trading Range
#     Algorithmic Prediction
#   Values Derived on Data from
#          2021-02-03 to
#          2021-04-15
#
#   @mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version /ES (and maybe /MES) only
#  Functional on 1, 3, 5, 10, 15, 20, 30, 60 minute charts
#
#########################################################

declare upper;

def Y = 31556926;
def M = 2629743;
def D = 86400;
def H = 3600;
def HalfHour = 1800;
def epoch = (getTime() / 1000);
def YMD = (epoch % Y) - (epoch / Y);
def month = (Floor(YMD / M) + 1);
def GMT = Floor((epoch % D) / H);
def HOUR = if GMT > 4 then GMT - 4 else if GMT < 4 then (GMT + 24) - 4 else 0;

def tf = getAggregationPeriod();

def barsPerHour = if tf == AggregationPeriod.HOUR then 1
    else if tf == AggregationPeriod.THIRTY_MIN then 2
    else if tf == AggregationPeriod.TWENTY_MIN then 3
    else if tf == AggregationPeriod.FIFTEEN_MIN then 4
    else if tf == AggregationPeriod.TEN_MIN then 6
    else if tf == AggregationPeriod.FIVE_MIN then 12
    else if tf == AggregationPeriod.THREE_MIN then 20
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;
   

def q1 =
    if HOUR == 0 then -2.25
    else if HOUR == 1 then -3.25
    else if HOUR == 2 then -2.812
    else if HOUR == 3 then -3.5
    else if HOUR == 4 then -1.75
    else if HOUR == 5 then -2.5
    else if HOUR == 6 then -2.0
    else if HOUR == 7 then -3.5
    else if HOUR == 8 then -3.5
    else if HOUR == 9 then -5.688
    else if HOUR == 10 then -4.0
    else if HOUR == 11 then -2.25
    else if HOUR == 12 then -2.812
    else if HOUR == 13 then -4.25
    else if HOUR == 14 then -6.5
    else if HOUR == 15 then -4.5
    else if HOUR == 16 then -1.75
    else if HOUR == 17 then 1.0
    else if HOUR == 18 then -3.25
    else if HOUR == 19 then -3.0
    else if HOUR == 20 then -3.5
    else if HOUR == 21 then -3.5
    else if HOUR == 22 then -2.0
    else -1.5;
def q3 =
    if HOUR == 0 then 2.25
    else if HOUR == 1 then 3.0
    else if HOUR == 2 then 3.75
    else if HOUR == 3 then 3.75
    else if HOUR == 4 then 2.75
    else if HOUR == 5 then 2.75
    else if HOUR == 6 then 3.25
    else if HOUR == 7 then 3.062
    else if HOUR == 8 then 5.0
    else if HOUR == 9 then 8.25
    else if HOUR == 10 then 7.062
    else if HOUR == 11 then 6.75
    else if HOUR == 12 then 5.25
    else if HOUR == 13 then 5.0
    else if HOUR == 14 then 6.25
    else if HOUR == 15 then 6.938
    else if HOUR == 16 then 3.5
    else if HOUR == 17 then 6.25
    else if HOUR == 18 then 2.812
    else if HOUR == 19 then 3.0
    else if HOUR == 20 then 3.25
    else if HOUR == 21 then 2.25
    else if HOUR == 22 then 1.75
    else 2.0;
def m2 =
    if HOUR == 0 then -0.125
    else if HOUR == 1 then -0.25
    else if HOUR == 2 then 0.25
    else if HOUR == 3 then 0.25
    else if HOUR == 4 then 0.375
    else if HOUR == 5 then 0.0
    else if HOUR == 6 then 0.5
    else if HOUR == 7 then 0.0
    else if HOUR == 8 then 0.5
    else if HOUR == 9 then 2.0
    else if HOUR == 10 then 2.25
    else if HOUR == 11 then 2.5
    else if HOUR == 12 then 1.25
    else if HOUR == 13 then 0.75
    else if HOUR == 14 then -0.5
    else if HOUR == 15 then 1.25
    else if HOUR == 16 then 0.75
    else if HOUR == 17 then 2.5
    else if HOUR == 18 then -0.5
    else if HOUR == 19 then 0.25
    else if HOUR == 20 then 0.25
    else if HOUR == 21 then -0.5
    else if HOUR == 22 then 0.25
    else 0.25;

def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + m2;
def upper = median + (q3);
def lower = median + (q1);

plot c = midline;
c.setStyle(CURve.SHORT_DASH);
c.setDefaultColor(getColor(7));

plot median_line = median[barsPerHour];
median_line.SetPaintingStrategy(PaintingStrategy.DASHES);
median_line.SetDefaultColor(getColor(3));
plot expected_upper = upper[barsPerHour];
expected_upper.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_upper.SetDefaultColor(getColor(1));
plot expected_lower = lower[barsPerHour];
expected_lower.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
expected_lower.SetDefaultColor(getColor(5));

addcloud(expected_upper, expected_lower, color.white, color.white);
def upside = (expected_upper[(-1 * barsPerHour)] - close);
def downside = (close - expected_lower[(-1 * barsPerHour)]);
addLabel(yes, "current upside: " + upside + "  current downside: " + downside, if upside > downside then color.dark_green else if downside > upside then color.dark_red else color.dark_gray);

def dist_to_median = (median_line[(-1 * barsPerHour)] - close);
addLabel(yes, "Distance to Median: " + dist_to_median,
if dist_to_median > 5 then color.green
else if dist_to_median > 1 then color.dark_green
else if dist_to_median < -5 then color.red
else if dist_to_median < -1 then color.dark_red
else color.gray);
Works perfectly...Thank you
 

Similar threads

Top