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

@mashume.. on any time frame, per your observation, what do you think the maximum distance price will travel (either direction) before returning to the mean?
 
@mashume.. on any time frame, per your observation, what do you think the maximum distance price will travel (either direction) before returning to the mean?
I honestly don't know. I can say that the probability is that, 50% of the time the price should not move beyond the upper and lower boundaries. These numbers are adjustable, but dividing a normal distribution this way is fairly standard. this illustration: https://www.researchgate.net/figure...al-distribution-of-observation_fig4_309148334 is very good.

Remember too that the lines are plotted as change vs the hourly HL2 price, so that it tracks the movement of the market, but it does not consider momentum, since the original statistical analysis did not. It is just based on change in price over 1 hour.

The graphs in the other thread about this (ref in post 1) has some box plots that show outliers, as well as min and max values. They are aggregated for different hold times. If you have questions about them, feel free to ask.

This may, or may not, have made anything clearer for you. If it is the latter, let me know what I can do to clear it up. It is not generally good to trade using methodologies or indicators for which we don't understand the underlying mechanics.

-seth
 
Last edited:
I honestly don't know. I can say that the probability is that, 50% of the time the price should not move beyond the upper and lower boundaries. These numbers are adjustable, but dividing a normal distribution this way is fairly standard. this illustration: https://www.researchgate.net/figure...al-distribution-of-observation_fig4_309148334 is very good.

Remember too that the lines are plotted as change vs the hourly HL2 price, so that it tracks the movement of the market, but it does not consider momentum, since the original statistical analysis did not. It is just based on change in price over 1 hour.

The graphs in the other thread about this (ref in post 1) has some box plots that show outliers, as well as min and max values. They are aggregated for different hold times. If you have questions about them, feel free to ask.

This may, or may not, have made anything clearer for you. If it is the latter, let me know what I can do to clear it up. It is not generally good to trade using methodologies or indicators for which we don't understand the underlying mechanics.

-seth
There is an order in chaos, which I’m trying to understand..
 
jupyter notebook hosted on google collab works fine. thanks!
Here it is
https://colab.research.google.com/drive/15AXGoDA9rtaapu-FIPea8xmXNgRlibfx?usp=sharing
I set it so anyone with the link can view the notebook.

Please, I threw a copyright on the notebook because I do that with all of the python code I release. I love open source, please don't abuse the model. If you like this, or would like to use part of the code, let me know how you use it. I share because I've been a teacher for many years and appreciate all the folks who taught me along the way.

-mashume
 
Here it is
https://colab.research.google.com/drive/15AXGoDA9rtaapu-FIPea8xmXNgRlibfx?usp=sharing
I set it so anyone with the link can view the notebook.

Please, I threw a copyright on the notebook because I do that with all of the python code I release. I love open source, please don't abuse the model. If you like this, or would like to use part of the code, let me know how you use it. I share because I've been a teacher for many years and appreciate all the folks who taught me along the way.

-mashume
This is awesome! Thank You!

No worries! I do not know how to abuse the model.

I am just a student of knowledge learning different fields to certain depths as usual.

I am getting a better understanding on how these coefficients are generated. It is not that difficult as such.

If I can contribute in anyway, then surely I will do so.

Have a good weekend ahead!
 
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);
Does this work on NQ?
 
In watching the last couple of days, it struck me that there might be wildly different probabilities depending on whether the market had moved up or down over the proceeding hour. So I segregated the data into price changes for the next hour based on whether the last hour had been positive or negative. They turn out not to be too terribly different for the most part.

I did turn it into a new version of the indicator, for those who wish to compare them just overlay the two, perhaps one you prefer with wide lines and one with thin or dashed lines to be able to see the difference.

happy trading,
mashume
Code:
#########################################################
#
#   Next Hour ES Trading Range
#     Probable Trading Range Prediction
#    V 2  Up Down Hour Segregation
#   Values Derived on Data from
#          2021-02-08 to
#          2021-04-20
#
#   @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 up_q1 =
    if HOUR == 0 then -2.75
    else if HOUR == 1 then -3.5
    else if HOUR == 2 then -2.0
    else if HOUR == 3 then -3.0
    else if HOUR == 4 then -1.25
    else if HOUR == 5 then -3.0
    else if HOUR == 6 then -2.5
    else if HOUR == 7 then -3.25
    else if HOUR == 8 then -2.75
    else if HOUR == 9 then -5.5
    else if HOUR == 10 then -4.0
    else if HOUR == 11 then -3.0625
    else if HOUR == 12 then -2.9375
    else if HOUR == 13 then -4.25
    else if HOUR == 14 then -5.0
    else if HOUR == 15 then -4.75
    else if HOUR == 16 then -2.0
    else if HOUR == 17 then -0.5
    else if HOUR == 18 then -3.0
    else if HOUR == 19 then -3.1875
    else if HOUR == 20 then -3.25
    else if HOUR == 21 then -3.5
    else if HOUR == 22 then -1.5
    else if HOUR == 23 then -1.75
    else 0;
def up_q2 =
    if HOUR == 0 then -0.25
    else if HOUR == 1 then -0.875
    else if HOUR == 2 then 1.25
    else if HOUR == 3 then 0.5
    else if HOUR == 4 then 0.375
    else if HOUR == 5 then -0.5
    else if HOUR == 6 then 0.0
    else if HOUR == 7 then -0.125
    else if HOUR == 8 then 0.75
    else if HOUR == 9 then 2.5
    else if HOUR == 10 then 1.0
    else if HOUR == 11 then 2.0
    else if HOUR == 12 then 0.75
    else if HOUR == 13 then 0.75
    else if HOUR == 14 then -0.25
    else if HOUR == 15 then 0.5
    else if HOUR == 16 then 0.25
    else if HOUR == 17 then -0.5
    else if HOUR == 18 then -0.5
    else if HOUR == 19 then 0.0
    else if HOUR == 20 then 0.0
    else if HOUR == 21 then -1.0
    else if HOUR == 22 then 0.5
    else if HOUR == 23 then 0.125
    else 0;
def up_q3 =
    if HOUR == 0 then 1.75
    else if HOUR == 1 then 3.0
    else if HOUR == 2 then 4.0
    else if HOUR == 3 then 4.0
    else if HOUR == 4 then 2.75
    else if HOUR == 5 then 2.75
    else if HOUR == 6 then 2.75
    else if HOUR == 7 then 3.25
    else if HOUR == 8 then 5.125
    else if HOUR == 9 then 9.0
    else if HOUR == 10 then 5.375
    else if HOUR == 11 then 5.75
    else if HOUR == 12 then 4.6875
    else if HOUR == 13 then 5.0
    else if HOUR == 14 then 6.0
    else if HOUR == 15 then 6.375
    else if HOUR == 16 then 2.0
    else if HOUR == 17 then -0.5
    else if HOUR == 18 then 2.5
    else if HOUR == 19 then 2.75
    else if HOUR == 20 then 3.0
    else if HOUR == 21 then 1.75
    else if HOUR == 22 then 2.0
    else if HOUR == 23 then 2.0625
    else 0;
def dn_q1 =
    if HOUR == 0 then -2.75
    else if HOUR == 1 then -3.5
    else if HOUR == 2 then -2.0
    else if HOUR == 3 then -3.0
    else if HOUR == 4 then -1.25
    else if HOUR == 5 then -3.0
    else if HOUR == 6 then -2.5
    else if HOUR == 7 then -3.25
    else if HOUR == 8 then -2.75
    else if HOUR == 9 then -5.5
    else if HOUR == 10 then -4.0
    else if HOUR == 11 then -3.0625
    else if HOUR == 12 then -2.9375
    else if HOUR == 13 then -4.25
    else if HOUR == 14 then -5.0
    else if HOUR == 15 then -4.75
    else if HOUR == 16 then -2.0
    else if HOUR == 17 then -0.5
    else if HOUR == 18 then -3.0
    else if HOUR == 19 then -3.1875
    else if HOUR == 20 then -3.25
    else if HOUR == 21 then -3.5
    else if HOUR == 22 then -1.5
    else if HOUR == 23 then -1.75
    else 0;
def dn_q2 =
    if HOUR == 0 then -0.25
    else if HOUR == 1 then -0.875
    else if HOUR == 2 then 1.25
    else if HOUR == 3 then 0.5
    else if HOUR == 4 then 0.375
    else if HOUR == 5 then -0.5
    else if HOUR == 6 then 0.0
    else if HOUR == 7 then -0.125
    else if HOUR == 8 then 0.75
    else if HOUR == 9 then 2.5
    else if HOUR == 10 then 1.0
    else if HOUR == 11 then 2.0
    else if HOUR == 12 then 0.75
    else if HOUR == 13 then 0.75
    else if HOUR == 14 then -0.25
    else if HOUR == 15 then 0.5
    else if HOUR == 16 then 0.25
    else if HOUR == 17 then -0.5
    else if HOUR == 18 then -0.5
    else if HOUR == 19 then 0.0
    else if HOUR == 20 then 0.0
    else if HOUR == 21 then -1.0
    else if HOUR == 22 then 0.5
    else if HOUR == 23 then 0.125
    else 0;
def dn_q3 =
    if HOUR == 0 then 1.75
    else if HOUR == 1 then 3.0
    else if HOUR == 2 then 4.0
    else if HOUR == 3 then 4.0
    else if HOUR == 4 then 2.75
    else if HOUR == 5 then 2.75
    else if HOUR == 6 then 2.75
    else if HOUR == 7 then 3.25
    else if HOUR == 8 then 5.125
    else if HOUR == 9 then 9.0
    else if HOUR == 10 then 5.375
    else if HOUR == 11 then 5.75
    else if HOUR == 12 then 4.6875
    else if HOUR == 13 then 5.0
    else if HOUR == 14 then 6.0
    else if HOUR == 15 then 6.375
    else if HOUR == 16 then 2.0
    else if HOUR == 17 then -0.5
    else if HOUR == 18 then 2.5
    else if HOUR == 19 then 2.75
    else if HOUR == 20 then 3.0
    else if HOUR == 21 then 1.75
    else if HOUR == 22 then 2.0
    else if HOUR == 23 then 2.0625
    else 0;


def up_dn_hour = if close(period = AggregationPeriod.HOUR)[1] - CLOSE(period = AggregationPeriod.HOUR) >= 0 then 1 else 0;
def midline = hl2(period = AggregationPeriod.HOUR)[1];
def median = hl2(period = AggregationPeriod.HOUR)[1] + if up_dn_hour == 1 then up_q2 else dn_q2;
def upper = median + (if up_dn_hour == 1 then up_q3 else dn_q3);
def lower = median + (if up_dn_hour == 1 then up_q1 else dn_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, thank you for sharing this! I was curious to see how your indicator would look on the micros. Here are some pics of the MES with your indicator plotted as solid lines to help me see patterns better. I noticed that a close above or below the boundaries can be a predictor of a good move. Sometimes my lower signals are in confluence, and sometimes your indicator gives an earlier entry. I hope the pics below show what I mean. I plan to watch this on my charts this week. My initial impression is that I like it on lower timeframes (15 min or less) the best.

On this 3 min chart, 2 of my 3 lower indicators were showing a long signal. But a close below the lower boundary on your indicator accurately predicted a short.


On this 5 min chart, my lower indicators were mixed. A close above the upper boundary on yours accurately predicted a long.


On this 10 min chart, the close above the upper boundary of your indicator would have gotten me into the trade several candles earlier than waiting on confluence in my lowers.


Finally, here's a 1 hour chart. A close below your lower boundary was in confluence with my lower indicators. But the close above your upper boundary would have given me a good entry while my lower indicators didn't come into confluence until the move was stalling out.


Thank you again for sharing your work!
 
@mashume Hi there, thanks for this work! I was wondering if in your statistical work, if you'd be comfortable adding a label showing how confident the system would be in being long/short at different levels? Or even suggesting exits?

Thanks!
 
To anyone waiting for a version for something or other from me, the data feed I use is currently down. When it is back up, I will post some new indicators for y'all

-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
235 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