Log in to see Cloud of Tags

Wealth-Lab Wiki

TASC 2013-07 | The Step Candle Pattern (Vervoort)

RSS

Traders' Tip text

In previous issue (June 2013), we presented a simplified version of Sylvain Vervoort’s zigzag system which was based on closing prices. This month, the swing detection uses the high and low prices so to fully comply with the original system.

Since no trading rules were presented by the author, the current system only does the charting. The system marks each zigzag leg on the chart, connecting them with colored lines. The blue/red letters attached to turning points indicate Downstep (D), Upstep (U), Engulfing (E) and Harami (H) patterns, respectively.

To execute successfully in Wealth-Lab, the system requires the companion SVEHLZZperc indicator from TASCIndicators library. Please install (or update if you haven't done so already) the library from the www.wealth-lab.com site to its latest version 2013.04 or higher.

Image

Figure 1. A Wealth-Lab 6 chart pinpoints Engulfing, Downstep and Upstep patterns that occurred at reversal points on a chart of AAPL (Apple Inc).


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using WealthLab.Rules.Candlesticks;
using TASCIndicators;

namespace WealthLab.Strategies { public class IRSTS_StepPattern : WealthScript { private StrategyParameter paramPercent; private StrategyParameter paramLookbackForStepPattern; public IRSTS_StepPattern() { paramPercent = CreateParameter("Reversal %", 10.0, 1.0, 50.0, 1.0); paramLookbackForStepPattern = CreateParameter("Lookback", 3, 1, 20, 1); } bool isInsideBody( int bar, double price ) { return price <= Math.Max(Open[bar],Close[bar]) && price >= Math.Min(Open[bar],Close[bar]); } bool Upstep( int bar, int lookback ) { bool result = false; bool way1 = (Open[bar] > Close[bar] & Open[bar+1] < Close[bar+1]) && isInsideBody(bar, Open[bar+1]) && Close[bar+1] > Open[bar]; bool way2 = (Open[bar] < Close[bar] & Open[bar+1] < Close[bar+1]) && isInsideBody(bar, Open[bar+1]) && Close[bar+1] > Close[bar]; bool way3 = (Open[bar-1] > Close[bar-1]) && (Open[bar] < Close[bar]) && isInsideBody(bar, Open[bar+1]) && (Close[bar] > Open[bar-1]); bool way4 = (Open[bar-1] < Close[bar-1]) && (Open[bar] < Close[bar]) && isInsideBody(bar, Open[bar+1]) && (Close[bar] > Close[bar-1]); result = bar == LowestBar.Series( Low,lookback )[bar] && ( way1 | way2 | way3 | way4 ); return result; } bool Downstep( int bar, int lookback ) { bool result = false; bool way1 = (Open[bar] < Close[bar] & Open[bar+1] > Close[bar+1]) && isInsideBody(bar, Open[bar+1]) && Close[bar+1] < Open[bar]; bool way2 = (Open[bar] > Close[bar] & Open[bar+1] > Close[bar+1]) && isInsideBody(bar, Open[bar+1]) && Close[bar+1] < Close[bar]; bool way3 = (Open[bar-1] < Close[bar-1]) && (Open[bar] > Close[bar]) && isInsideBody(bar, Open[bar+1]) && (Close[bar] < Open[bar-1]); bool way4 = (Open[bar-1] > Close[bar-1]) && (Open[bar] > Close[bar]) && isInsideBody(bar, Open[bar+1]) && (Close[bar] < Close[bar-1]); result = bar == HighestBar.Series( High,lookback )[bar] && ( way1 | way2 | way3 | way4 ); return result; } protected override void Execute() { int lookback = paramLookbackForStepPattern.ValueInt; double percent = paramPercent.Value; const string t = "\t"; string s = string.Empty; ZZBuilder zz = new ZZBuilder( Bars, percent ); List<ZigZag> lst = zz.ZigZags;

bool[] BearishEngulfing; CandlePattern.BearishEngulfingLines(this, s, false, out BearishEngulfing); bool[] BullishEngulfing; CandlePattern.BullishEngulfingLines(this, s, false, out BullishEngulfing); bool[] BearishHarami; CandlePattern.BearishHarami(this, s, false, out BearishHarami); bool[] BullishHarami; CandlePattern.BullishHarami(this, s, false, out BullishHarami); HideVolume(); SetBarColors(Color.Silver,Color.Silver); if( lst != null ) { DrawLabel(PricePane, string.Format( "Total {0}-percent zigzags: {1}", percent, lst.Count) ); foreach( ZigZag z in lst ) { if ( z.inPrice == 0.0 ) continue; DrawLine( PricePane, z.zigBar, z.inPrice, z.zagBar, z.outPrice, z.isMoveUp ? Color.Blue : Color.Red, LineStyle.Solid, 2 ); } } for(int bar = 2 + lookback; bar < Bars.Count; bar++) { if( lst != null ) { if( lst.Count > 0 ) { int idx = 0; foreach( ZigZag z in lst ) { if( z.barDetected == bar ) { //SetBackgroundColor( bar, !z.isMoveUp ? Color.FromArgb(30,Color.Green) : Color.FromArgb(30,Color.Red) ); if( Downstep( z.zagBar, lookback ) ) AnnotateBar( "D", z.zagBar, true, Color.Red ); if (BearishHarami[z.zagBar]) AnnotateBar( "H", z.zagBar, true, Color.Red ); if (BearishEngulfing[z.zagBar]) AnnotateBar( "E", z.zagBar, true, Color.Red );

if( Upstep( z.zagBar, lookback ) ) AnnotateBar( "U", z.zagBar, false, Color.Blue ); if (BullishHarami[z.zagBar]) AnnotateBar( "H", z.zagBar, false, Color.Blue ); if (BullishEngulfing[z.zagBar]) AnnotateBar( "E", z.zagBar, false, Color.Blue ); } } } } } } } public class XEvent { public int Bar {get; set; } public int Type {get; set; } public double Price {get; set; } public XEvent( int bar, int type ) { Bar = bar; Type = type; } public XEvent( int bar, int type, double price ) { Bar = bar; Type = type; Price = price; } } public enum Wave {W1, W2, W3} public class ZigZag { public int barDetected { get; set; } public bool isMoveUp { get; set; } public int zigBar { get; set; } public int zagBar { get; set; } public double inPrice { get; set; } public double outPrice { get; set; } public double magnitude { get; set; } public Wave wave { get; set; } public int leg3Count { get; set; } public ZigZag(int barDetected, bool isMoveUp, int zigBar, int zagBar, double inPrice, double outPrice, double magnitude) { this.barDetected = barDetected; this.isMoveUp = isMoveUp; this.zigBar = zigBar; this.zagBar = zagBar; this.inPrice = inPrice; this.outPrice = outPrice; this.magnitude = magnitude; this.leg3Count = 0; } } public class ZZBuilder { private bool Initialized = false; public Bars bars { get; private set; } public double percent { get; private set; } public List<ZigZag> ZigZags { get; private set; } public ZZBuilder( Bars b, double pct ) { this.bars = b; this.percent = pct; BuildZZHiLo(); //BuildZZ(); } private void BuildZZHiLo() { try { DataSeries zz = SVEHLZZperc.Series(bars,percent,14,3,SVEHLZZperc_Type.Percent); List<XEvent> lstX = new List<XEvent>(); lstX.Add( new XEvent( 0, 0 ) ); for(int bar = 1; bar < bars.Count; bar++) { if( bars.High[bar - 1] < zz[bar - 1] && bars.High[bar] > zz[bar] ) { lstX.Add( new XEvent(bar, 1) ); } if( bars.Low[bar - 1] > zz[bar - 1] && bars.Low[bar] < zz[bar] ) { lstX.Add( new XEvent(bar, -1) ); } } for(int bar = 0; bar < bars.Count; bar++) { for( int i = 0; i < lstX.Count; i++ ) { if( i == 0 ) continue; XEvent e = lstX[i]; if( e.Bar == bar ) { int prevEventBar = lstX[i - 1].Bar; int step = bar-prevEventBar; if( e.Type == 1 ) { double Trough = Lowest.Value( bar, bars.Low, step ); e.Price = Trough; e.Bar = (int)LowestBar.Value( bar, bars.Low, step ); } else if( e.Type == -1 ) { double Peak = Highest.Value( bar, bars.High, step ); e.Price = Peak; e.Bar = (int)HighestBar.Value( bar, bars.High, step ); } break; } } }

List<ZigZag> lst = new List<ZigZag>(); double inPrice = 0, outPrice = 0, magnitude = 0; int barDetected = 0, zigBar = 0, zagBar = 0; bool detected = false;

for(int bar = 1; bar < bars.Count; bar++) { detected = false; XEvent e = lstX[0]; XEvent prev = lstX[0]; for( int i = 0; i < lstX.Count; i++ ) { if( i == 0 ) continue; e = lstX[i]; prev = lstX[i - 1]; if( e.Bar == bar ) { detected = true; break; } } if( detected ) { bool isMoveUp = (e.Type == 1); if( isMoveUp ) { zigBar = prev.Bar; zagBar = e.Bar; inPrice = prev.Price; outPrice = e.Price; } else { zigBar = prev.Bar; zagBar = e.Bar; inPrice = prev.Price; outPrice = e.Price; } magnitude = Math.Abs( inPrice - outPrice );

lst.Add( new ZigZag( bar, isMoveUp, zigBar, zagBar, inPrice, outPrice, magnitude ) ); } } ZigZags = lst; Initialized = true; } catch { } } [Obsolete] private void BuildZZ() { try { PeakTroughMode mode = WealthLab.Indicators.PeakTroughMode.Percent; PeakBar pb = PeakBar.Series(bars.Close,percent,mode); TroughBar tb = TroughBar.Series(bars.Close,percent,mode); Trough tr = Trough.Series(bars.Close,percent,mode); Peak pk = Peak.Series(bars.Close,percent,mode); List<ZigZag> lst = new List<ZigZag>(); double t1 = 0, p1 = 0, inPrice, outPrice = 0, magnitude = 0; int tb1 = 0, pb1, barDetected = 0, zigBar = 0, zagBar = 0; bool detected = false;

for(int bar = 1; bar < bars.Count; bar++) { detected = false; t1 = tr[bar]; tb1 = (int)tb[bar]; if (tb1 == -1) continue; p1 = pk[bar]; pb1 = (int)pb[bar]; if (pb1 == -1) continue; if( tb[bar] > tb[bar-1] && pb[bar] > -1){ detected = true; }

if( pb[bar] > pb[bar-1] && tb[bar] > -1 ){ detected = true; } if( detected ) { bool isMoveUp = (tb1 < pb1); magnitude = Math.Abs( bars.High[pb1] - bars.Low[tb1] ); if( isMoveUp ) { zigBar = tb1; zagBar = pb1; inPrice = t1; outPrice = p1; } else { zigBar = pb1; zagBar = tb1; inPrice = p1; outPrice = t1; } lst.Add( new ZigZag( bar, isMoveUp, zigBar, zagBar, inPrice, outPrice, magnitude ) ); } } ZigZags = lst; Initialized = true; } catch { } } } }

Eugene
Wealth-Lab team
www.wealth-lab.com

Important Disclaimer: The information provided by Wealth-Lab is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.  The owner of Wealth-Lab.com assumes no liability resulting from the use of the material contained herein for investment purposes. By using this web site, you agree to the terms of this disclaimer and our Terms of Use.


ScrewTurn Wiki. Some of the icons created by FamFamFam.