Trend Direction Force Index - TDFI

A custom indicator created by James Chambers on TrendSpider. You can import this custom indicator into your TrendSpider account. Don't have TrendSpider? Create an account first, then import the custom indicator.

Chart featuring the Trend Direction Force Index - TDFI indicator

Source code

This indicator had been implemented by James Chambers in JavaScript on TrendSpider. Check out the developer documentation to learn more about JS on TrendSpider.

describe_indicator('Trend Direction Force Index - TDFI', 'lower');

// Define your input parameters here
const lookback = 13;
const mmaLength = 13;
const mmaMode = "ema";  // Assuming TrendSpider has "ema", "wma", "vwma", "hull", and "tema"
const smmaLength = 13;
const smmaMode = "ema";  // Assuming the same as above
const nLength = 3;
const filterHigh = 0.05;
const filterLow = -0.05;
const price = prices['close']; // Assuming 'prices' is an object with price data

// Define the TEMA and MA functions using TrendSpider's available methods
function tema(src, len) {
    const ema1 = ema(src, len);
    const ema2 = ema(ema1, len);
    const ema3 = ema(ema2, len);
    return (3 * ema1) - (3 * ema2) + ema3;
}

function ma(mode, src, len) {
    switch (mode) {
        case "ema":
            return ema(src, len);
        case "wma":
            return wma(src, len);
        case "vwma":
            return vwma(src, len);
        case "hull":
            return hullma(src, len);
        case "tema":
            return tema(src, len);
        default:
            return sma(src, len);
    }
}

// TDFI calculation function
function tdfi() {
    const mma = ma(mmaMode, price.map(p => p * 1000), mmaLength);
    const smma = ma(smmaMode, mma, smmaLength);
    const impetmma = shift(mma, 1);
    const impetsmma = shift(smma, 1);
    const divma = mma.map((val, idx) => Math.abs(val - smma[idx]));
    const averimpet = impetmma.map((val, idx) => (val + impetsmma[idx]) / 2);
    const tdf = divma.map((val, idx) => Math.pow(val, 1) * Math.pow(averimpet[idx], nLength));
    
    // Assuming a function to get the highest value over a lookback period exists
    const highestTdf = highest(tdf.map(val => Math.abs(val)), lookback * nLength);
    
    return tdf.map((val, idx) => val / highestTdf[idx]);
}

// Calculate the TDFI signal
const signal = tdfi();

// Determine color based on signal value
const color = signal.map(s => s > filterHigh ? 'green' : s < filterLow ? 'red' : 'gray');

// Paint the TDFI line
paint(signal, {
    style: 'line',
    color: color,
    lineWidth: 2
});

// Paint horizontal lines for filters
paint(horizontal_line(filterHigh), { color: 'black' });
paint(horizontal_line(filterLow), { color: 'black' });