/// <summary> /// Returns the range between an index interval in a market series /// </summary> /// <param name="bars"></param> /// <param name="startIndex">Start index</param> /// <param name="endIndex">End index</param> /// <param name="useBarBody">Use bar body (open and close) instead of shadows (high and low)</param> /// <returns>double</returns> public static double GetRange(this Bars bars, int startIndex, int endIndex, bool useBarBody = false) { double min = double.MaxValue, max = double.MinValue; for (var i = startIndex; i <= endIndex; i++) { double barLow, barHigh; if (useBarBody) { barLow = bars.GetBarType(i) == BarType.Bullish ? bars.OpenPrices[i] : bars.ClosePrices[i]; barHigh = bars.GetBarType(i) == BarType.Bullish ? bars.ClosePrices[i] : bars.OpenPrices[i]; } else { barLow = bars.LowPrices[i]; barHigh = bars.HighPrices[i]; } min = Math.Min(min, barLow); max = Math.Max(max, barHigh); } return(max - min); }
/// <summary> /// Returns True if the index bar is a three bar reversal /// </summary> /// <param name="bars"></param> /// <param name="index">The bar index number in a market series</param> /// <returns>bool</returns> public static bool IsThreeBarReversal(this Bars bars, int index) { var result = false; BarType barType = bars.GetBarType(index); BarType previousBarType = bars.GetBarType(index - 1); if (barType == BarType.Bullish && previousBarType == BarType.Bearish && bars.GetBarType(index - 2) == BarType.Bearish) { if (bars.LowPrices[index - 1] < bars.LowPrices[index - 2] && bars.LowPrices[index - 1] < bars.LowPrices[index]) { if (bars.ClosePrices[index] > bars.OpenPrices[index - 1]) { result = true; } } } else if (barType == BarType.Bearish && previousBarType == BarType.Bullish && bars.GetBarType(index - 2) == BarType.Bullish) { if (bars.HighPrices[index - 1] > bars.HighPrices[index - 2] && bars.HighPrices[index - 1] > bars.HighPrices[index]) { if (bars.ClosePrices[index] < bars.OpenPrices[index - 1]) { result = true; } } } return(result); }
/// <summary> /// Returns True if the index bar is an engulfing bar /// </summary> /// <param name="bars"></param> /// <param name="index">The bar index number in a market series</param> /// <returns>bool</returns> public static bool IsEngulfingBar(this Bars bars, int index) { double barBodyRange = bars.GetBarRange(index, true); double previousBarRange = bars.GetBarRange(index - 1); BarType barType = bars.GetBarType(index); BarType previousBarType = bars.GetBarType(index - 1); return(barBodyRange > previousBarRange && barType != previousBarType); }
/// <summary> /// Returns True if the index bar is an inside bar /// </summary> /// <param name="bars"></param> /// <param name="index">The bar index number in a market series</param> /// <returns>bool</returns> public static bool IsInsideBar(this Bars bars, int index) { BarType barType = bars.GetBarType(index); BarType previousBarType = bars.GetBarType(index - 1); if (bars.HighPrices[index] < bars.HighPrices[index - 1] && bars.LowPrices[index] > bars.LowPrices[index - 1] && barType != previousBarType) { return(true); } return(false); }
/// <summary> /// Returns the minimum bar range in a market series /// </summary> /// <param name="bars"></param> /// <param name="index">The start bar index</param> /// <param name="periods">The number of previous bars</param> /// <param name="barType">The type of bars</param> /// <param name="useBarBody">Use bar open and close price instead of high and low?</param> /// <returns>double</returns> public static double GetMinBarRange(this Bars bars, int index, int periods, BarType barType, bool useBarBody = false) { var minRange = double.MaxValue; for (var i = index; i >= index - periods; i--) { if (bars.GetBarType(i) != barType) { continue; } minRange = Math.Min(minRange, bars.GetBarRange(i, useBarBody: useBarBody)); } return(minRange); }
/// <summary> /// Returns the median bar range of x previous bars on a market series /// </summary> /// <param name="bars"></param> /// <param name="index">Bar index in market series, the calculation will begin from this bar</param> /// <param name="periods">The number of x previous bars or look back bars</param> /// <param name="barType">The type of bars</param> /// <param name="useBarBody">Use bar open and close price instead of high and low?</param> /// <returns>double</returns> public static double GetMedianBarRange(this Bars bars, int index, int periods, BarType barType, bool useBarBody = false) { var barRanges = new List <double>(); for (var iBarIndex = index; iBarIndex >= index - periods; iBarIndex--) { if (bars.GetBarType(iBarIndex) != barType) { continue; } double iBarRange = bars.GetBarRange(iBarIndex, useBarBody); barRanges.Add(iBarRange); } return(barRanges.Median()); }
/// <summary> /// Returns True if the index bar is a rejection bar /// </summary> /// <param name="bars"></param> /// <param name="index">The bar index number in a market series</param> /// <returns>bool</returns> public static bool IsRejectionBar(this Bars bars, int index) { double barBodyRange = bars.GetBarRange(index, true); double barRange = bars.GetBarRange(index); BarType barType = bars.GetBarType(index); double meanBarRange = bars.GetAverageBarRange(index - 1, 50); if (barBodyRange / barRange < 0.3 && barRange > meanBarRange) { var barMiddle = barRange * 0.5 + bars.LowPrices[index]; var barFirstQuartile = barRange * 0.25 + bars.LowPrices[index]; var barThirdQuartile = barRange * 0.75 + bars.LowPrices[index]; if (bars.OpenPrices[index] > barMiddle && bars.ClosePrices[index] > barThirdQuartile && barType == BarType.Bullish || bars.OpenPrices[index] < barMiddle && bars.ClosePrices[index] < barFirstQuartile && barType == BarType.Bearish) { return(true); } } return(false); }