(If you already have an account, login at the top of the page)

futures io is the largest futures trading community on the planet, with over 100,000 members. At futures io, our goal has always been and always will be to create a friendly, positive, forward-thinking community where members can openly share and discuss everything the world of trading has to offer. The community is one of the friendliest you will find on any subject, with members going out of their way to help others. Some of the primary differences between futures io and other trading sites revolve around the standards of our community. Those standards include a code of conduct for our members, as well as extremely high standards that govern which partners we do business with, and which products or services we recommend to our members.

At futures io, our focus is on quality education. No hype, gimmicks, or secret sauce. The truth is: trading is hard. To succeed, you need to surround yourself with the right support system, educational content, and trading mentors – all of which you can find on futures io, utilizing our social trading environment.

With futures io, you can find honest trading reviews on brokers, trading rooms, indicator packages, trading strategies, and much more. Our trading review process is highly moderated to ensure that only genuine users are allowed, so you don’t need to worry about fake reviews.

We are fundamentally different than most other trading sites:

We are here to help. Just let us know what you need.

We work extremely hard to keep things positive in our community.

We do not tolerate rude behavior, trolling, or vendors advertising in posts.

We firmly believe in and encourage sharing. The holy grail is within you, we can help you find it.

We expect our members to participate and become a part of the community. Help yourself by helping others.

You'll need to register in order to view the content of the threads and start contributing to our community. It's free and simple.

I've got a bug that I cannot sort out.. I am building some indicators and one of my primary goal is to ensure stationarity of the indicator values. This is to ensure handling those extreme values. To do this I am applying logic that both centers and scales the values between a range of +/- 50. The indicator is less important however the ability to normalize the data is critical.

What I have below is MC/Easy Language code for an Open/Close indicator that "ideally" is to be normalized between +/- 50. This logic is based on leveraging the InterQuartile Range (IQR).

In short, the final values are grouping around -50 and not cycling above/below 0 within the +50/-50 oscillations. The raw values look ok and nothing special, so I am thinking that the issue is perhaps with the calculation of the IQR itself. Everything else looks pretty vanilla as for syntax and use? Unless I should have some numericseries types there? but that would only be used in a function??

I am using a variation of the following normalization formula. y = 100 * (.5 * ((x-median)/(3rdQuartile-1stQuartile))-50.

And although I am using IQR I have tried a variation using standard scaling formula of y = 2((x-minx)/(maxx-minx))-1 to prove it out cycling between 1 and -1, but still no luck.

I appreciate your review and any tips.

I am on MC64bitv12 build 17002 with EasyLanguage
Slimmed down compiled/"working" code below:

// Note that '//' are for commenting and developer notes
// ver 999 - testing

// First are all the inputs
inputs:
ind_len(14), // indicator length
hist_len(100), // the historical length to be used for an entire historical dataset
med_len(40); // median length

variables:
oco_sum_o(0), // sum of opens
oco_sum_c(0), // sum of closes oco(0), // raw indicator
q1_oco(0), // 1st 25% quartile
q2_oco(0), // 2nd 50% quartile
q3_oco(0), // 3rd 75% quartile
nml_oco(0), // normalized oco value
cen_oco(0), // centered oco value
scl_oco(0), // scaled oco value
median_oco(0), // median oco value
iqr(0), // the inter-quartile range result q3-q1
num(0); // numerator

// calc the quartiles over the historical length
q1_oco = Quartile(1, oco[1], hist_len);
q2_oco = Quartile(2, oco[1], hist_len);
q3_oco = Quartile(3, oco[1], hist_len);

// Goal is to normalize the values between +/- 50 so as to force
// stationarity on the indicator values and create an oscillator around zero.
// Normalization calculation is to take the indicator value less the median and divide
// it by the IQR and compress between +/- 50.

num = ( oco - q2_oco );

iqr = ( q3_oco - q1_oco );
// handle divide by zero. ?Why doesn't EL/MC handle this explicitly?
if iqr = 0 then
iqr = iqr +.000000000001;

// full normalization including centering, scaling, and compression
nml_oco = 1 * (.5*((num)/(iqr))) - 50;

Favorite Futures: No i dont trade for fun i trade for profit

Posts: 181 since Aug 2017

Thanks: 109 given,
272
received

This is a code ( different language ) but similar in nature i use to normalize ATR to a ranking from 0 - 100 . You may be able to adapt it for your requirements

Please register on futures.io to view futures trading content such as post attachment(s), image(s), and screenshot(s).

The following user says Thank You to Ozquant for this post:

Thank you OzQuant for the tip. I will give that a go and see what it provides. I can see that it will consider all values within the lookback period and rank the value in relation to all the values.

Question to the group. One thing that I have not done and am considering. Is do I need to center the values within a high/low range of historical values first? Using ATR or other? I have not tried that, but I thought that is what the formula was doing anyway just with the Q2/IQR of the standard normal CDF setting the bounds?

ok answered my question.. (Still have to figure out why this is not oscillating like I expect...) but the formula is indeed handling both centering and scaling as part of the full normalization formula. The indicator values are 1st having the median subtracted which is to center it and 2nd then being divided by the IQR to scale.

v = value
r_min = range min
r_max = range max
t_min = target min
t_max = target max

scaled value = ((v-r_min)/(r_max-r_min))*(t_max-t_min)+t_min

The final working code..
// Note that '//' are for commenting and developer notes
// ver 002 - with scaling

// First are all the inputs
inputs:
ind_len(14), // indicator length
hist_len(100), // the historical length to be used for an entire historical dataset
med_len(40), // median length
slow_len(15), // slow ma length
fast_len(3); // fast ma length

variables:
oco_sum_o(0), // sum of opens
oco_sum_c(0), // sum of closes oco(0), // raw indicator
nml_oco(0), // normalized oco value
median_oco(0), // median oco value
atr_oco(0), // the atr of the indicator
h_oco(0), // high of oco over hist length
l_oco(0), // low of oco over hist length
num(0), // numerator
den(0), // denominator
ocobyatr(0), // result of oco / atr
t_min(-50), // scaling target min
t_max(50), // scaling target max
oco_qnt(0), // oco quotient
r_min(0), // range min
r_max(0), // range max
f_avg(0), // fast ma result
s_avg(0); // slow ma result

// take the raw oco and determine the H/L range over the historical length
h_oco = highestvalue(oco,hist_len);
l_oco = lowestvalue(oco,hist_len);

atr_oco = TrueRangeCustom(h_oco,l_oco,oco);

ocobyatr = oco/atr_oco;
// get the min and max of the indicator values
r_max = highestvalue(ocobyatr,hist_len);
r_min = lowestvalue(ocobyatr,hist_len);

// scaling and normalization

num = ( ocobyatr - Median(ocobyatr,hist_len) ) - (r_min);
den = (r_max - r_min);
if den = 0 then
den = den +.000000000001;

// new scaling formula
oco_qnt = num/den;
nml_oco =( oco_qnt * (t_max - t_min)) + t_min;