/ES Futures Quasi-Algo 1 Hour Out Prediction for ThinkorSwim

EDIT 2021-December

There are many updated versions of this indicator using more recent data. Please start your search at the END of this thread and work your way toward page 1 to find the most recent for whichever instrument you want. If you don't see it, post a request and I'll do my best to fill it in reasonable order.

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).

View attachment 10334
Overnight projections.

View attachment 10335
Showing regular trading day projections.

View attachment 10336
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
@mashume - is there anyway you can create a scan when the price crosses above median? I am looking to create a scan for SPY and AMZN on 2m timeframe. I am not able to create one for a 2m time frame since the Aggregation Period is set to 1 hour.
 
Last edited:
@mashume - is there anyway you can create a scan when the price crosses above median? I am looking to create a scan for SPY and AMZN on 2m timeframe. I am not able to create one for a 2m time frame since the Aggregation Period is set to 1 hour.

Yes, that is correct.
You cannot create a 2m scan.
You must set your scan timeframe to be the same as the aggregation period in your script.
If the secondary aggregation is set at 1hr then the scanner must be set to 1hr.
There is no workaround to this limitation as the ToS platform does not support the use of differing secondary aggregations in any of the ToS widgets (scans, watchlists, conditional orders, etc).
 
Hi @mashume, has this post been updated recently? Does the script mentioned for /MNQ or QQQ still work? From what I understand, the script requires the latest data from the API. If that's true, the old script might not work correctly anymore. Is that correct?
 
Hi @mashume, has this post been updated recently? Does the script mentioned for /MNQ or QQQ still work? From what I understand, the script requires the latest data from the API. If that's true, the old script might not work correctly anymore. Is that correct?
I have not updated this in quite a while. I can possibly run some updates for you later in the day today if I can find a bit of time.

The scripts themselves will still run, though the underlying market may have changed its behaviour in the interim. That basically means, your script will be predicting things based on an old idea of how much the market moves at any given point in time.

The API for getting data is only required for creating a new (updated) version of the script. There is a python notebook in this thread somewhere (google colab) which has all the programming stuff to spit out a new thinkScript indicator code. I'll check whether the price history API it uses is still valid when I can.

Thanks for your continued interest,
mashume
 

/MNQ

Code:
#########################################################
#
#   Next Hour /MNQ Trading Range
#     Algorithmic Prediction
#
#   Values Derived on Data from
#          2024-12-24 to
#          2025-03-06
#
#   mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version /MNQ only
#  Functional on 1, 2, 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.TWO_MIN then 30
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;


def q1 =
    if HOUR == 0 then -12.25
    else if HOUR == 1 then -20.812
    else if HOUR == 2 then -23.312
    else if HOUR == 3 then -14.438
    else if HOUR == 4 then -15.75
    else if HOUR == 5 then -13.562
    else if HOUR == 6 then -23.25
    else if HOUR == 7 then -20.0
    else if HOUR == 8 then -42.062
    else if HOUR == 9 then -89.5
    else if HOUR == 10 then -35.125
    else if HOUR == 11 then -41.562
    else if HOUR == 12 then -31.062
    else if HOUR == 13 then -39.125
    else if HOUR == 14 then -37.25
    else if HOUR == 15 then -34.688
    else if HOUR == 16 then -16.75
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then -14.062
    else if HOUR == 19 then -14.75
    else if HOUR == 20 then -12.0
    else if HOUR == 21 then -13.75
    else if HOUR == 22 then -11.75
    else -11.062;
def q3 =
    if HOUR == 0 then 14.875
    else if HOUR == 1 then 17.062
    else if HOUR == 2 then 19.812
    else if HOUR == 3 then 29.062
    else if HOUR == 4 then 16.25
    else if HOUR == 5 then 16.25
    else if HOUR == 6 then 21.0
    else if HOUR == 7 then 24.812
    else if HOUR == 8 then 30.0
    else if HOUR == 9 then 75.688
    else if HOUR == 10 then 47.062
    else if HOUR == 11 then 41.812
    else if HOUR == 12 then 46.875
    else if HOUR == 13 then 38.625
    else if HOUR == 14 then 31.812
    else if HOUR == 15 then 48.812
    else if HOUR == 16 then 28.5
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 19.062
    else if HOUR == 19 then 18.625
    else if HOUR == 20 then 16.375
    else if HOUR == 21 then 10.562
    else if HOUR == 22 then 11.0
    else 15.5;
def m2 =
    if HOUR == 0 then 0.75
    else if HOUR == 1 then -4.375
    else if HOUR == 2 then 0.75
    else if HOUR == 3 then 6.625
    else if HOUR == 4 then 2.25
    else if HOUR == 5 then 3.25
    else if HOUR == 6 then 1.5
    else if HOUR == 7 then 5.125
    else if HOUR == 8 then -1.25
    else if HOUR == 9 then -2.25
    else if HOUR == 10 then 8.125
    else if HOUR == 11 then -1.125
    else if HOUR == 12 then 12.625
    else if HOUR == 13 then 0.25
    else if HOUR == 14 then -2.25
    else if HOUR == 15 then 4.5
    else if HOUR == 16 then 3.0
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 4.125
    else if HOUR == 19 then 2.375
    else if HOUR == 20 then 2.25
    else if HOUR == 21 then -1.5
    else if HOUR == 22 then -0.5
    else 1.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);

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);
 

QQQ

Code:
#########################################################
#
#   Next Hour QQQ Trading Range
#     Algorithmic Prediction
#
#   Values Derived on Data from
#          2024-12-06 to
#          2025-03-06
#
#   mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version QQQ only
#  Functional on 1, 2, 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.TWO_MIN then 30
    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.382
    else if HOUR == 5 then -0.33
    else if HOUR == 6 then -0.502
    else if HOUR == 7 then -0.463
    else if HOUR == 8 then -0.953
    else if HOUR == 9 then -1.883
    else if HOUR == 10 then -0.84
    else if HOUR == 11 then -0.859
    else if HOUR == 12 then -0.621
    else if HOUR == 13 then -0.951
    else if HOUR == 14 then -0.955
    else if HOUR == 15 then -0.878
    else if HOUR == 16 then -0.19
    else if HOUR == 17 then -0.275
    else if HOUR == 18 then -0.766
    else if HOUR == 19 then nan
    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.382
    else if HOUR == 5 then 0.36
    else if HOUR == 6 then 0.532
    else if HOUR == 7 then 0.623
    else if HOUR == 8 then 0.776
    else if HOUR == 9 then 1.861
    else if HOUR == 10 then 1.212
    else if HOUR == 11 then 0.973
    else if HOUR == 12 then 1.073
    else if HOUR == 13 then 0.84
    else if HOUR == 14 then 0.588
    else if HOUR == 15 then 0.968
    else if HOUR == 16 then 0.305
    else if HOUR == 17 then 0.37
    else if HOUR == 18 then 2.002
    else if HOUR == 19 then nan
    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.02
    else if HOUR == 5 then 0.04
    else if HOUR == 6 then 0.06
    else if HOUR == 7 then 0.12
    else if HOUR == 8 then 0.048
    else if HOUR == 9 then 0.125
    else if HOUR == 10 then 0.223
    else if HOUR == 11 then 0.055
    else if HOUR == 12 then 0.322
    else if HOUR == 13 then -0.065
    else if HOUR == 14 then -0.09
    else if HOUR == 15 then -0.041
    else if HOUR == 16 then 0.012
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 0.64
    else if HOUR == 19 then nan
    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);

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);
 
@mashume:

First of all, I want to thank you for generously sharing your time and the many innovative, enlightening contributions you've published here at useThinkScript...I am a big fan! With that said, I believe I read somewhere along the way that you are currently taking some time off from trading...I hope this post finds all is well your way...

If you happen to read this, I hope I'm not disturbing your "sabbatical" with a couple of questions about the Quasi-Algo...Basically I'm currently trying to wrap my head around the Stats, Quartiles and the plotting of the Algo...

Given the following sample 5 min Chart and the Markets selling off substantially today:

202503102319__.jpg

  1. Is the last running of the Algo for MNQ (3/6/2025) still viable? Or would today's price action require the Algo be updated?
  2. Looking at the projections on the sample Chart above, I was wondering why the projections are more compressed in the afterhours?
  3. What is the significance of price breaking out above the projection, as opposed to price breaking down below the projection?
  4. What is the significance of price being quite a bit above or below the associated projection?
  5. One last question, if I may...the sample Chart above shows projections running 2+ hours out in front of the current price action...Is this by design or is there a preferred setting for the Right Expansion area? I currently have it set to 36 bars to the right...
Thanks again for sharing...All the best with your future endeavors...
 
  1. Is the last running of the Algo for MNQ (3/6/2025) still viable? Or would today's price action require the Algo be updated?
  2. Looking at the projections on the sample Chart above, I was wondering why the projections are more compressed in the afterhours?
  3. What is the significance of price breaking out above the projection, as opposed to price breaking down below the projection?
  4. What is the significance of price being quite a bit above or below the associated projection?
  5. One last question, if I may...the sample Chart above shows projections running 2+ hours out in front of the current price action...Is this by design or is there a preferred setting for the Right Expansion area? I currently have it set to 36 bars to the right...
Thanks again for sharing...All the best with your future endeavors...
To try some quick answers:
1. The algo is based on several months of data, the latest version says this in the header:
Code:
#   Values Derived on Data from
#          2024-12-24 to
#          2025-03-06
so while unlikely, it is possible that one bad day might skew things. There is a discussion at some point back in this thread about the effects of the Russian invasion of Ukraine on oil futures with some interesting comparison graphs. I haven't done that much work on this, but may if I get bored with other things.

2. Presumably, the after hours ranges are more compressed because the trend in after hours trading is for things to move less. I don't really know, but I don't massage the data to reduce ranges or increase them. Whatever the data says, goes into the indicator.

3. I feel that breaking through ranges is indicative of the market volatility increasing and being willing or more willing to move the instrument in one direction or another. it is analogous to a line of support or resistance in a way.

4. Like all indicators, when the market is doing unusual things (in this case moving decisively in one direction more than it usually does) indicators can be wrong. It does tell us that there is, in this case, a decidedly negative sentiment in a rather broad group of investors.

5. I believe I ran the projection out about an hour when I was developing the indicator. beyond that, it is pure speculation as it needs the close of the last hour to draw the center lines for the next set of range markers. Or something like that. It has been a while since I've thought seriously about this bit of code.

As for trading, I still don't for the moment. I've gotten back to watching the markets a bit and playing with some ideas, but not even paper trading right now. Life has given me other rewards that I chose to pay more attention to for a bit. :)

all the best,
mashume
 
@mashume:

Thank you for your time and effort with the swift and very informative reply...I really appreciate it!

I certainly understand the need to take a break and focus on other potentially rewarding things...I hope that the ideas you're currently exploring have the potential to bear fruit somewhere further on down the road...

With that said, here's hoping you might possibly share them with the community somewhere along the way...I have certainly enjoyed exploring the indicators you've already posted here at useThinkScript...

Have a great weekend!
 
Could you post latest for /ES?

/ES

Code:
#########################################################
#
#   Next Hour /ES Trading Range
#     Algorithmic Prediction
#
#   Values Derived on Data from
#          2025-01-07 to
#          2025-03-19
#
#   mashume at usethinkscript.com
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
#  This Version /ES only
#  Functional on 1, 2, 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.TWO_MIN then 30
    else if tf == AggregationPeriod.MIN then 60
    else double.nan;


def q1 =
    if HOUR == 0 then -2.5
    else if HOUR == 1 then -4.0
    else if HOUR == 2 then -4.5
    else if HOUR == 3 then -3.75
    else if HOUR == 4 then -3.25
    else if HOUR == 5 then -4.25
    else if HOUR == 6 then -5.5
    else if HOUR == 7 then -5.25
    else if HOUR == 8 then -8.75
    else if HOUR == 9 then -21.125
    else if HOUR == 10 then -11.5
    else if HOUR == 11 then -8.25
    else if HOUR == 12 then -8.062
    else if HOUR == 13 then -8.375
    else if HOUR == 14 then -7.875
    else if HOUR == 15 then -8.5
    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 -2.75
    else if HOUR == 20 then -3.25
    else if HOUR == 21 then -2.75
    else if HOUR == 22 then -2.5
    else -2.25;
def q3 =
    if HOUR == 0 then 2.0
    else if HOUR == 1 then 3.25
    else if HOUR == 2 then 4.5
    else if HOUR == 3 then 6.5
    else if HOUR == 4 then 4.0
    else if HOUR == 5 then 4.0
    else if HOUR == 6 then 3.75
    else if HOUR == 7 then 5.5
    else if HOUR == 8 then 6.75
    else if HOUR == 9 then 11.25
    else if HOUR == 10 then 9.75
    else if HOUR == 11 then 9.75
    else if HOUR == 12 then 10.25
    else if HOUR == 13 then 12.0
    else if HOUR == 14 then 8.25
    else if HOUR == 15 then 8.75
    else if HOUR == 16 then 5.25
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 4.0
    else if HOUR == 19 then 3.75
    else if HOUR == 20 then 3.25
    else if HOUR == 21 then 2.5
    else if HOUR == 22 then 2.5
    else 2.75;
def m2 =
    if HOUR == 0 then -0.5
    else if HOUR == 1 then -0.75
    else if HOUR == 2 then 0.5
    else if HOUR == 3 then 2.5
    else if HOUR == 4 then 0.75
    else if HOUR == 5 then 0.5
    else if HOUR == 6 then 0.0
    else if HOUR == 7 then 1.0
    else if HOUR == 8 then 0.0
    else if HOUR == 9 then -1.25
    else if HOUR == 10 then -0.25
    else if HOUR == 11 then 0.125
    else if HOUR == 12 then 1.875
    else if HOUR == 13 then 1.75
    else if HOUR == 14 then -0.25
    else if HOUR == 15 then -0.75
    else if HOUR == 16 then 1.0
    else if HOUR == 17 then 0.0
    else if HOUR == 18 then 0.75
    else if HOUR == 19 then 1.0
    else if HOUR == 20 then -0.25
    else if HOUR == 21 then -0.25
    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);

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);
 
Some interesting graphs of /ES hold times vs price delta:
8ynnjsG.png

LMSwbsP.png

zHy6TsG.png

dJCNlBk.png


These are a series of graphs of the change in price depending on how long a position was held when opened at a specific hour of the day. they do not take into consideration buying at any point other than the top of the hour and selling at the half hour marks. They are purely statistical in nature and do not represent advice on when during a day to make investments either long or short.
The timeframes are, from top to bottom, short, medIum, long, and all timeframes combined. (up to the limit of the data and time periods it calculates.)

presented for those who are interested in a slightly more statistical side of technical analysis.

-mashume
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
369 Online
Create Post

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top