Understanding the MTF DMI Indicator
The MTF DMI (Directional Movement Index) Indicator enhances your ability to analyze trends across multiple time frames, offering you insights into bullish, bearish, and neutral zones.
Using this tutorial, you’ll learn how to build a Multiple Time Frame indicator (17 different time frames, to be exact!) for ThinkOrSwim. This expands upon the original DMI Indicator (shout-out Hubert Senters and Pete Hahn), and allows for it to work with multiple time frames in ThinkOrSwim (TOS).
The original Directional Movement Index (DMI) Indicator is popular among momentum and breakout traders. It tracks the strength and direction of trends, helping you determine the prevailing market bias. With the MTF approach, you can see how trends align across time frames from one minute to a month, providing a comprehensive trend analysis tool.
By the end, you’ll have a versatile tool that adapts across different time periods, helping you optimize your trading strategy.
Understanding the MTF DMI Indicator
The MTF DMI (Directional Movement Index) Indicator enhances your ability to analyze trends across multiple time frames, offering you insights into bullish, bearish, and neutral zones. Using this tutorial, you’ll learn how to build a Multiple Time Frame indicator (17 different time frames, to be exact!) for ThinkOrSwim. This expands upon the original DMI Indicator (shout-out Hubert Senters and Pete Hahn), and allows for it to work with multiple time frames in ThinkOrSwim (TOS).
The original Directional Movement Index (DMI) Indicator is popular among momentum and breakout traders. It tracks the strength and direction of trends, helping you determine the prevailing market bias. With the MTF approach, you can see how trends align across time frames from one minute to a month, providing a comprehensive trend analysis tool.
By the end, you’ll have a versatile tool that adapts across different time periods, helping you optimize your trading strategy.
Why Multi-Timeframe DMI Analysis Matters
The Directional Movement Index excels at identifying momentum and breakout opportunities, making it the go-to tool for traders who prefer strong directional moves over overbought/oversold reversals. Unlike indicators that work well in range-bound markets, DMI thrives in trending environments and helps you catch explosive moves early in their development.
Dick K, one of the Volatility Box members who inspired this tutorial, recognized that while the Dynamic RSI works beautifully for patient traders seeking overbought/oversold confirmations, momentum and breakout traders need something that helps them front-run directional moves. The DMI perfectly fills this need by identifying when directional momentum is building across multiple timeframes.
When multiple timeframes show aligned DMI signals, it indicates strong institutional participation and higher probability moves. The colored candle system provides instant visual feedback, allowing you to quickly assess whether the market is in a strong trending phase (green/red candles) or a choppy, neutral condition (yellow candles) where breakout strategies might fail.
Reading ThinkOrSwim DMI Documentation
Before building our multi-timeframe version, it’s crucial to understand the foundational DMI concepts from ThinkOrSwim’s official documentation. According to TD Ameritrade, “DMI is a trend following indicator. DI+ crossing above the DI- suggests uptrend conditions and vice-versa. DI+ crossing below the DI- might signify the downtrend. ADX is used for confirmation: trend indications are more likely to be correct if ADX is rising and its values are above 50.”
The DMI indicator takes two inputs (length and average type) and produces three plots: DI+, DI-, and ADX. For our multi-timeframe version, we need to understand that an uptrend occurs when DI+ crosses above DI-, a downtrend when DI+ crosses below DI-, and the ADX provides confirmation when it’s above our threshold level (we’ll use 20 instead of 50 for more trading opportunities).
This documentation gives us everything we need to build our enhanced version. The key insight is that we’ll replicate these calculations across 17 different timeframes and create a zone classification system that automatically categorizes market conditions.
Step-by-Step Coding Tutorial: Building the MTF DMI
Now let’s walk through the complete process of building this Multi-Timeframe DMI indicator from scratch. This tutorial shows the actual development process, including debugging and problem-solving, to help you understand how to build complex multi-timeframe indicators.
Step 1: Setting Up Global Variables and Input Parameters
We start by establishing the foundational inputs that control the indicator’s behavior across all timeframes:
input coloredCandlesOn = yes;
input length = 14;
input ADXLevels = 20;
input averageType = AverageType.WILDERS;
The coloredCandlesOn input allows users to toggle the colored candle functionality, respecting the principle that screen real estate is valuable and should only be used for meaningful information. The length parameter controls the DMI calculation period, while ADXLevels sets the threshold for trend strength confirmation.
Step 2: Understanding Basic DMI Calculations
Before building the multi-timeframe version, we need to understand how to access the DMI plots. Through research and testing, we discover that ThinkOrSwim requires specific syntax to access the DMI components:
def plus = DMI(length, averageType)."DI+";
def minus = DMI(length, averageType)."DI-";
def adx = DMI(length, averageType).ADX;
Note the quotes around “DI+” and “DI-” – this is required because of the special characters. We then create our basic signal logic:
def bullishSignal = plus crosses above minus;
def bearishSignal = plus crosses below minus;
Step 3: Creating Zone Classifications
For the colored candle system, we need zone definitions rather than just crossover signals. Zones remain true as long as conditions persist, while signals only trigger at the moment of crossover:
def bullishZone = plus > minus;
def bearishZone = plus < minus;
However, we quickly discover that this creates too many signals without ADX confirmation. We need to add trend strength filtering:
def bullishZone = plus > minus and adx >= ADXLevels;
def bearishZone = plus = ADXLevels;
def neutralZone = !bullishZone and !bearishZone;
Step 4: Building the Multi-Timeframe Framework
The core challenge is creating a framework that calculates DMI values for multiple timeframes efficiently. We need to manually recreate the DMI calculations using different aggregation periods since the built-in DMI function doesn't accept period parameters:
def monthPlus;
def monthMinus;
def monthAdx;
def monthBullishZone;
def monthBearishZone;
def monthNeutralZone;
if GetAggregationPeriod() monthLoDiff and monthHiDiff > 0 then monthHiDiff else 0;
def monthMinusDM = if monthLoDiff > monthHiDiff and monthLoDiff > 0 then monthLoDiff else 0;
monthPlus = 100 * MovingAverage(averageType, monthPlusDM, length);
monthMinus = 100 * MovingAverage(averageType, monthMinusDM, length);
def monthDX = if (monthPlus + monthMinus > 0) then 100 * AbsValue(monthPlus - monthMinus) / (monthPlus + monthMinus) else 0;
monthAdx = MovingAverage(averageType, monthDX, length);
monthBullishZone = monthPlus > monthMinus and monthAdx >= ADXLevels;
monthBearishZone = monthPlus = ADXLevels;
monthNeutralZone = !monthBullishZone and !monthBearishZone;
} else {
monthPlus = 0;
monthMinus = 0;
monthAdx = 0;
monthBullishZone = 0;
monthBearishZone = 0;
monthNeutralZone = 0;
}
This framework manually calculates the directional movement by comparing current and previous period highs and lows, then applies the appropriate moving averages and ADX calculations. The conditional logic ensures that timeframe data only displays when you're on a chart timeframe equal to or lower than the calculated timeframe.
Step 5: Implementing the Copy-Paste Strategy
Rather than manually typing each timeframe, we use a strategic copy-paste approach. We create the monthly framework first, then use find-and-replace to quickly generate all 17 timeframes:
# Copy the monthly code block
# Replace "month" with "week" for weekly calculations
# Replace "Month" with "Week" in period specifications
# Repeat for all timeframes: 4Days, 3Days, 2Days, Day, 4Hours, 2Hours, Hour, 30Min, 15Min, 10Min, 5Min, 4Min, 3Min, 2Min, Min
This systematic approach allows us to build the entire 1100+ line indicator efficiently while maintaining consistency across all timeframes.
Step 6: Creating the Automatic Labeling System
The labeling system provides instant visual feedback about trend conditions across all relevant timeframes:
AddLabel(monthBullishZone, "M", Color.GREEN);
AddLabel(monthBearishZone, "M", Color.RED);
AddLabel(monthNeutralZone, "M", Color.YELLOW);
AddLabel(weekBullishZone, "W", Color.GREEN);
AddLabel(weekBearishZone, "W", Color.RED);
AddLabel(weekNeutralZone, "W", Color.YELLOW);
This creates colored labels that appear in the upper corner of your chart. Green indicates bullish zones with strong directional movement and ADX confirmation. Red shows bearish zones with similar strength requirements. Yellow warns of neutral conditions where breakout strategies may fail.
Step 7: Adding the Colored Candle System
The colored candle system translates the current timeframe's zone classification into immediate visual feedback:
# Current timeframe calculations
def HiDiff = high - high[1];
def LoDiff = low[1] - low;
def PlusDM = if HiDiff > LoDiff and HiDiff > 0 then HiDiff else 0;
def MinusDM = if LoDiff > HiDiff and LoDiff > 0 then LoDiff else 0;
def Plus = 100 * MovingAverage(averageType, PlusDM, length);
def Minus = 100 * MovingAverage(averageType, MinusDM, length);
def DX = if (Plus + Minus > 0) then 100 * AbsValue(Plus - Minus) / (Plus + Minus) else 0;
def Adx = MovingAverage(averageType, DX, length);
def BullishZone = Plus > Minus and Adx >= ADXLevels;
def BearishZone = Plus = ADXLevels;
def NeutralZone = !BullishZone and !BearishZone;
AssignPriceColor(if coloredCandlesOn and NeutralZone then Color.YELLOW
else if coloredCandlesOn and BullishZone then Color.GREEN
else if coloredCandlesOn and BearishZone then Color.RED
else Color.CURRENT);
This system respects the user's preference for colored candles while providing instant trend recognition. The neutral zone check comes first to ensure that weak trending conditions are properly identified.
Step 8: Debugging and Optimization
During development, we encountered several common issues that provide valuable learning opportunities:
ADX Threshold Issues: Initially, we used the documentation's suggested ADX threshold of 50, but discovered this rarely triggered on most timeframes. Through testing, we found that a threshold of 20 provides a good balance between signal quality and frequency.
Variable Definition Errors: The multi-timeframe approach requires careful variable management. Each timeframe needs its own variable set, and we must define variables outside conditional blocks before assigning values inside them.
Aggregation Period Logic: The conditional logic ensures that higher timeframe data only appears when you're on equal or lower timeframes. This prevents information overload while ensuring you never miss important context.
Step 9: User Control and Customization
The final indicator includes user controls that allow customization without modifying the core code:
input coloredCandlesOn = yes; # Toggle colored candles
input length = 14; # DMI calculation period
input ADXLevels = 20; # Trend strength threshold
input averageType = AverageType.WILDERS; # Smoothing method
These inputs allow traders to adapt the indicator to different trading styles. Conservative traders might increase the ADX threshold to 25 or 30 for higher-quality signals, while aggressive traders might lower it to 15 for more opportunities.
Practical Application and Trading Strategies
The MTF DMI excels in several specific trading scenarios. For breakout trading, look for periods when multiple timeframes transition from neutral (yellow) to directional (green or red) simultaneously. This often indicates the beginning of strong trending moves with institutional participation.
The colored candle system provides immediate feedback about trend quality. When you see consistent green or red candles across multiple timeframes, it suggests the trend has strong momentum behind it. Extended periods of yellow candles often indicate compression that precedes explosive moves.
Risk management improves significantly with multi-timeframe context. When your trading timeframe shows a signal but higher timeframes show opposing bias, consider reducing position size or waiting for better alignment. This prevents many false breakout losses that occur when traders ignore higher-timeframe context.
Integration with Other Trading Systems
The MTF DMI works exceptionally well with volatility-based systems like the Volatility Box. When DMI signals align with volatility edges, it creates high-probability setups with clearly defined risk levels. The multi-timeframe analysis adds crucial context that single-timeframe indicators cannot provide.
For momentum continuation strategies, use the multi-timeframe alignment to identify when trends have room to run. When 4-5 consecutive timeframes show the same directional bias, pullbacks often offer excellent entry opportunities rather than trend reversal signals.
#TOS Indicators
#Home of the Volatility Box
#Full tutorial here: tosindicators.com/indicators/mtf-dmi
#Contains code written by Hubert Senters and Pete Hahn
input coloredCandlesOn = yes;
input length = 14;
input ADXLevels = 20;
input averageType = AverageType.WILDERS;
// ... 119 more lines ...Here are some resources that you may find useful: