using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators;namespace WealthLab.Strategies { public class IRSTS123Strategy : WealthScript { private StrategyParameter paramPercent; private StrategyParameter paramPT; private StrategyParameter paramSL; public IRSTS123Strategy() { paramPercent = CreateParameter("Reversal %",5.0, 1.0, 50.0, 1.0); paramPT = CreateParameter("Profit Target %",20.0,1.0,50.0,1.0); paramSL = CreateParameter("Stop Loss %",5.0,1.0,20.0,1.0); } protected override void Execute() { double percent = paramPercent.Value, target = paramPT.Value, stop = paramSL.Value; const string t = "\t"; ZZBuilder zz = new ZZBuilder( Bars, percent ); List<ZigZag> lst = zz.ZigZags; for(int bar = 1; bar < Bars.Count; bar++) { if (IsLastPositionActive) { Position p = LastPosition; double ProfitTgt = 0, StopPrice = 0; if ( p.PositionType == PositionType.Long ) { ProfitTgt = p.EntryPrice * (1 + target / 100.0d); StopPrice = p.EntryPrice * (1 - stop / 100.0d); } else { ProfitTgt = p.EntryPrice * (1 - target / 100.0d); StopPrice = p.EntryPrice * (1 + stop / 100.0d); } if(!ExitAtStop(bar + 1, p, StopPrice, "Stop Loss")) ExitAtLimit(bar + 1, p, ProfitTgt, "Profit Target"); } else { if( lst != null ) { if( lst.Count > 0 ) { int idx = 0; foreach( ZigZag z in lst ) { if( z.barDetected == bar ) { if( z.wave == Wave.W2 ) { SetBackgroundColor( bar, !z.isMoveUp ? Color.FromArgb(30,Color.Green) : Color.FromArgb(30,Color.Red) ); Position p = !z.isMoveUp ? BuyAtMarket( bar+1 ) : ShortAtMarket( bar+1 ); if( p != null ) { p.Tag = idx; } } } } } } } } HideVolume(); SetBarColors(Color.Silver,Color.Silver); } } 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; BuildZZ(); IRSTS123WaveRule(); } 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 { } } private void IRSTS123WaveRule() { if( ZigZags.Count > 0 ) { ZigZags[0].wave = Wave.W1; for( int i = 1; i < ZigZags.Count; i++ ) { ZigZag prev = ZigZags[i - 1]; ZigZag w = ZigZags[i]; switch (prev.wave) { case Wave.W1: if( i > 0 ) { if( prev.isMoveUp ) { // W2 breaks down through W1's base = new W1 down w.wave = ( w.outPrice < prev.inPrice ) ? Wave.W1 : Wave.W2; } else { // W2 breaks out through W1's base = new W1 up w.wave = ( w.outPrice > prev.inPrice ) ? Wave.W1 : Wave.W2; } } break; case Wave.W2: if( w.isMoveUp ) { // prev Up, W1 = Down if( w.outPrice >= prev.outPrice ) w.wave = Wave.W3; } else { // prev Down, W1 = Up if( w.outPrice < prev.outPrice ) w.wave = Wave.W3; } break; case Wave.W3: if( w.isMoveUp ) { // prev Up, W1 = Down if( w.outPrice > prev.outPrice ) w.wave = Wave.W2; if( w.outPrice > prev.inPrice ) w.wave = Wave.W1; } else { // prev Down, W1 = Up if( w.outPrice < prev.outPrice ) w.wave = Wave.W2; if( w.outPrice < prev.inPrice ) w.wave = Wave.W1; } break; default: if( prev.magnitude > w.magnitude ) w.wave = Wave.W1; break; } } // Wave 3 Leg count int c = 1; for(int i = 0; i < ZigZags.Count; i++ ) { ZigZag zz = ZigZags[i]; if( zz.wave == Wave.W3 ) { zz.leg3Count = c; c++; } else if( zz.wave == Wave.W1 ) c = 1; } } } } }