Traders' Tip text
To test the efficiency of the four indicators in detecting trends, we present a framework which lets a Wealth-Lab user run any of the four example systems. By dragging respective "parameter slider" on the bottom left of the screen, either one of the included subsystems will be executed (ADX, R2, VHF or ER) or all together.
While most indicators used by Mark Katsanos are prepackaged, one participating indicator – Kaufman's
Efficiency Ratio – has been included in the
Community Indicators library which should be installed additionally from our website's
Extensions section.
Figure 1 illustrates trades taken by all the four trading systems at the same time on the Daily chart of USO (U.S. Oil Fund).using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Indicators;
namespace WealthLab.Strategies
{
public class TASC201610Katsanos : WealthScript
{
private StrategyParameter paramStrategy2Run;
public TASC201610Katsanos()
{
paramStrategy2Run = CreateParameter("ADX/R2/VHF/ER/All",4,0,4,1);
}
protected override void Execute()
{
var whichStrategyToRun = paramStrategy2Run.ValueInt;
HideVolume();
switch (whichStrategyToRun)
{
case 0: SystemADX.Run(this); break;
case 1: SystemR2.Run(this); break;
case 2: SystemVHF.Run(this); break;
case 3: SystemER.Run(this); break;
case 4: SystemADX.Run(this); SystemR2.Run(this); SystemVHF.Run(this); SystemER.Run(this); break;
default:
break;
}
}
}
class SystemADX
{
public static void Run(WealthScript obj)
{
int periodADX = 14, adxTrend = 30, adxMax = 42, mab = 50, crit = 22, adxLag = 12;
double adxMult = 1.8;
var c = obj.Close;
var adx = ADX.Series(obj.Bars,periodADX);
var avgMAB = SMA.Series(c,mab);
var adxLow = Lowest.Series(adx,adxLag);
ChartPane p = obj.CreatePane(30,true,true);
obj.PlotSeries(p, adx, Color.Red, LineStyle.Solid, 2 );
for(int bar = obj.GetTradingLoopStartBar(1); bar < obj.Bars.Count; bar++)
{
if (obj.IsLastPositionActive)
{
if( obj.CrossUnder(bar, c, avgMAB) || obj.CrossOver(bar, c, avgMAB) )
obj.ExitAtMarket( bar+1, obj.LastPosition, "MA" );
}
else
{
if( obj.CrossOver(bar, adx, adxTrend) && adx[bar] < adxMax & c[bar] > avgMAB[bar] )
obj.BuyAtMarket(bar+1,"Strong Trend");
if( adx[bar] > adxMult * adxLow[bar] && obj.CrossOver(bar, adx, crit) & c[bar] > avgMAB[bar] )
obj.BuyAtMarket(bar+1,"Trend");
if( obj.CrossOver(bar, adx, adxTrend) && adx[bar] < adxMax & c[bar] < avgMAB[bar] )
obj.ShortAtMarket(bar+1,"Strong Dntrend");
if( adx[bar] > adxMult * adxLow[bar] && obj.CrossOver(bar, adx, crit) & c[bar] < avgMAB[bar] )
obj.ShortAtMarket(bar+1,"Downtrend");
}
// Workaround to prevent open positions from one system to be available for the next system to close
if( bar == obj.Bars.Count-1 )
obj.ExitAtClose( bar, Position.AllPositions, "Close All" );
}
}
}
class SystemR2
{
public static void Run(WealthScript obj)
{
int periodR2 = 18, smooth = 3, mab = 50, crit = 10, r2Lag = 10;
double Trend = 0.42, r2Max = 0.85;
var c = obj.Close;
var r2 = RSquared.Series( c,periodR2 );
var lr = 100 * LinearRegSlope.Series( c,periodR2 );
var avgMAB = SMA.Series(c,mab);
ChartPane p = obj.CreatePane(30,true,true);
obj.PlotSeries(p, r2, Color.Blue, LineStyle.Solid, 2 );
for(int bar = obj.GetTradingLoopStartBar(1 + smooth + r2Lag); bar < obj.Bars.Count; bar++)
{
if (obj.IsLastPositionActive)
{
if( obj.CrossUnder(bar, c, avgMAB) || obj.CrossOver(bar, c, avgMAB) )
obj.ExitAtMarket( bar+1, obj.LastPosition, "MA" );
}
else
{
if( obj.CrossOver(bar,r2,Trend) && r2[bar] < r2Max && r2[bar] > r2[bar-r2Lag] )
{
if( c[bar] > avgMAB[bar] && lr[bar] > crit )
obj.BuyAtMarket(bar+1,"Strong Trend");
else
if( c[bar] < avgMAB[bar] && lr[bar] < -crit )
obj.ShortAtMarket(bar+1,"Strong Downtrend");
}
}
// Workaround to prevent open positions from one system to be available for the next system to close
if( bar == obj.Bars.Count-1 )
obj.ExitAtClose( bar, Position.AllPositions, "Close All" );
}
}
}
class SystemVHF
{
public static void Run(WealthScript obj)
{
int periodVHF = 36, mab = 50, vhfLag = 10;
double vhfTrend = 0.38, vhfMax = 0.45, vhfMult = 1.5, crit = 0.24;
var c = obj.Close;
var vhf = VHF.Series(c,periodVHF);
var avgMAB = SMA.Series(c,mab);
var vhfLow = Lowest.Series(vhf,vhfLag);
ChartPane p = obj.CreatePane(30,true,true);
obj.PlotSeries(p, vhf, Color.Magenta, LineStyle.Solid, 2 );
for(int bar = obj.GetTradingLoopStartBar(1 + mab + vhfLag); bar < obj.Bars.Count; bar++)
{
if (obj.IsLastPositionActive)
{
if( obj.CrossUnder(bar, c, avgMAB) || obj.CrossOver(bar, c, avgMAB) )
obj.ExitAtMarket( bar+1, obj.LastPosition, "MA" );
}
else
{
if( obj.CrossOver(bar, vhf, vhfTrend) && vhf[bar] < vhfMax & vhf[bar] > vhf[bar-vhfLag] & c[bar] > avgMAB[bar] )
obj.BuyAtMarket(bar+1,"Strong Trend");
if( vhf[bar] > vhfMult * vhfLow[bar] && obj.CrossOver(bar, vhf, crit) & c[bar] > avgMAB[bar] )
obj.BuyAtMarket(bar+1,"Trend");
if( obj.CrossOver(bar, vhf, vhfTrend) && vhf[bar] < vhfMax & vhf[bar] > vhf[bar-vhfLag] & c[bar] < avgMAB[bar] )
obj.ShortAtMarket(bar+1,"Strong Dntrend");
if( vhf[bar] > vhfMult * vhfLow[bar] && obj.CrossOver(bar, vhf, crit) & c[bar] < avgMAB[bar] )
obj.ShortAtMarket(bar+1,"Downtrend");
}
// Workaround to prevent open positions from one system to be available for the next system to close
if( bar == obj.Bars.Count-1 )
obj.ExitAtClose( bar, Position.AllPositions, "Close All" );
}
}
}
class SystemER
{
public static void Run(WealthScript obj)
{
int periodER = 24, mab = 50, erLag = 3;
double erTrend = 0.36, erMax = 0.42, erMult = 2.5, crit = 0.26;
var c = obj.Close;
var er = ER.Series(c,periodER);
var avgMAB = SMA.Series(c,mab);
var erLow = Lowest.Series(er,erLag);
ChartPane p = obj.CreatePane(30,true,true);
obj.PlotSeries(p, er, Color.Black, LineStyle.Solid, 2 );
for(int bar = obj.GetTradingLoopStartBar(1 + mab + erLag); bar < obj.Bars.Count; bar++)
{
if (obj.IsLastPositionActive)
{
if( obj.CrossUnder(bar, c, avgMAB) || obj.CrossOver(bar, c, avgMAB) )
obj.ExitAtMarket( bar+1, obj.LastPosition, "MA" );
}
else
{
if( obj.CrossOver(bar, er, erTrend) && er[bar] < erMax & er[bar] > er[bar-erLag] & c[bar] > avgMAB[bar] )
obj.BuyAtMarket(bar+1,"Strong Trend");
if( er[bar] > erMult * erLow[bar] && obj.CrossOver(bar, er, crit) & c[bar] > avgMAB[bar] )
obj.BuyAtMarket(bar+1,"Trend");
if( obj.CrossOver(bar, er, erTrend) && er[bar] < erMax & er[bar] > er[bar-erLag] & c[bar] < avgMAB[bar] )
obj.ShortAtMarket(bar+1,"Strong Dntrend");
if( er[bar] > erMult * erLow[bar] && obj.CrossOver(bar, er, crit) & c[bar] < avgMAB[bar] )
obj.ShortAtMarket(bar+1,"Downtrend");
}
// Workaround to prevent open positions from one system to be available for the next system to close
if( bar == obj.Bars.Count-1 )
obj.ExitAtClose( bar, Position.AllPositions, "Close All" );
}
}
}
}
Eugene
Wealth-Lab team
www.wealth-lab.com