DI+ and DI- Calculations

Discussion in 'Automated Trading' started by Xiode, Jan 4, 2011.

  1. Xiode

    Xiode

    I'm hoping a fellow coder can help me out here... I have an algorithmic platform developed in server-side Javascript using NodeJS coupled with MongoDB. Our current strategy uses a combination of technical indicators, which, for the sake of this explanation, don't necessarily matter. While I've been able to come up with functions for a number of technical indicators (RSI, EMA, etc..) that come within .001 of most finance websites, I'm having a little bit of trouble with the DI calculation.

    I've spent the better part of 24 hours writing, reworking, and testing different methods of calculating DI. However, using Freestockcharts.com to check my calculations, I get pretty drastically different numbers than they do for DI+ and DI- (let's say.. + or - anywhere from 1 to 15). Any insight anyone could provide would be much appreciated. Below is my current code, but I've tried pretty much every DI calculation I've found on the web at this point.

    Currently, I can replicate the calculations in this spreadsheet for DI+ and DI- exactly, but the same method of calculating DI produces different values than Freestockcharts. I realize that it's possible that they could be using quite a bit of historical data and/or smoothing values, but I would imagine that the numbers would still be in the same ballpark.

    I've also attached a screenshot of the same code with syntax highlighting for the reader's convenience.

    Code:
    var bars = [] // will contain an array of bar objects
    
    function calculateDI(period, sign) {
    	if (bars.length < period+1) {
    		return 0;
    	}
    	var isDIPlus = false;
    	if (sign == '+') {
    		isDIPlus = true;
    	}
    	var totalDI = 0, totalTR = 0;
    	for (var i = (bars.length-period); i < bars.length; i++) {
    		var current = bars[i], previous = null;
    		if (i > 0) {
    			previous = bars[i-1];
    		}
    		totalTR += calculateTR(current, previous);
    		if (null == previous) {
    			continue;
    		}
    		var deltaHigh = current['high'] - previous['high'];
    		var deltaLow = previous['low'] - current['low'];
    		// DM+ and DM- are defined to be 0 for an inside interval and/or when their differences are equal
    		if ((deltaHigh < 0 && deltaLow < 0) || deltaHigh == deltaLow) {
    			continue;
    		}
    		var minusDM = 0, plusDM = 0;
    		// Positive directional move, short circuit if this is not DI+
    		if (isDIPlus && deltaHigh > deltaLow) {
    			plusDM = deltaHigh;
    		}
    		// Negative directional move, short circuit if this is not DI-
    		else if (!isDIPlus && deltaHigh < deltaLow) {
    			minusDM = deltaLow;
    		}
    		// Something we don't care about (short circuit)
    		else { continue; }
    
    		if (isDIPlus) { totalDI += plusDM; }
    		else { totalDI += minusDM; }
    	}
    	return Math.round((totalDI/totalTR*100)*1000)/1000;  // round to 3 decimal places
    }
    
     
  2. Xiode

    Xiode

    Any ideas?