Traders' Tip text
The Wealth-Lab Strategy code for the short-term pattern scanner by Perry J. Kaufman is presented below. With 'parameter sliders' at the bottom left of your Wealth-Lab workspace, included Strategy demonstrates how to switch between the patterns interactively when viewing a chart. Dragging the 'Pattern' slider to the left or to the right will change between the six choices and make the chart update with backtested trades.
Figure 1. Sample entries on a Daily chart of QLD. Data provided by Yahoo! Finance.For example, Figure 1 illustrates a bearish and two bullish key reversal trades created on the next open following the pattern and exiting 3 days after. Through another parameter slider you can control exits after N bars in a trade.
To avoid copy/paste, hitting Ctrl-O and choosing “Download…” in Wealth-Lab gets you the downloadable Strategy under the “Chart patterns” folder.
WealthScript Code (C#)
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Components;
namespace WealthLab.Strategies
{
public class TASCJan2021 : WealthScript
{
private StrategyParameter paramPattern;
private StrategyParameter paramExitDays;
public TASCJan2021()
{
paramPattern = CreateParameter("Pattern", 1, 1, 6, 1);
paramExitDays = CreateParameter("Exit after", 3, 1, 10, 1);
}
protected override void Execute()
{
var _pattern = paramPattern.ValueInt;
var _exitAfter = paramExitDays.ValueInt;
int atrPeriod = 20, maPeriod = 80;
double tick = Bars.SymbolInfo.Tick;
var atr = ATR.Series(Bars, atrPeriod);
var trendFilter = SMA.Series(Close, maPeriod);
for(int bar = GetTradingLoopStartBar(Math.Max(atrPeriod,maPeriod)); bar < Bars.Count; bar++)
{
//key reversal
bool keyRevBear = Highbar > Highbar - 1 && Lowbar < Lowbar - 1 && Closebar < Lowbar - 1;
bool keyRevBull = Highbar > Highbar - 1 && Lowbar < Lowbar - 1 && Closebar > Highbar - 1;
//island reversal
bool islRevBear = Lowbar > Highbar - 1 && Closebar < Openbar;
bool islRevBull = Highbar < Lowbar - 1 && Closebar > Openbar;
//outside day
bool outsideBull = this.isOutsideBar(bar) && Closebar > Lowbar + ( 0.75 * (Highbar - Lowbar));
bool outsideBear = this.isOutsideBar(bar) && Closebar < Lowbar + ( 0.25 * (Highbar - Lowbar));
//wide range day
var ratio = TrueRange.Series(Bars)bar / atrbar;
bool isWRBBull = outsideBull && (ratio > 1.5);
bool isWRBBear = outsideBear && (ratio > 1.5);
//3-day compression
bool compression = CumDown.Series(TrueRange.Series(Bars), 1)bar >= 3;
//gap open
bool isGapUp = (this.isGap(bar) == CommonSignalsEx.GapType.FullUp) && (Openbar > Closebar + 0.5 * atrbar);
bool isGapDown = (this.isGap(bar) == CommonSignalsEx.GapType.FullDown) && (Openbar < Closebar + 0.5 * atrbar);
//trend filter
bool isBullish = Closebar > trendFilterbar;
bool isBearish = Closebar < trendFilterbar;
if (IsLastPositionActive)
{
/* Exit after N days */
Position p = LastPosition;
if (bar + 1 - p.EntryBar >= _exitAfter)
ExitAtMarket(bar + 1, p, string.Format("After {0}", _exitAfter));
}
else
{
switch (_pattern)
{
case 1:
if( keyRevBear && isBearish) ShortAtMarket(bar + 1, "KeyRevBear");
if( keyRevBull && isBullish) BuyAtMarket(bar + 1, "KeyRevBull");
break;
case 2:
if (islRevBear && isBearish) ShortAtMarket(bar + 1, "IslRevBear");
if (islRevBull && isBullish) BuyAtMarket(bar + 1, "IslRevBull");
break;
case 3:
if (outsideBear && isBearish) ShortAtMarket(bar + 1, "OutsideBear");
if (outsideBull && isBullish) BuyAtMarket(bar + 1, "OutsideBull");
break;
case 4:
if (isWRBBear && isBearish) ShortAtMarket(bar + 1, "WRBBear");
if (isWRBBull && isBullish) BuyAtMarket(bar + 1, "WRBBull");
break;
case 5:
if (compression)
{
if(BuyAtStop(bar+1, Highest.Series(High,3)bar, "CompressionBull") ==null)
ShortAtStop(bar + 1, Lowest.Series(Low, 3)bar, "CompressionBear");
}
break;
case 6:
if (isGapUp && isBullish) BuyAtClose(bar, "GapUp");
if (isGapDown && isBearish) ShortAtClose(bar, "GapDown");
break;
default: break;
}
}
}
}
}
}
Gene Geren (Eugene)
Wealth-Lab team