Traders' Tip text
At first it may seem that the idea presented in the current month's article is trivial. After all, what else we don't know about the many variations of a moving average crossover? However, author Sylvain Vervoort takes the technique a step further, applying moving average crossovers on his modified Renko chart with an added twist of Heikin Ashi. The premise behind this is to reduce the noise of a typical used fixed-time-related chart and to produce less losing trades.
First, we build two moving averages: the fast is the SMA of the Renko-based typical price and the slow is a SMA of Heikin-Ashi recalculated prices. For simplicity of our example Strategy, we take a standard Renko chart and use Daily prices. Despite using the same period, the HA-based average always lags behind due to added smoothing. The rules are:
- When the 8-period “fast” average crosses above the “slower” counterpart of the same period, a long position is established.
- When the 8-period “fast” average crosses below the “slower” average of the same period, the long position is closed.
Figure 1. A Wealth-Lab 6 chart illustrating the application of the system's rules on a Daily chart of AXP (American Express).The green and red bricks on Figure 1 show Renko bricks supermiposed on the usual OHLC chart.
To execute the enclosed trading system, Wealth-Lab users may copy/paste the enclosed strategy’s C# code or simply let Wealth-Lab do the job: in the “Open Strategy” dialog, click “Download” to get the strategy code.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using WealthLab.ChartStyles.Trending;
namespace WealthLab.Strategies
{
public class VervoortOct2014 : WealthScript
{
StrategyParameter paramRPU;
StrategyParameter paramPeriod;
public VervoortOct2014()
{
paramRPU = CreateParameter("Renko Units", 1, 1, 10, 1);
paramPeriod = CreateParameter("MA Period", 8, 2, 20, 1);
}
protected override void Execute()
{
double rpu = paramRPU.Value;
int period = paramPeriod.ValueInt;
TRenko renko = new TRenko(Bars, rpu);
DataSeries dsOpen = new DataSeries(Bars,"R-Open"), dsHigh = new DataSeries(Bars,"R-High"),
dsLow = new DataSeries(Bars,"R-Low"), dsClose = new DataSeries(Bars,"R-Close");
DataSeries haOpen = new DataSeries(Bars,"HA-Open"), haHigh = new DataSeries(Bars,"HA-High"),
haLow = new DataSeries(Bars,"HA-Low"), haClose = new DataSeries(Bars,"HA-Close");
for(int bar = 1; bar < Bars.Count; bar++)
{
Renko rko = renko.Columnsbar;
// Create Renko-based OHLC and Heikin Ashi for averaging
if( rko.Col > -1 )
{
if( rko.Col > renko.Columnsbar-1.Col )
{
Renko prev = renko.Columnsbar-1;
double open = rko.DirectionUp ? rko.Low : rko.High;
double close = !rko.DirectionUp ? rko.Low : rko.High;
double high = rko.High;
double low = rko.Low;
double prevOpen = prev.DirectionUp ? prev.Low : prev.High;
double prevClose = !prev.DirectionUp ? prev.Low : prev.High;
double prevHigh = prev.High;
double prevLow = prev.Low;
double _haClose = (open + high + low + close) / 4;
double _haOpen = (prevOpen + prevClose) / 2;
double _haHigh = Math.Max( Math.Max(high, open), close );
double _haLow = Math.Min( Math.Min(low, open), close );
dsOpenbar = open;
dsHighbar = high;
dsLowbar = low;
dsClosebar = close;
haOpenbar = _haOpen;
haHighbar = _haHigh;
haLowbar = _haLow;
haClosebar = _haClose;
}
else
{
dsOpenbar = dsOpenbar-1;
dsHighbar = dsHighbar-1;
dsLowbar = dsLowbar-1;
dsClosebar = dsClosebar-1;
haOpenbar = haOpenbar-1;
haHighbar = haHighbar-1;
haLowbar = haLowbar-1;
haClosebar = haClosebar-1;
}
}
}
//The first and faster average is the SMA of the typical price (HLC/3)
//The second average is a SMA of heikin ashi re-calculated prices or haOpen + haHigh + haLow + haClose divided by four
DataSeries maTypical = (SMA.Series( dsHigh, period ) + SMA.Series( dsLow, period ) + SMA.Series( dsClose, period )) / 3;
DataSeries maHeikin = (SMA.Series( haOpen, period ) + SMA.Series( haHigh, period ) + SMA.Series( haLow, period ) + SMA.Series( haClose, period )) / 4;
maTypical.Description = "SMA of Renko-based typical price";
maHeikin.Description = "SMA of Renko-based Heikin Ashi";
PlotSeries( PricePane, maTypical, Color.Blue, LineStyle.Solid, 1 );
PlotSeries( PricePane, maHeikin, Color.Red, LineStyle.Solid, 1 );
for(int bar = 1; bar < Bars.Count; bar++)
{
// Detect crossover/crossunder and store state in a variable
bool maXo = CrossOver(bar, maTypical, maHeikin);
bool maXu = CrossUnder(bar, maTypical, maHeikin);
Position p = LastPosition;
if ( IsLastPositionActive )
{
if ( maXu )
SellAtMarket( bar + 1, p );
}
else
{
if ( maXo )
BuyAtMarket( bar + 1 );
}
}
}
}
}
Eugene
Wealth-Lab team
www.wealth-lab.com