Traders' Tip text
Wealth-Lab owes to C# for the power of extensibility and ability to express trading rules of any complexity. However, its strong point is also that no programming may be required to "wire-frame" a trading system idea.
The Strategy Builder lets us throw building blocks known as Rules onto a "drawing board", group them together or divide them into separate chunks:
- Add a pair of few entry Buy/Sell rules (or Short/Cover if you prefer)
- Drag and drop some "Indicator crosses below (above) a value" and pick "ZScore" from the Community Indicators group (requires Community Indicators library v2019.04 or greater)
- Do the same for "Fast moving average is above (below) Slow moving average" to take trades only if the long term trend is in your favor
- For the exit repeat step #2 with an opposite Z-Score value.
Figure 1. Creating a mean-reversion Strategy in the Rule Wizard.
There's one more exit rule in author's Python code which liquidates positions if
Z-Score flips from positive to negative or vice versa without going through the neutral zone. As shown on Figure 1, implementing it is a matter of dropping an OR divider with a couple of extra conditions below it.
If everything's done right your trading system will generate trades similar to those on Figure 2. Those of you who prefer C# to take complete control will find a sample Strategy code below.
Figure 2. Characteristic trades on a Daily chart of Coca Cola (data provided by Yahoo)
Bottom line: the advantage of Wealth-Lab over software packages that require coding is that we can come up with a mean reversion system like the one presented by Anthony Garner in a minute of our time.
WealthScript Code (C#)
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 MeanReversion : WealthScript
{
private StrategyParameter paramPeriod;
public MeanReversion()
{
paramPeriod = CreateParameter("Period", 10, 5, 30, 5);
}
protected override void Execute()
{
int period = paramPeriod.ValueInt;
int lmaPeriod = period * 10;
SMA sma = SMA.Series( Close, period );
SMA lma = SMA.Series( Close, lmaPeriod );
DataSeries zscore = ZScore.Series( Close, period, StdDevCalculation.Sample );
PlotSeries( PricePane, sma, Color.Red, LineStyle.Solid, 1 );
PlotSeries( PricePane, lma, Color.Blue, LineStyle.Solid, 2 );
ChartPane zPane = CreatePane( 30, true, true );
PlotSeries( zPane, zscore, Color.DarkViolet, LineStyle.Histogram, 3 );
DrawHorzLine( zPane, 1.0, Color.Red, LineStyle.Dashed, 1 );
DrawHorzLine( zPane, -1.0, Color.Blue, LineStyle.Dashed, 1 );
//The trigger is a move up or down by more than one standard deviation from the 10-day average price:
//a z-score of over +1 triggers a sell and a z-score of less than -1 triggers a buy.
for(int bar = GetTradingLoopStartBar(1); bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
// exit all positions if zscore flips from positive to negative or vice versa
// without going through the neutral zone
if( (zscore[bar - 1] > 0.5 && zscore[bar] < -0.5) ||
(zscore[bar - 1] < -0.5 && zscore[bar] > 0.5) ||
// Clear positions if the z-score between -.5 and .5
Math.Abs(zscore[bar]) < 0.5 )
SellAtMarket(bar+1, LastPosition);
}
else
{
// Buy long if the z-score is < -2 and the longer term trend is positive
if( zscore[bar] < -2 && sma[bar] > lma[bar])
BuyAtMarket(bar+1);
}
}
}
}
}
Gene Geren (Eugene)
Wealth-Lab team