public bool Evaluate(ChartPattern pattern) { if (ninjaScript.CurrentBar < trendStrength || ninjaScript.CurrentBar < 2) { return(false); } if (max == null && trendStrength > 0 && (pattern == ChartPattern.HangingMan || pattern == ChartPattern.InvertedHammer)) { max = new Indicators.MAX(); max.Period = trendStrength; try { max.SetState(State.Configure); } catch (Exception exp) { Cbi.Log.Process(typeof(Resource), "CbiUnableToCreateInstance2", new object[] { max.Name, exp.InnerException != null ? exp.InnerException.ToString() : exp.ToString() }, Cbi.LogLevel.Error, Cbi.LogCategories.Default); max.SetState(State.Finalized); } max.Parent = ninjaScript; max.SetInput(ninjaScript.High); lock (ninjaScript.NinjaScripts) ninjaScript.NinjaScripts.Add(max); try { max.SetState(ninjaScript.State); } catch (Exception exp) { Cbi.Log.Process(typeof(Resource), "CbiUnableToCreateInstance2", new object[] { max.Name, exp.InnerException != null ? exp.InnerException.ToString() : exp.ToString() }, Cbi.LogLevel.Error, Cbi.LogCategories.Default); max.SetState(State.Finalized); return(false); } } if (min == null && trendStrength > 0 && pattern == ChartPattern.Hammer) { min = new MIN(); min.Period = trendStrength; try { min.SetState(State.Configure); } catch (Exception exp) { Cbi.Log.Process(typeof(Resource), "CbiUnableToCreateInstance2", new object[] { min.Name, exp.InnerException != null ? exp.InnerException.ToString() : exp.ToString() }, Cbi.LogLevel.Error, Cbi.LogCategories.Default); min.SetState(State.Finalized); } min.Parent = ninjaScript; min.SetInput(ninjaScript.Low); lock (ninjaScript.NinjaScripts) ninjaScript.NinjaScripts.Add(min); try { min.SetState(ninjaScript.State); } catch (Exception exp) { Cbi.Log.Process(typeof(Resource), "CbiUnableToCreateInstance2", new object[] { min.Name, exp.InnerException != null ? exp.InnerException.ToString() : exp.ToString() }, Cbi.LogLevel.Error, Cbi.LogCategories.Default); min.SetState(State.Finalized); return(false); } } if (pattern != ChartPattern.Doji && pattern != ChartPattern.DownsideTasukiGap && pattern != ChartPattern.EveningStar && pattern != ChartPattern.FallingThreeMethods && pattern != ChartPattern.MorningStar && pattern != ChartPattern.RisingThreeMethods && pattern != ChartPattern.StickSandwich && pattern != ChartPattern.UpsideTasukiGap) { if (trendStrength == 0) { isInDownTrend = true; isInUpTrend = true; } else { if (swing == null) { swing = new Swing(); swing.Strength = trendStrength; try { swing.SetState(State.Configure); } catch (Exception exp) { Cbi.Log.Process(typeof(Resource), "CbiUnableToCreateInstance2", new object[] { swing.Name, exp.InnerException != null ? exp.InnerException.ToString() : exp.ToString() }, Cbi.LogLevel.Error, Cbi.LogCategories.Default); swing.SetState(State.Finalized); } swing.Parent = ninjaScript; swing.SetInput(ninjaScript.Input); lock (ninjaScript.NinjaScripts) ninjaScript.NinjaScripts.Add(swing); try { swing.SetState(ninjaScript.State); } catch (Exception exp) { Cbi.Log.Process(typeof(Resource), "CbiUnableToCreateInstance2", new object[] { swing.Name, exp.InnerException != null ? exp.InnerException.ToString() : exp.ToString() }, Cbi.LogLevel.Error, Cbi.LogCategories.Default); swing.SetState(State.Finalized); return(false); } } // Calculate up trend line int upTrendStartBarsAgo = 0; int upTrendEndBarsAgo = 0; int upTrendOccurence = 1; while (ninjaScript.Low[upTrendEndBarsAgo] <= ninjaScript.Low[upTrendStartBarsAgo]) { upTrendStartBarsAgo = swing.SwingLowBar(0, upTrendOccurence + 1, ninjaScript.CurrentBar); upTrendEndBarsAgo = swing.SwingLowBar(0, upTrendOccurence, ninjaScript.CurrentBar); if (upTrendStartBarsAgo < 0 || upTrendEndBarsAgo < 0) { break; } upTrendOccurence++; } // Calculate down trend line int downTrendStartBarsAgo = 0; int downTrendEndBarsAgo = 0; int downTrendOccurence = 1; while (ninjaScript.High[downTrendEndBarsAgo] >= ninjaScript.High[downTrendStartBarsAgo]) { downTrendStartBarsAgo = swing.SwingHighBar(0, downTrendOccurence + 1, ninjaScript.CurrentBar); downTrendEndBarsAgo = swing.SwingHighBar(0, downTrendOccurence, ninjaScript.CurrentBar); if (downTrendStartBarsAgo < 0 || downTrendEndBarsAgo < 0) { break; } downTrendOccurence++; } if (upTrendStartBarsAgo > 0 && upTrendEndBarsAgo > 0 && upTrendStartBarsAgo < downTrendStartBarsAgo) { isInDownTrend = false; isInUpTrend = true; } else if (downTrendStartBarsAgo > 0 && downTrendEndBarsAgo > 0 && upTrendStartBarsAgo > downTrendStartBarsAgo) { isInDownTrend = true; isInUpTrend = false; } else { isInDownTrend = false; isInUpTrend = false; } } } bool found = false; NinjaScriptBase n = ninjaScript; if (!prior[0] && !prior[1]) // no pattern found on the last 2 bars { switch (pattern) { case ChartPattern.BearishBeltHold: found = isInUpTrend && n.Close[1] > n.Open[1] && n.Open[0] > n.Close[1] + 5 * n.TickSize && n.Open[0] == n.High[0] && n.Close[0] < n.Open[0]; break; case ChartPattern.BearishEngulfing: found = isInUpTrend && n.Close[1] > n.Open[1] && n.Close[0] < n.Open[0] && n.Open[0] > n.Close[1] && n.Close[0] < n.Open[1]; break; case ChartPattern.BearishHarami: found = isInUpTrend && n.Close[0] < n.Open[0] && n.Close[1] > n.Open[1] && n.Low[0] >= n.Open[1] && n.High[0] <= n.Close[1]; break; case ChartPattern.BearishHaramiCross: found = isInUpTrend && (n.High[0] <= n.Close[1]) && (n.Low[0] >= n.Open[1]) && n.Open[0] <= n.Close[1] && n.Close[0] >= n.Open[1] && ((n.Close[0] >= n.Open[0] && n.Close[0] <= n.Open[0] + n.TickSize) || (n.Close[0] <= n.Open[0] && n.Close[0] >= n.Open[0] - n.TickSize)); break; case ChartPattern.BullishBeltHold: found = isInDownTrend && n.Close[1] < n.Open[1] && n.Open[0] < n.Close[1] - 5 * n.TickSize && n.Open[0] == n.Low[0] && n.Close[0] > n.Open[0]; break; case ChartPattern.BullishEngulfing: found = isInDownTrend && n.Close[1] < n.Open[1] && n.Close[0] > n.Open[0] && n.Close[0] > n.Open[1] && n.Open[0] < n.Close[1]; break; case ChartPattern.BullishHarami: found = isInDownTrend && n.Close[0] > n.Open[0] && n.Close[1] < n.Open[1] && n.Low[0] >= n.Close[1] && n.High[0] <= n.Open[1]; break; case ChartPattern.BullishHaramiCross: found = isInDownTrend && (n.High[0] <= n.Open[1]) && (n.Low[0] >= n.Close[1]) && n.Open[0] >= n.Close[1] && n.Close[0] <= n.Open[1] && ((n.Close[0] >= n.Open[0] && n.Close[0] <= n.Open[0] + n.TickSize) || (n.Close[0] <= n.Open[0] && n.Close[0] >= n.Open[0] - n.TickSize)); break; case ChartPattern.DarkCloudCover: found = isInUpTrend && n.Open[0] > n.High[1] && n.Close[1] > n.Open[1] && n.Close[0] < n.Open[0] && n.Close[0] <= n.Close[1] - (n.Close[1] - n.Open[1]) / 2 && n.Close[0] >= n.Open[1]; break; case ChartPattern.Doji: found = Math.Abs(n.Close[0] - n.Open[0]) <= (n.High[0] - n.Low[0]) * 0.07; break; case ChartPattern.DownsideTasukiGap: found = n.Close[2] < n.Open[2] && n.Close[1] < n.Open[1] && n.Close[0] > n.Open[0] && n.High[1] < n.Low[2] && n.Open[0] > n.Close[1] && n.Open[0] < n.Open[1] && n.Close[0] > n.Open[1] && n.Close[0] < n.Close[2]; break; case ChartPattern.EveningStar: found = n.Close[2] > n.Open[2] && n.Close[1] > n.Close[2] && n.Open[0] < (Math.Abs((n.Close[1] - n.Open[1]) / 2) + n.Open[1]) && n.Close[0] < n.Open[0]; break; case ChartPattern.FallingThreeMethods: found = n.CurrentBar > 5 && n.Close[4] < n.Open[4] && n.Close[0] < n.Open[0] && n.Close[0] < n.Low[4] && n.High[3] < n.High[4] && n.Low[3] > n.Low[4] && n.High[2] < n.High[4] && n.Low[2] > n.Low[4] && n.High[1] < n.High[4] && n.Low[1] > n.Low[4]; break; case ChartPattern.Hammer: found = isInDownTrend && (min == null ? true : min[0] == n.Low[0]) && n.Low[0] < n.Open[0] - 5 * n.TickSize && Math.Abs(n.Open[0] - n.Close[0]) < (0.10 * (n.High[0] - n.Low[0])) && (n.High[0] - n.Close[0]) < (0.25 * (n.High[0] - n.Low[0])); break; case ChartPattern.HangingMan: found = isInUpTrend && (max == null ? true : max[0] == n.High[0]) && n.Low[0] < n.Open[0] - 5 * n.TickSize && Math.Abs(n.Open[0] - n.Close[0]) < (0.10 * (n.High[0] - n.Low[0])) && (n.High[0] - n.Close[0]) < (0.25 * (n.High[0] - n.Low[0])); break; case ChartPattern.InvertedHammer: found = isInUpTrend && (max == null ? true : max[0] == n.High[0]) && n.High[0] > n.Open[0] + 5 * n.TickSize && Math.Abs(n.Open[0] - n.Close[0]) < (0.10 * (n.High[0] - n.Low[0])) && (n.Close[0] - n.Low[0]) < (0.25 * (n.High[0] - n.Low[0])); break; case ChartPattern.MorningStar: found = n.Close[2] < n.Open[2] && n.Close[1] < n.Close[2] && n.Open[0] > (Math.Abs((n.Close[1] - n.Open[1]) / 2) + n.Open[1]) && n.Close[0] > n.Open[0]; break; case ChartPattern.PiercingLine: found = isInDownTrend && n.Open[0] < n.Low[1] && n.Close[1] < n.Open[1] && n.Close[0] > n.Open[0] && n.Close[0] >= n.Close[1] + (n.Open[1] - n.Close[1]) / 2 && n.Close[0] <= n.Open[1]; break; case ChartPattern.RisingThreeMethods: found = n.CurrentBar > 5 && n.Close[4] > n.Open[4] && n.Close[0] > n.Open[0] && n.Close[0] > n.High[4] && n.High[3] < n.High[4] && n.Low[3] > n.Low[4] && n.High[2] < n.High[4] && n.Low[2] > n.Low[4] && n.High[1] < n.High[4] && n.Low[1] > n.Low[4]; break; case ChartPattern.ShootingStar: found = isInUpTrend && n.High[0] > n.Open[0] && (n.High[0] - n.Open[0]) >= 2 * (n.Open[0] - n.Close[0]) && n.Close[0] < n.Open[0] && (n.Close[0] - n.Low[0]) <= 2 * n.TickSize; break; case ChartPattern.StickSandwich: found = n.Close[2] == n.Close[0] && n.Close[2] < n.Open[2] && n.Close[1] > n.Open[1] && n.Close[0] < n.Open[0]; break; case ChartPattern.ThreeBlackCrows: found = isInUpTrend && n.Close[0] < n.Open[0] && n.Close[1] < n.Open[1] && n.Close[2] < n.Open[2] && n.Close[0] < n.Close[1] && n.Close[1] < n.Close[2] && n.Open[0] < n.Open[1] && n.Open[0] > n.Close[1] && n.Open[1] < n.Open[2] && n.Open[1] > n.Close[2]; break; case ChartPattern.ThreeWhiteSoldiers: found = isInDownTrend && n.Close[0] > n.Open[0] && n.Close[1] > n.Open[1] && n.Close[2] > n.Open[2] && n.Close[0] > n.Close[1] && n.Close[1] > n.Close[2] && n.Open[0] < n.Close[1] && n.Open[0] > n.Open[1] && n.Open[1] < n.Close[2] && n.Open[1] > n.Open[2]; break; case ChartPattern.UpsideGapTwoCrows: found = isInUpTrend && n.Close[2] > n.Open[2] && n.Close[1] < n.Open[1] && n.Close[0] < n.Open[0] && n.Low[1] > n.High[2] && n.Close[0] > n.High[2] && n.Close[0] < n.Close[1] && n.Open[0] > n.Open[1]; break; case ChartPattern.UpsideTasukiGap: found = n.Close[2] > n.Open[2] && n.Close[1] > n.Open[1] && n.Close[0] < n.Open[0] && n.Low[1] > n.High[2] && n.Open[0] < n.Close[1] && n.Open[0] > n.Open[1] && n.Close[0] < n.Open[1] && n.Close[0] > n.Close[2]; break; } } prior[n.CurrentBars[0] % 2] = found; return(found); }