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.@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?
have written a python script to "regenerate" the indicator code so I can run it weekly to update the coefficients if there is interest.
I can. How would you prefer to see it... a single script or a jupyter notebook hosted on say, google collab?Hi, If it is okay with you, then can you please share the python script to generate the coefficients?
There is an order in chaos, which I’m trying to understand..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
I can. How would you prefer to see it... a single script or a jupyter notebook hosted on say, google collab?
-mashume
Here it isjupyter notebook hosted on google collab works fine. thanks!
This is awesome! Thank You!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
Does this work on NQ?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);
There is a version for NQ in post 14 of this thread. I think the data in there is recent enough to be valid.Does this work on NQ?
#########################################################
#
# 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);
I'll see if I can pull one together for you before the market opens Monday.@mashume Thanks for posting it for studies for /ES, /NQ, /RTY, and $SPY. Would it be possible to get one for $QQQ?
he might have meant $VIXsix ... is that minutes, or $SIX (some stock), or ...?
-mashume
Join useThinkScript to post your question to a community of 21,000+ developers and traders.
Start a new thread and receive assistance from our community.
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.
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.