TASC 2013-01 | The DMI Stochastic (Star)

Modified on 2012/12/31 14:40 by Eugene — Categorized as: TASC Traders Tips

Traders' Tip text

This month's article by Barbara Star (Ph.D) presents a number of simple but universal oscillator setups that help get into a position, be it a trade in the direction of trend or a counter-trend opportunity. The author applies Stochastic to Wilder's Directional Oscillator (+DI minus -DI), and uses both to identify the trend.

We will not stay far from truth saying that most publications are centered around entries into trades. However, a trading system's success ultimately depends on exits, position sizing, and portfolio selection – not entries. Unfortunately, the DMI stochastic is not a complete trading system, and to offset that, we have added two generic exit strategies to evaluate its performance: a fixed bars exit that terminates a position once the specified number of days in position has been reached, and a combination of profitable/losing closes. These techniques can be used to backtest almost any entry style without adding prejudice.


  1. Pullback entry:
    1. Buy at open next bar if the DMI Oscillator is above 0 and the DMI Stochastic crosses above 10.
    2. Short at open next bar if the DMI Oscillator is below 0 and the DMI Stochastic crosses below 90.
  2. Countertrend entry:
    1. Short at open next bar if the DMI Oscillator crosses under -20.
    2. Buy at open next bar if the DMI Oscillator crosses above 20.


  1. Fixed bars: exit at open next bar when the specified number of days has been reached.
  2. Profitable and Losing closes (profitable close is a close in the direction of a trade, vice versa for losing close):
    1. Exit at open next bar after reaching the specified number of profitable closes.
    2. Exit at open next bar after reaching the specified number of losing closes.

Both the entries and exits can be applied separately: the choice is up to user. To switch between the different entry and exit styles, drag the respective slider in the “Strategy Parameter” box on the lower left of the program's workspace. The resulting Strategy is available to Wealth-Lab users for downloading right inside the program: simply click the “Download...” button in the application's “Open Strategy” dialog.

Image

Figure 1. Daily chart of QQQ illustrating the application of the DMI Oscillator/DMI Stochastic.

The additional library is available for download to Wealth-Lab customers from our site www.wealth-lab.com ("Extensions" section). To avoid copy/paste, we suggest that Wealth-Lab users would download the code of the trading strategy (see below) by simply clicking the "Download" button in Wealth-Lab's "Open Strategy" dialog (Figure 2).

Image

Figure 2. How to download trading strategies in Wealth-Lab 6.

WealthScript Code (C#)


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies { public class Star201301 : WealthScript { private StrategyParameter paramEntryType; private StrategyParameter paramExitType; private StrategyParameter paramFixedBars; private StrategyParameter paramProfitableClosesTrend; private StrategyParameter paramProfitableClosesCT; private StrategyParameter paramLosingCloses; public Star201301() { paramEntryType = CreateParameter("Entry type", 0, 0, 2, 1); paramExitType = CreateParameter("Exit style", 0, 0, 1, 1); paramFixedBars = CreateParameter("Fixed bars", 5, 1, 30, 1); paramProfitableClosesTrend = CreateParameter("Prft closes (trend)", 10, 1, 15, 1); paramProfitableClosesCT = CreateParameter("Prft closes (CT)", 5, 1, 15, 1); paramLosingCloses = CreateParameter("Losing closes", 3, 1, 15, 1); } protected override void Execute() { int EntryType = paramEntryType.ValueInt == 0 ? 0 : paramEntryType.ValueInt == 1 ? 1 : 2; int pBars = 0; int lBars = 0; int FixedBars = paramFixedBars.ValueInt; // Exit after N fixed bars int ProfitableClosesTrend = paramProfitableClosesTrend.ValueInt; // Number of profitable closes, trend mode int ProfitableClosesCounter = paramProfitableClosesCT.ValueInt; // Number of profitable closes, counter-trend mode int LosingCloses = paramLosingCloses.ValueInt; // Number of losing closes DIPlus dmp = DIPlus.Series( Bars,10 ); // DMI Oscillator DIMinus dmm = DIMinus.Series( Bars,10 ); DataSeries dmo = dmp - dmm; dmo.Description = "DMI Oscillator"; ChartPane dmoPane = CreatePane( 30,true,true ); PlotSeries( dmoPane, dmo, Color.Red, LineStyle.Histogram, 3 );

DataSeries dmiStoch = new DataSeries( dmo, "DMI Stochastic" ); // DMI Stochastic - direct calculation Highest hDmo = Highest.Series( dmo, 10 ); Lowest lDmo = Lowest.Series( dmo, 10 ); dmiStoch = 100 * ( dmo - lDmo ) / ( hDmo - lDmo ); dmiStoch = SMA.Series( dmiStoch, 3 ); dmiStoch.Description = "DMI Stochastic #1"; ChartPane dmsPane = CreatePane( 30,true,true ); PlotSeries( dmsPane, dmiStoch, Color.Red, LineStyle.Solid, 2 ); Bars dmiBars = new Bars("DMI Bars (" + Bars.Symbol+")",Bars.Scale,Bars.BarInterval); for(int bar = 0; bar < Bars.Count; bar++) { dmiBars.Add( Bars.Date[bar], dmo[bar], dmo[bar], dmo[bar], dmo[bar], 0 ); } dmiBars = Synchronize( dmiBars ); // DMI Stochastic - version #2 DataSeries dmiStoch2 = StochD.Series( dmiBars, 10, 3 ); dmiStoch2.Description = "DMI Stochastic #2"; ChartPane dmsPane2 = CreatePane( 30,true,true ); PlotSeries( dmsPane2, dmiStoch2, Color.Green, LineStyle.Solid, 2 ); DrawHorzLine( dmsPane2, 10, Color.Blue, LineStyle.Dashed, 1 ); DrawHorzLine( dmsPane2, 90, Color.Red, LineStyle.Dashed, 1 ); HideVolume(); for(int bar = GetTradingLoopStartBar(10); bar < Bars.Count; bar++) { SetBarColor( bar, dmo[bar] > 0 ? Color.DarkBlue : Color.Red ); if (IsLastPositionActive) { Position p = LastPosition; if( paramExitType.ValueInt == 0 ) // Fixed bars { if ( bar+1 - p.EntryBar >= FixedBars ) ExitAtMarket( bar+1, p, "Timed" ); } else { // Profitable/losing closes if( p.PositionType == PositionType.Long ) { if( Bars.Close[bar] > p.EntryPrice ) pBars++; else if( Bars.Close[bar] < p.EntryPrice ) lBars++; } else { if( Bars.Close[bar] < p.EntryPrice ) pBars++; else if( Bars.Close[bar] > p.EntryPrice ) lBars++; } if( p.EntrySignal == "Pullback" ) { if( pBars >= ProfitableClosesTrend ) ExitAtMarket( bar+1, p, "Profitable Closes.Pullback" ); } else if( p.EntrySignal == "Countertrend" ) { if( pBars >= ProfitableClosesCounter ) ExitAtMarket( bar+1, p, "Profitable Closes.CounterTrend" ); } if( lBars >= LosingCloses ) ExitAtMarket( bar+1, p, "Losing Closes" ); } } else { Position p = null; // Pullback entries

if( EntryType == 0 || EntryType == 1 ) { if( dmo[bar] > 0 && CrossOver( bar, dmiStoch2, 10 ) ) p = BuyAtMarket( bar+1, "Pullback" ); if( dmo[bar] < 0 && CrossUnder( bar, dmiStoch2, 90 ) ) p = ShortAtMarket( bar+1, "Pullback" ); } // Countertrend entries if( EntryType == 0 || EntryType == 2 ) { if( p == null ) { if( CrossUnder( bar, dmo, 20 ) ) p = ShortAtMarket( bar+1, "Countertrend" ); else if( CrossOver( bar, dmo, -20 ) ) p = BuyAtMarket( bar+1, "Countertrend" ); } } if( p != null ) { pBars = 0; lBars = 0; } } } } } }