if(Buffer.getRounded(0,6)>Buffer.getRounded(i,6)){ pRank = pRank+1; } } } dvo = 100.0d*pRank/(double)PercentRankPeriod;
for(int i = 1; i<= PercentRankPeriod; i++){ if(Buffer.getRounded(0,12)>Buffer.getRounded(i,12)){ pRank = pRank+1; } } } dvo = 100.0d*((double)pRank/(double)PercentRankPeriod);
I attached two DVO strategies exactly the same, one tested with the old DVO and one tested with my suggested fixed DVO.
Why so sensitive?
This indicator is extra sensitive to rounding. Taking the high and the low and dividing by two gets us the middle of a single bar expressed in price but half the time the high+low is an odd number of points resulting in precisely half a point being rounded off and will be rounded in one direction only. Some markets have 15 minute bars that are as small as 10 points or less so a significant bias will exist due to this rounding. So yeah 12 decimals is not needed only 7 I think.
And also, while I'm looking at this, I think it is technically correct to account for when the two buffers are precisely the same like this:
protected void OnInit() throws TradingException { SMAAverageCalculator = new AverageCalculator(AverageCalculator.SMA, MAPeriod); } @Override protected void OnBarUpdate() throws TradingException { double price =0 ; double dvo = 0; double pRank =0; double maValue =0; if (CurrentBar < Math.max(PercentRankPeriod,MAPeriod)) { Value.set(0, 0); Buffer.set(0,0); } else { SMAAverageCalculator.onBarUpdate(Chart.Close.get(0)/((Chart.High.get(0)+Chart.Low.get(0))/2), CurrentBar); maValue = SMAAverageCalculator.getValue(); Buffer.set(0,maValue); if(CurrentBar<PercentRankPeriod+MAPeriod+1){ Value.set(0, 0); } else{ for(int i = 1; i<= PercentRankPeriod; i++){ if(Buffer.getRounded(0,12)>Buffer.getRounded(i,12)){ pRank = pRank+1; } else if(Buffer.getRounded(0,12)==Buffer.getRounded(i,12)){ pRank = pRank + 0.5; } } } dvo = 100.0d*(pRank/(double)PercentRankPeriod); } Value.set(0,dvo); } }
Description changed:
if(Buffer.getRounded(0,6)>Buffer.getRounded(i,6)){ pRank = pRank+1; } } } dvo = 100.0d*pRank/(double)PercentRankPeriod;
for(int i = 1; i<= PercentRankPeriod; i++){ if(Buffer.getRounded(0,12)>Buffer.getRounded(i,12)){ pRank = pRank+1; } } } dvo = 100.0d*((double)pRank/(double)PercentRankPeriod);
I attached two DVO strategies exactly the same, one tested with the old DVO and one tested with my suggested fixed DVO.
Why so sensitive?
This indicator is extra sensitive to rounding. Taking the high and the low and dividing by two gets us the middle of a single bar expressed in price but half the time the high+low is an odd number of points resulting in precisely half a point being rounded off and will be rounded in one direction only. So yeah 12 decimals is not needed only 7 I think.
And also, while I'm looking at this, I think it is technically correct to account for when the two buffers are precisely the same like this:
protected void OnInit() throws TradingException { SMAAverageCalculator = new AverageCalculator(AverageCalculator.SMA, MAPeriod); } @Override protected void OnBarUpdate() throws TradingException { double price =0 ; double dvo = 0; double pRank =0; double maValue =0; if (CurrentBar < Math.max(PercentRankPeriod,MAPeriod)) { Value.set(0, 0); Buffer.set(0,0); } else { SMAAverageCalculator.onBarUpdate(Chart.Close.get(0)/((Chart.High.get(0)+Chart.Low.get(0))/2), CurrentBar); maValue = SMAAverageCalculator.getValue(); Buffer.set(0,maValue); if(CurrentBar<PercentRankPeriod+MAPeriod+1){ Value.set(0, 0); } else{ for(int i = 1; i<= PercentRankPeriod; i++){ if(Buffer.getRounded(0,12)>Buffer.getRounded(i,12)){ pRank = pRank+1; } else if(Buffer.getRounded(0,12)==Buffer.getRounded(i,12)){ pRank = pRank + 0.5; } } } dvo = 100.0d*(pRank/(double)PercentRankPeriod); } Value.set(0,dvo); } }
protected void OnInit() throws TradingException { SMAAverageCalculator = new AverageCalculator(AverageCalculator.SMA, MAPeriod); } @Override protected void OnBarUpdate() throws TradingException { double price =0 ; double dvo = 0; double pRank =0; double maValue =0; if (CurrentBar < Math.max(PercentRankPeriod,MAPeriod)) { Value.set(0, 0); Buffer.set(0,0); } else { SMAAverageCalculator.onBarUpdate(Chart.Close.get(0)/((Chart.High.get(0)+Chart.Low.get(0))/2), CurrentBar); maValue = SMAAverageCalculator.getValue(); Buffer.set(0,maValue); if(CurrentBar<PercentRankPeriod+MAPeriod+1){ Value.set(0, 0); } else{ for(int i = 1; i<= PercentRankPeriod; i++){ if(Buffer.getRounded(0,12)>Buffer.getRounded(i,12)){ pRank = pRank+1; } else if(Buffer.getRounded(0,12)==Buffer.getRounded(i,12)){ pRank = pRank + 0.5; } } } dvo = 100.0d*(pRank/(double)PercentRankPeriod); } Value.set(0,dvo); } }
Subject changed from Minor rounding issue in DVO to Rounding issue in DVO effecting m15 and bellow strategies significantly
Also, certainly, 12 is overkill, I just put something extra large in for testing.