# API ChartStyles Community Components Community Indicators IndexDefinitions Knowledge Base Misc Optimizers Pending Deletion PosSizers Providers Standard Indicators TASC Traders Tips TASCIndicators Tutorial Videos Visualizers Quick Search
»

# TASC 2015-03 | Kiss & Touch With The Modified True Range (Lindgren)

In his March 2015 article, author Chris Lindgren explored an option's probability of reaching certain price prior to expiration. Knowing the probability is achieved through some simple statistical calculations. At the foundation of his work is a new rendition of J. Welles Wilder's classic indicator True Range called the “Modified True Range”. The difference is simply the omission of the current high less the current low: the new indicator only considers the greatest of the two values:

• Absolute value of the current high less the previous close
• Absolute value of the current low less the previous close

It's noticeable how the rounding performed by the Average MTR indicator makes the result appear smoother than the traditional ATR.

While options trading an interesting topic of its own, we will explore applications of the indicator introduced by Mr. Lindgren to trading securities. One example of a possible trading idea could be detection of price spikes using the new MTR indicator. Our sample trading system will follow a counter-trend, mean reversion approach, fading strong moves over a short-term horizon. To spot outlier values in the price, we calculate standard deviation of the MTR. The setup is in place when the current MTR reading exceeds the average MTR by 3 standard deviations of MTR or greater. An entry is triggered when:

• Buy next bar at market if today's close price has declined.
• Short next bar at market if today's close price has increased.

A position is exited with a simple trailing channel exit:

• Exit long when today's low price has broke below the 3-day lowest price.
• Cover short when today's high price has broke above the 3-day highest price.

This system is merely a proof-of-concept. Among possible enhancements to this barebone system, the following can be suggested:

• perform trend detection to not enter against established trend
• to support the trailing exit, introduce a stop loss for risk management
• explore if “clumping” of MTR spikes has effect on system's profitability Figure 1. A Wealth-Lab 6 chart illustrates the sample system's performance on the Daily chart of American Express (AXP).

```using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;namespace WealthLab.Strategies
{
public class ModifiedTrueRange : WealthScript
{
private StrategyParameter paramPeriod;		public ModifiedTrueRange()
{
paramPeriod = CreateParameter("Period", 20, 1, 100, 1);
}		protected override void Execute()
{
int period = paramPeriod.ValueInt;
double Goal = 9.99;			//Calcluate modified true range (MTR)			DataSeries MTR = new DataSeries( Bars,"MTR" );
DataSeries RangeLow = DataSeries.Abs( (Close>>1)-Lowest.Series(Low,1) );
DataSeries RangeHigh = DataSeries.Abs( (Close>>1)-Highest.Series(High,1) );
DataSeries Range1 = new DataSeries( Bars,"Range" );
DataSeries HitGoal = new DataSeries( Bars,"HitGoal" );
DataSeries GoalCount = new DataSeries( Bars,"GoalCount" );
DataSeries GoalPct = new DataSeries( Bars,"GoalPct" );
DataSeries AvgMTR = new DataSeries( Bars,"AvgMTR" );

for(int bar = 1; bar < Bars.Count; bar++)
{
double mtr = Math.Max(RangeLow[bar],RangeHigh[bar]);
MTR[bar] = mtr;
}			//MTR Standard Deviation			DataSeries RangeLow1=( (Close>>1) - Lowest.Series(Low,1) );
DataSeries RangeHigh1=( (Close>>1) - Highest.Series(High,1) );			for(int bar = 1; bar < Bars.Count; bar++)
{
double range = ( Math.Abs(RangeLow1[bar]) >= Math.Abs(RangeHigh1[bar]) ) ?
RangeLow1[bar] : RangeHigh1[bar];
Range1[bar] = range;
}			DataSeries MTRStdDev = StdDev.Series(Range1,period,StdDevCalculation.Sample);			for(int bar = 1; bar < Bars.Count; bar++)
{
HitGoal[bar] = MTR[bar] >= Goal ? 1 : 0;
GoalCount[bar] = Sum.Series( HitGoal,period )[bar];

double goalPct = Math.Round( GoalCount[bar]/period, 2) * 100;
double avgMTR = Math.Round( SMA.Series(MTR,period)[bar], 2 );

GoalPct[bar] = goalPct;
AvgMTR[bar] = avgMTR;
}

StdDev MTRSD = StdDev.Series(MTR,period,StdDevCalculation.Sample);

ChartPane mtrPane = CreatePane( 40, true, true );
PlotSeries( mtrPane, MTR, Color.Red, LineStyle.Histogram, 1 );
PlotSeries( mtrPane, AvgMTR, Color.Blue, LineStyle.Solid, 2 );
PlotStops();			for(int bar = GetTradingLoopStartBar(period); bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
Position p = LastPosition;
if( p.PositionType == PositionType.Long )
SellAtStop( bar+1, p, Lowest.Series( Low,3 )[bar] );
else
CoverAtStop( bar+1, p, Highest.Series( High,3 )[bar] );
}
else
{
//MTR spike
bool spike = MTR[bar] > (AvgMTR[bar] + 3 * MTRSD[bar]);
if( spike )
{
SetBackgroundColor( bar, Color.FromArgb( 20, Color.Green ) );
if( ROC.Value( bar, Close, 1 ) > 0 )
ShortAtMarket(bar+1 );
else