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(Openbar,Closebar) && price >= Math.Min(Openbar,Closebar); } bool Upstep( int bar, int lookback ) { bool result = false; bool way1 = (Openbar > Closebar & Openbar+1 < Closebar+1) && isInsideBody(bar, Openbar+1) && Closebar+1 > Openbar; bool way2 = (Openbar < Closebar & Openbar+1 < Closebar+1) && isInsideBody(bar, Openbar+1) && Closebar+1 > Closebar; bool way3 = (Openbar-1 > Closebar-1) && (Openbar < Closebar) && isInsideBody(bar, Openbar+1) && (Closebar > Openbar-1); bool way4 = (Openbar-1 < Closebar-1) && (Openbar < Closebar) && isInsideBody(bar, Openbar+1) && (Closebar > Closebar-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 = (Openbar < Closebar & Openbar+1 > Closebar+1) && isInsideBody(bar, Openbar+1) && Closebar+1 < Openbar; bool way2 = (Openbar > Closebar & Openbar+1 > Closebar+1) && isInsideBody(bar, Openbar+1) && Closebar+1 < Closebar; bool way3 = (Openbar-1 < Closebar-1) && (Openbar > Closebar) && isInsideBody(bar, Openbar+1) && (Closebar < Openbar-1); bool way4 = (Openbar-1 > Closebar-1) && (Openbar > Closebar) && isInsideBody(bar, Openbar+1) && (Closebar < Closebar-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 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 (BearishHaramiz.zagBar) AnnotateBar( "H", z.zagBar, true, Color.Red ); if (BearishEngulfingz.zagBar) AnnotateBar( "E", z.zagBar, true, Color.Red ); if( Upstep( z.zagBar, lookback ) ) AnnotateBar( "U", z.zagBar, false, Color.Blue ); if (BullishHaramiz.zagBar) AnnotateBar( "H", z.zagBar, false, Color.Blue ); if (BullishEngulfingz.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 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 lstX = new List(); lstX.Add( new XEvent( 0, 0 ) ); for(int bar = 1; bar < bars.Count; bar++) { if( bars.Highbar - 1 < zzbar - 1 && bars.Highbar > zzbar ) { lstX.Add( new XEvent(bar, 1) ); } if( bars.Lowbar - 1 > zzbar - 1 && bars.Lowbar < zzbar ) { 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 = lstXi; if( e.Bar == bar ) { int prevEventBar = lstXi - 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 lst = new List(); 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 = lstX0; XEvent prev = lstX0; for( int i = 0; i < lstX.Count; i++ ) { if( i == 0 ) continue; e = lstXi; prev = lstXi - 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 lst = new List(); 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 = trbar; tb1 = (int)tbbar; if (tb1 == -1) continue; p1 = pkbar; pb1 = (int)pbbar; if (pb1 == -1) continue; if( tbbar > tbbar-1 && pbbar > -1){ detected = true; } if( pbbar > pbbar-1 && tbbar > -1 ){ detected = true; } if( detected ) { bool isMoveUp = (tb1 < pb1); magnitude = Math.Abs( bars.Highpb1 - bars.Lowtb1 ); 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 { } } } }