NexusFi: Find Your Edge


Home Menu

 





Assistance with normalizing oscillator values


Discussion in MultiCharts

Updated
    1. trending_up 1,630 views
    2. thumb_up 1 thanks given
    3. group 3 followers
    1. forum 6 posts
    2. attach_file 1 attachments




 
 

Assistance with normalizing oscillator values

 
 JoeyZaza 
MA/USA
 
Experience: Intermediate
Platform: Multicharts 64
Broker: AMP Futures
Trading: emini es
Posts: 72 since Oct 2015
Thanks Given: 30
Thanks Received: 53

Hi Traders,

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

// initialization

// logic
oco_sum_o = Summation(open,ind_len);
oco_sum_c = Summation(close,ind_len);

oco = (oco_sum_c - oco_sum_o);

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

// outputs
//Plot1( oco, "OCO" ) ;
Plot1( nml_oco, "OCO Osc");
//Plot2( q1_oco, "q1");
//Plot3( q2_oco, "q2");
//Plot4( q3_oco, "q3");
//Plot5( nml_oco, "OCO Osc" );
//Plot6( nml_den, "denom" );
//Plot7( atr_trend, "centered");
//plot8( median_oco,"median");
//plot9( cen_oco ,"centered");
//plot10( scl_oco,"scaled");
//plot11(iqr,"iqr");
//plot12(std,"std");

if nml_oco > 0 then
SetPlotColor(1, green)
else
SetPlotColor(1, red);


-JoeyZ

Visit my NexusFi Trade Journal Started this thread

Can you help answer these questions
from other members on NexusFi?
Pivot Indicator like the old SwingTemp by Big Mike
NinjaTrader
Exit Strategy
NinjaTrader
REcommedations for programming help
Sierra Chart
NT7 Indicator Script Troubleshooting - Camarilla Pivots
NinjaTrader
How to apply profiles
Traders Hideout
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Just another trading journal: PA, Wyckoff & Trends
31 thanks
Spoo-nalysis ES e-mini futures S&P 500
28 thanks
Tao te Trade: way of the WLD
24 thanks
Bigger Wins or Fewer Losses?
20 thanks
GFIs1 1 DAX trade per day journal
17 thanks
 
Ozquant
Brisbane Queensland Australia
 
Posts: 220 since Aug 2017
Thanks Given: 167
Thanks Received: 380

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



Thanked by:
 
 JoeyZaza 
MA/USA
 
Experience: Intermediate
Platform: Multicharts 64
Broker: AMP Futures
Trading: emini es
Posts: 72 since Oct 2015
Thanks Given: 30
Thanks Received: 53


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.

Visit my NexusFi Trade Journal Started this thread
 
 JoeyZaza 
MA/USA
 
Experience: Intermediate
Platform: Multicharts 64
Broker: AMP Futures
Trading: emini es
Posts: 72 since Oct 2015
Thanks Given: 30
Thanks Received: 53

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?

Visit my NexusFi Trade Journal Started this thread
 
 JoeyZaza 
MA/USA
 
Experience: Intermediate
Platform: Multicharts 64
Broker: AMP Futures
Trading: emini es
Posts: 72 since Oct 2015
Thanks Given: 30
Thanks Received: 53

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.

Visit my NexusFi Trade Journal Started this thread
 
 JoeyZaza 
MA/USA
 
Experience: Intermediate
Platform: Multicharts 64
Broker: AMP Futures
Trading: emini es
Posts: 72 since Oct 2015
Thanks Given: 30
Thanks Received: 53

done..
a bit of research and a few more iterations..
Followed the scaling formula as found here: https://stats.stackexchange.com/questions/281162/scale-a-number-between-a-range

summarized as:

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


// logic
//raw indicator
oco_sum_o = Summation(open,ind_len);
oco_sum_c = Summation(close,ind_len);

oco = (oco_sum_c - oco_sum_o);

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

// averages
s_avg = Average(nml_oco,slow_len);
f_avg = average(nml_oco,fast_len);


// outputs
//Plot0( oco, "OCO" ) ;
Plot1( nml_oco, "OCO Osc");
plot17(s_avg,"SlowMA");
plot18(f_avg,"FastMA");
plot98(0,"zero");
plot99(50,"max");
plot100(-50,"min");

if nml_oco > 0 then
SetPlotColor(1, green)
else
SetPlotColor(1, red);

Best,
JZ

Visit my NexusFi Trade Journal Started this thread
 
Mir1
Luzern, Switzerland
 
Posts: 1 since May 2023
Thanks Given: 0
Thanks Received: 0

Hey Joe
Would you PLS give me an example how can I use your normalized indicator for volatility exit or entry in signal like.....
If normalized value > 25 then sell next bar at market.
Or if normalized value > average normalized value then....
Thank you
Mir


 



Last Updated on May 28, 2023


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts