/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _equalAveragePeriod) { _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]); } return 0m; } decimal value; if ( // first black GetCandleColor(window[1]) == CandleColor.Black && // second black GetCandleColor(input) == CandleColor.Black && // 1st and 2nd same close input.Close <= window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) && input.Close >= window[1].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) - GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return 0m; } decimal value; if (GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && GetUpperShadow(input) > GetRealBody(input) && GetLowerShadow(input) > GetRealBody(input) ) value = (int)GetCandleColor(input); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[4]); } return 0m; } decimal value; if ( // 1st long GetRealBody(window[4]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[4]) && // 1st, 2nd, 4th same color, 5th opposite GetCandleColor(window[4]) == GetCandleColor(window[3]) && GetCandleColor(window[3]) == GetCandleColor(window[1]) && (int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) && ( ( // when 1st is black: GetCandleColor(window[4]) == CandleColor.Black && // 2nd gaps down GetRealBodyGapDown(window[3], window[4]) && // 3rd has lower high and low than 2nd window[2].High < window[3].High && window[2].Low < window[3].Low && // 4th has lower high and low than 3rd window[1].High < window[2].High && window[1].Low < window[2].Low && // 5th closes inside the gap input.Close > window[3].Open && input.Close < window[4].Close ) || ( // when 1st is white: GetCandleColor(window[4]) == CandleColor.White && // 2nd gaps up GetRealBodyGapUp(window[3], window[4]) && // 3rd has higher high and low than 2nd window[2].High > window[3].High && window[2].Low > window[3].Low && // 4th has higher high and low than 3rd window[1].High > window[2].High && window[1].Low > window[2].Low && // 5th closes inside the gap input.Close < window[3].Open && input.Close > window[4].Close ) ) ) value = (int)GetCandleColor(input); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[4]) - GetCandleRange(CandleSettingType.BodyLong, window[4 + _bodyLongAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { return 0m; } decimal value; if ( // white engulfs black (GetCandleColor(input) == CandleColor.White && GetCandleColor(window[1]) == CandleColor.Black && input.Close > window[1].Open && input.Open < window[1].Close ) || // black engulfs white (GetCandleColor(input) == CandleColor.Black && GetCandleColor(window[1]) == CandleColor.White && input.Open > window[1].Close && input.Close < window[1].Open ) ) value = (int)GetCandleColor(input); else value = 0; return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { return 0m; } decimal value; if ( ( // white engulfs black GetCandleColor(window[1]) == CandleColor.White && GetCandleColor(window[2]) == CandleColor.Black && window[1].Close > window[2].Open && window[1].Open < window[2].Close && // third candle higher input.Close > window[1].Close ) || ( // black engulfs white GetCandleColor(window[1]) == CandleColor.Black && GetCandleColor(window[2]) == CandleColor.White && window[1].Open > window[2].Close && window[1].Close < window[2].Open && // third candle lower input.Close < window[1].Close ) ) value = (int)GetCandleColor(window[1]); else value = 0; return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } if (Samples >= Period - _shadowLongAveragePeriod) { _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input); } if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input); } if (Samples >= Period - _nearAveragePeriod - 1 && Samples < Period - 1) { _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input); } return 0m; } decimal value; if ( // small rb GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && // long lower shadow GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) && // very short upper shadow GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) && // rb near the prior candle's lows Math.Min(input.Close, input.Open) <= window[1].Low + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) - GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]); _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]); _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) - GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod + 1]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _nearAveragePeriod) { _nearPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]); } return 0m; } decimal value; if ( ( // upside gap GetRealBodyGapUp(window[1], window[2]) && // 1st: white GetCandleColor(window[1]) == CandleColor.White && // 2nd: black GetCandleColor(input) == CandleColor.Black && // that opens within the white rb input.Open < window[1].Close && input.Open > window[1].Open && // and closes under the white rb input.Close < window[1].Open && // inside the gap input.Close > Math.Max(window[2].Close, window[2].Open) && // size of 2 rb near the same Math.Abs(GetRealBody(window[1]) - GetRealBody(input)) < GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) ) || ( // downside gap GetRealBodyGapDown(window[1], window[2]) && // 1st: black GetCandleColor(window[1]) == CandleColor.Black && // 2nd: white GetCandleColor(input) == CandleColor.White && // that opens within the black rb input.Open < window[1].Open && input.Open > window[1].Close && // and closes above the black rb input.Close > window[1].Open && // inside the gap input.Close < Math.Min(window[2].Close, window[2].Open) && // size of 2 rb near the same Math.Abs(GetRealBody(window[1]) - GetRealBody(input)) < GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) ) ) value = (int)GetCandleColor(window[1]); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) - GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod + 1]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } if (Samples >= Period - _shadowLongAveragePeriod) { _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input); } if (Samples >= Period - _nearAveragePeriod) { _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input); } return 0m; } decimal value; if ( // doji GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && // long shadow GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) && // long shadow GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) && // body near midpoint ( Math.Min(input.Open, input.Close) <= input.Low + GetHighLowRange(input) / 2 + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, input) && Math.Max(input.Open, input.Close) >= input.Low + GetHighLowRange(input) / 2 - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, input) ) ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) - GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]); _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, input) - GetCandleRange(CandleSettingType.Near, window[_nearAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[2]); _shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]); _shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input); } return 0m; } decimal value; if ( // white GetCandleColor(window[3]) == CandleColor.White && // 1st black GetCandleColor(window[2]) == CandleColor.Black && // very short lower shadow GetLowerShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) && // 2nd black GetCandleColor(window[1]) == CandleColor.Black && // very short lower shadow GetLowerShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) && // 3rd black GetCandleColor(input) == CandleColor.Black && // very short lower shadow GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) && // 2nd black opens within 1st black's rb window[1].Open < window[2].Open && window[1].Open > window[2].Close && // 3rd black opens within 2nd black's rb input.Open < window[1].Open && input.Open > window[1].Close && // 1st black closes under prior candle's high window[3].High > window[2].Close && // three declining window[2].Close > window[1].Close && // three declining window[1].Close > input.Close ) value = -1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) for (var i = 2; i >= 0; i--) { _shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]); } return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]); _shadowVeryShortPeriodTotal[0] += GetCandleRange(CandleSettingType.ShadowVeryShort, input); } if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]); _bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input); } return 0m; } decimal value; if ( // opposite candles (int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) && // 1st marubozu GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) && GetUpperShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) && GetLowerShadow(window[1]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) && // 2nd marubozu GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) && GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) && GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[0], input) && // gap ( (GetCandleColor(window[1]) == CandleColor.Black && GetCandleGapUp(input, window[1])) || (GetCandleColor(window[1]) == CandleColor.White && GetCandleGapDown(input, window[1])) ) ) value = (int)GetCandleColor(input); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) for (var i = 1; i >= 0; i--) { _shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]); _bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) - GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]); } return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal[3] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[3]); _shadowVeryShortPeriodTotal[2] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[2]); _shadowVeryShortPeriodTotal[1] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]); } return 0m; } decimal value; if ( // 1st black GetCandleColor(window[3]) == CandleColor.Black && // 2nd black GetCandleColor(window[2]) == CandleColor.Black && // 3rd black GetCandleColor(window[1]) == CandleColor.Black && // 4th black GetCandleColor(input) == CandleColor.Black && // 1st: marubozu GetLowerShadow(window[3]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[3], window[3]) && GetUpperShadow(window[3]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[3], window[3]) && // 2nd: marubozu GetLowerShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) && GetUpperShadow(window[2]) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[2], window[2]) && // 3rd: opens gapping down GetRealBodyGapDown(window[1], window[2]) && // and has an upper shadow GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal[1], window[1]) && // that extends into the prior body window[1].High > window[2].Close && // 4th: engulfs the 3rd including the shadows input.High > window[1].High && input.Low < window[1].Low ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) for (var i = 3; i >= 1; i--) { _shadowVeryShortPeriodTotal[i] += GetCandleRange(CandleSettingType.ShadowVeryShort, window[i]) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[i + _shadowVeryShortAveragePeriod]); } return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyShortAveragePeriod - 1 && Samples < Period - 1) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); _bodyShortPeriodTotal2 += GetCandleRange(CandleSettingType.BodyShort, window[1]); } return 0m; } decimal value; if ( // 1st: long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // black GetCandleColor(window[2]) == CandleColor.Black && // 2nd: short GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) && // gapping down GetRealBodyGapDown(window[1], window[2]) && // 3rd: longer than short GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal2, input) && // white real body GetCandleColor(input) == CandleColor.White && // closing well within 1st rb input.Close > window[2].Close + GetRealBody(window[2]) * _penetration ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]); _bodyShortPeriodTotal2 += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input value to this indicator on this time step</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input) { Average.Update(input); var absoluteChange = base.ComputeNextValue(window, input); if (Average == 0m) { return 0m; } return absoluteChange/Average; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyShortAveragePeriod - 1 && Samples < Period - 1) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return 0m; } decimal value; if ( // 1st: white GetCandleColor(window[2]) == CandleColor.White && // long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // 2nd: black GetCandleColor(window[1]) == CandleColor.Black && // short GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) && // gapping up GetRealBodyGapUp(window[1], window[2]) && // 3rd: black GetCandleColor(input) == CandleColor.Black && // 3rd: engulfing prior rb input.Open > window[1].Open && input.Close < window[1].Close && // closing above 1st input.Close > window[2].Close ) value = -1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return 0m; } decimal value; if ( // 1st: long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // black GetCandleColor(window[2]) == CandleColor.Black && // 2nd: black GetCandleColor(window[1]) == CandleColor.Black && // harami window[1].Close > window[2].Close && window[1].Open <= window[2].Open && // lower low window[1].Low < window[2].Low && // 3rd: short GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && // white GetCandleColor(input) == CandleColor.White && // open not lower input.Open > window[1].Low ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 2]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } if (Samples >= Period - _shadowLongAveragePeriod) { _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input); } if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input); } return 0m; } decimal value; if ( // small rb GetRealBody(input) < GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && // long upper shadow GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) && // very short lower shadow GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) && // gap down GetRealBodyGapDown(input, window[1]) ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) - GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]); _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]); _bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input); } return(0m); } decimal value; if ( // 1st: black GetCandleColor(window[1]) == CandleColor.Black && // long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) && // 2nd: white GetCandleColor(input) == CandleColor.White && // long GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) && // open below prior low input.Open < window[1].Low && // close within prior body input.Close <window[1].Open && // above midpoint input.Close> window[1].Close + GetRealBody(window[1]) * 0.5m ) { value = 1m; } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) for (var i = 1; i >= 0; i--) { _bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) - GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]); } return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _nearAveragePeriod) { _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]); } if (Samples >= Period - _equalAveragePeriod) { _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]); } return 0m; } decimal value; if ( ( // upside or downside gap between the 1st candle and both the next 2 candles (GetRealBodyGapUp(window[1], window[2]) && GetRealBodyGapUp(input, window[2])) || (GetRealBodyGapDown(window[1], window[2]) && GetRealBodyGapDown(input, window[2])) ) && // 2nd: white GetCandleColor(window[1]) == CandleColor.White && // 3rd: white GetCandleColor(input) == CandleColor.White && // same size 2 and 3 GetRealBody(input) >= GetRealBody(window[1]) - GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) && GetRealBody(input) <= GetRealBody(window[1]) + GetCandleAverage(CandleSettingType.Near, _nearPeriodTotal, window[1]) && // same open 2 and 3 input.Open >= window[1].Open - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) && input.Open <= window[1].Open + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) ) value = GetRealBodyGapUp(window[1], window[2]) ? 1m : -1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _nearPeriodTotal += GetCandleRange(CandleSettingType.Near, window[1]) - GetCandleRange(CandleSettingType.Near, window[1 + _nearAveragePeriod]); _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) - GetCandleRange(CandleSettingType.Equal, window[1 + _equalAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input); } if (Samples >= Period - _shadowVeryLongAveragePeriod) { _shadowVeryLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryLong, input); } return(0m); } decimal value; if (GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) && GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowVeryLong, _shadowVeryLongPeriodTotal, input) ) { value = 1m; } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]); _shadowVeryLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryLong, input) - GetCandleRange(CandleSettingType.ShadowVeryLong, window[_shadowVeryLongAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]); _bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input); } return(Constants.Zero); } double value; if ( // 1st: black GetCandleColor(window[1]) == CandleColor.Black && // long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) && // 2nd: white GetCandleColor(input) == CandleColor.White && // long GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) && // open below prior low input.Open < window[1].Low && // close within prior body input[CloseIdx] < window[1].Open && // above midpoint input[CloseIdx] > window[1].Close + GetRealBody(window[1]) * 0.5d ) { value = 1d; } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) for (var i = 1; i >= 0; i--) { _bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) - GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]); } return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]); } return(0m); } decimal value; if ( // 3 black candlesticks GetCandleColor(window[4]) == CandleColor.Black && GetCandleColor(window[3]) == CandleColor.Black && GetCandleColor(window[2]) == CandleColor.Black && // with consecutively lower opens window[4].Open > window[3].Open && window[3].Open > window[2].Open && // and closes window[4].Close > window[3].Close && window[3].Close > window[2].Close && // 4th: black with an upper shadow GetCandleColor(window[1]) == CandleColor.Black && GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, window[1]) && // 5th: white GetCandleColor(input) == CandleColor.White && // that opens above prior candle's body input.Open > window[1].Open && // and closes above prior candle's high input.Close > window[1].High ) { value = 1m; } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod + 1]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return(Constants.Zero); } double value; if ( // 1st: long real body GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: doji GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && // that gaps up if 1st is white ((GetCandleColor(window[1]) == CandleColor.White && GetRealBodyGapUp(input, window[1])) || // or down if 1st is black (GetCandleColor(window[1]) == CandleColor.Black && GetRealBodyGapDown(input, window[1])) )) { value = -(int)GetCandleColor(window[1]); } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]); } return(Constants.Zero); } double value; if ( // 3 black candlesticks GetCandleColor(window[4]) == CandleColor.Black && GetCandleColor(window[3]) == CandleColor.Black && GetCandleColor(window[2]) == CandleColor.Black && // with consecutively lower opens window[4].Open > window[3].Open && window[3].Open > window[2].Open && // and closes window[4].Close > window[3].Close && window[3].Close > window[2].Close && // 4th: black with an upper shadow GetCandleColor(window[1]) == CandleColor.Black && GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, window[1]) && // 5th: white GetCandleColor(input) == CandleColor.White && // that opens above prior candle's body input.Open > window[1].Open && // and closes above prior candle's high input[CloseIdx] > window[1].High ) { value = 1d; } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod + 1]); return(value); }
/// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input value to this indicator on this time step</param> /// <returns> /// A new value for this indicator /// </returns> /// <exception cref="System.NotImplementedException"></exception> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { if (!IsReady) { return(input); } var alma = decimal.Zero; for (var i = 0; i < window.Count; i++) { alma += window[i].Price * weightVector[i]; } return(alma); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input); } return 0m; } decimal value; if ( // long body GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, input) && ( ( // white body and very short upper shadow GetCandleColor(input) == CandleColor.White && GetUpperShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) ) || ( // black body and very short lower shadow GetCandleColor(input) == CandleColor.Black && GetLowerShadow(input) < GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, input) ) )) value = (int)GetCandleColor(input); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod]); _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, input) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _equalAveragePeriod) { _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]); } if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]); _bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input); } return 0m; } decimal value; if ( // opposite candles (int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) && // 1st long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) && // 2nd long GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) && // equal closes input.Close <= window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) && input.Close >= window[1].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) ) value = (int)GetCandleColor(input); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, input) - GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]); for (var i = 1; i >= 0; i--) { _bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) - GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]); } return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyDojiAveragePeriod - 2 && Samples < Period - 2) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return 0m; } decimal value; if ( // 1st: doji GetRealBody(window[2]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[2]) && // 2nd: doji GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[2]) && // 3rd: doji GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[2])) { value = 0; if ( // 2nd gaps up GetRealBodyGapUp(window[1], window[2]) && // 3rd is not higher than 2nd Math.Max(input.Open, input.Close) < Math.Max(window[1].Open, window[1].Close) ) value = -1m; if ( // 2nd gaps down GetRealBodyGapDown(window[1], window[2]) && // 3rd is not lower than 2nd Math.Min(input.Open, input.Close) > Math.Min(window[1].Open, window[1].Close) ) value = 1m; } else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[2]) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod + 2]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return(Constants.Zero); } double value; if ( // 1st: long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: doji GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && // engulfed by 1st Math.Max(input[CloseIdx], input.Open) < Math.Max(window[1].Close, window[1].Open) && Math.Min(input[CloseIdx], input.Open) > Math.Min(window[1].Close, window[1].Open) ) { value = -(int)GetCandleColor(window[1]); } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return(0m); } decimal value; if ( // 1st: long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: short GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && // engulfed by 1st Math.Max(input.Close, input.Open) < Math.Max(window[1].Close, window[1].Open) && Math.Min(input.Close, input.Open) > Math.Min(window[1].Close, window[1].Open) ) { value = -(int)GetCandleColor(window[1]); } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyShortAveragePeriod - 1 && Samples < Period - 1) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return 0m; } decimal value; if ( // 1st: long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // 2nd: short GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, window[1]) && // engulfed by 1st Math.Max(window[1].Close, window[1].Open) < Math.Max(window[2].Close, window[2].Open) && Math.Min(window[1].Close, window[1].Open) > Math.Min(window[2].Close, window[2].Open) && // 3rd: opposite to 1st ((GetCandleColor(window[2]) == CandleColor.White && GetCandleColor(input) == CandleColor.Black && input.Close < window[2].Open) || // and closing out (GetCandleColor(window[2]) == CandleColor.Black && GetCandleColor(input) == CandleColor.White && input.Close > window[2].Open) ) ) value = -(int)GetCandleColor(window[2]); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, window[1]) - GetCandleRange(CandleSettingType.BodyShort, window[1 + _bodyShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _equalAveragePeriod) { _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]); } if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]); } return 0m; } decimal value; if ( // 1st: black GetCandleColor(window[1]) == CandleColor.Black && // long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: white GetCandleColor(input) == CandleColor.White && // open below prior low input.Open < window[1].Low && // close into prior body input.Close > window[1].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[1]) && // under the midpoint input.Close <= window[1].Close + GetRealBody(window[1]) * 0.5m ) value = -1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[1]) - GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 1]); _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]); } if (Samples >= Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return 0m; } decimal value; if ( // 1st black GetCandleColor(window[1]) == CandleColor.Black && // 2nd black GetCandleColor(input) == CandleColor.Black && // 1st long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd short GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && // 2nd engulfed by 1st input.Open < window[1].Open && input.Close > window[1].Close ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } return(Constants.Zero); } double value; if ( // 1st: white GetCandleColor(window[2]) == CandleColor.White && // long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // 2nd: black GetCandleColor(window[1]) == CandleColor.Black && // gapping up GetRealBodyGapUp(window[1], window[2]) && // 3rd: black GetCandleColor(input) == CandleColor.Black && // opening within 2nd rb input.Open <window[1].Open && input.Open> window[1].Close && // closing within 1st rb input[CloseIdx] > window[2].Open && input[CloseIdx] < window[2].Close ) { value = -1d; } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { if (window.Count >= 3) { _multipliedDiffWindow.Add((window[0] - window[1]) * (window[1] - window[2])); } // Estimate the indicator if less than 50% of observation are zero. Avoid division by // zero and estimations with few real observations in case of forward filled data. if (IsReady && _multipliedDiffWindow.Count(obs => obs == 0) < 0.5 * _multipliedDiffWindow.Count) { var mc = _multipliedDiffWindow.Count(obs => obs > 0); var mRc = _multipliedDiffWindow.Count(obs => obs < 0); return(100m * mc / (mc + mRc)); } return(50m); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 2 && Samples < Period - 2) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } return(0m); } decimal value; if ( // 1st: white GetCandleColor(window[2]) == CandleColor.White && // long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // 2nd: black GetCandleColor(window[1]) == CandleColor.Black && // gapping up GetRealBodyGapUp(window[1], window[2]) && // 3rd: black GetCandleColor(input) == CandleColor.Black && // opening within 2nd rb input.Open <window[1].Open && input.Open> window[1].Close && // closing within 1st rb input.Close > window[2].Open && input.Close < window[2].Close ) { value = -1m; } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[2 + _bodyLongAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal[1] += GetCandleRange(CandleSettingType.BodyLong, window[1]); _bodyLongPeriodTotal[0] += GetCandleRange(CandleSettingType.BodyLong, input); } return 0m; } decimal value; if ( // 1st: black GetCandleColor(window[1]) == CandleColor.Black && // long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[1], window[1]) && // 2nd: white GetCandleColor(input) == CandleColor.White && // long GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal[0], input) && // open below prior low input.Open < window[1].Low && // close within prior body input.Close < window[1].Open && // above midpoint input.Close > window[1].Close + GetRealBody(window[1]) * 0.5m ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) for (var i = 1; i >= 0; i--) { _bodyLongPeriodTotal[i] += GetCandleRange(CandleSettingType.BodyLong, window[i]) - GetCandleRange(CandleSettingType.BodyLong, window[i + _bodyLongAveragePeriod]); } return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input) { // Until the window is ready, the indicator returns the input value. if (window.Samples <= window.Size) return input; // Sort the window by time, convert the observations to double and transform it to an array var series = window .OrderBy(i => i.Time) .Select(i => Convert.ToDouble(i.Value)) .ToArray(); // Fit OLS var ols = Fit.Line(x: t, y: series); Intercept.Update(input.Time, (decimal)ols.Item1); Slope.Update(input.Time, (decimal)ols.Item2); // Calculate the fitted value corresponding to the input return Intercept + Slope * Period; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window"></param> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (window.Count >= 3) { _multipliedDiffWindow.Add((window[0].Value - window[1].Value) * (window[1].Value - window[2].Value)); } // Estimate the indicator if less than 50% of observation are zero. Avoid division by // zero and estimations with few real observations in case of forward filled data. if (IsReady && _multipliedDiffWindow.Count(obs => Math.Abs(obs) < ZeroEpsilon) < 0.5 * _multipliedDiffWindow.Count) { var mc = _multipliedDiffWindow.Count(obs => obs > 0); var mRc = _multipliedDiffWindow.Count(obs => obs < 0); return(100.0d * mc / (mc + mRc)); } return(50.0d); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _shadowVeryShortAveragePeriod) { _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]); } return 0m; } decimal value; if ( // 3 black candlesticks GetCandleColor(window[4]) == CandleColor.Black && GetCandleColor(window[3]) == CandleColor.Black && GetCandleColor(window[2]) == CandleColor.Black && // with consecutively lower opens window[4].Open > window[3].Open && window[3].Open > window[2].Open && // and closes window[4].Close > window[3].Close && window[3].Close > window[2].Close && // 4th: black with an upper shadow GetCandleColor(window[1]) == CandleColor.Black && GetUpperShadow(window[1]) > GetCandleAverage(CandleSettingType.ShadowVeryShort, _shadowVeryShortPeriodTotal, window[1]) && // 5th: white GetCandleColor(input) == CandleColor.White && // that opens above prior candle's body input.Open > window[1].Open && // and closes above prior candle's high input.Close > window[1].High ) value = 1m; else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _shadowVeryShortPeriodTotal += GetCandleRange(CandleSettingType.ShadowVeryShort, window[1]) - GetCandleRange(CandleSettingType.ShadowVeryShort, window[_shadowVeryShortAveragePeriod + 1]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return 0m; } decimal value; if ( // 1st: long real body GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: doji GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && // that gaps up if 1st is white ((GetCandleColor(window[1]) == CandleColor.White && GetRealBodyGapUp(input, window[1])) || // or down if 1st is black (GetCandleColor(window[1]) == CandleColor.Black && GetRealBodyGapDown(input, window[1])) )) value = -(int)GetCandleColor(window[1]); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } if (Samples >= Period - _shadowLongAveragePeriod) { _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input); } return(Constants.Zero); } double value; if (GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && (GetLowerShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) || GetUpperShadow(input) > GetCandleAverage(CandleSettingType.ShadowLong, _shadowLongPeriodTotal, input) ) ) { value = 1d; } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); _shadowLongPeriodTotal += GetCandleRange(CandleSettingType.ShadowLong, input) - GetCandleRange(CandleSettingType.ShadowLong, window[_shadowLongAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <TradeBar> window, TradeBar input) { if (!IsReady) { return(0m); } decimal value; if ( // 1st and 2nd of same color GetCandleColor(window[2]) == GetCandleColor(window[1]) && // 3rd opposite color (int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) && // 3rd opens within 2nd rb input.Open <Math.Max(window[1].Close, window[1].Open) && input.Open> Math.Min(window[1].Close, window[1].Open) && // 3rd closes within 1st rb input.Close <Math.Max(window[2].Close, window[2].Open) && input.Close> Math.Min(window[2].Close, window[2].Open) && (( // when 1st is white GetCandleColor(window[2]) == CandleColor.White && // upside gap GetRealBodyGapUp(window[1], window[2]) ) || ( // when 1st is black GetCandleColor(window[2]) == CandleColor.Black && // downside gap GetRealBodyGapDown(window[1], window[2]) ) ) ) { value = (int)GetCandleColor(window[2]); } else { value = 0; } return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { return(Constants.Zero); } double value; if ( // 1st and 2nd of same color GetCandleColor(window[2]) == GetCandleColor(window[1]) && // 3rd opposite color (int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) && // 3rd opens within 2nd rb input.Open <Math.Max(window[1].Close, window[1].Open) && input.Open> Math.Min(window[1].Close, window[1].Open) && // 3rd closes within 1st rb input[CloseIdx] < Math.Max(window[2].Close, window[2].Open) && input[CloseIdx] > Math.Min(window[2].Close, window[2].Open) && (( // when 1st is white GetCandleColor(window[2]) == CandleColor.White && // upside gap GetRealBodyGapUp(window[1], window[2]) ) || ( // when 1st is black GetCandleColor(window[2]) == CandleColor.Black && // downside gap GetRealBodyGapDown(window[1], window[2]) ) ) ) { value = (int)GetCandleColor(window[2]); } else { value = 0; } return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <DataPointBar> window, DataPointBar input) { if (!IsReady) { if (Samples >= Period - _equalAveragePeriod) { _equalPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]); } return(0m); } decimal value; if ( // first black GetCandleColor(window[2]) == CandleColor.Black && // second white GetCandleColor(window[1]) == CandleColor.White && // third black GetCandleColor(input) == CandleColor.Black && // 2nd low > prior close window[1].Low > window[2].Close && // 1st and 3rd same close input.Close <= window[2].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[2]) && input.Close >= window[2].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[2]) ) { value = 1m; } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[2]) - GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 2]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]); } return(0m); } decimal value; if ( // 1st: white GetCandleColor(window[1]) == CandleColor.White && // long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: black GetCandleColor(input) == CandleColor.Black && // open above prior high input.Open > window[1].High && // close within prior body input.Close > window[1].Open && input.Close < window[1].Close - GetRealBody(window[1]) * _penetration ) { value = -1m; } else { value = 0m; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); return(value); }
/// <summary> /// Calculates the next value for the decycle /// </summary> /// <param name="window">the window for this indicator</param> /// <param name="input">the latest price to input into the trend</param> /// <returns>the computed value</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { // for convenience DateTime time = input.Time; _price.Add(input); if (!_price.IsReady) { _decycle.Add(input); } else { decimal decycle = alpha / 2 * (_price[0] + _price[1]) + (1 - alpha) * _decycle[1]; _decycle.Add(idp(time, decycle)); } return(_decycle[0]); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window of data held in this indicator</param> /// <param name="time"></param> /// <param name="input"></param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (!IsReady) { if (Samples >= Period - _equalAveragePeriod) { _equalPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]); } return(Constants.Zero); } double value; if ( // first black GetCandleColor(window[2]) == CandleColor.Black && // second white GetCandleColor(window[1]) == CandleColor.White && // third black GetCandleColor(input) == CandleColor.Black && // 2nd low > prior close window[1].Low > window[2].Close && // 1st and 3rd same close input[CloseIdx] <= window[2].Close + GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[2]) && input[CloseIdx] >= window[2].Close - GetCandleAverage(CandleSettingType.Equal, _equalPeriodTotal, window[2]) ) { value = 1d; } else { value = Constants.Zero; } // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _equalPeriodTotal += GetCandleRange(CandleSettingType.Equal, window[2]) - GetCandleRange(CandleSettingType.Equal, window[_equalAveragePeriod + 2]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { if (Samples >= Period - _bodyLongAveragePeriod - 1 && Samples < Period - 1) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, input); } if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return 0m; } decimal value; if ( // 1st: long GetRealBody(window[1]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[1]) && // 2nd: doji GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) && // engulfed by 1st Math.Max(input.Close, input.Open) < Math.Max(window[1].Close, window[1].Open) && Math.Min(input.Close, input.Open) > Math.Min(window[1].Close, window[1].Open) ) value = -(int)GetCandleColor(window[1]); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[1]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod + 1]); _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <param name="window">The window for the input history</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { _rollingSum += input.Value; _rollingSumOfSquares += input.Value * input.Value; if (Samples < Period) { return(0m); } var meanValue1 = _rollingSum / Period; var meanValue2 = _rollingSumOfSquares / Period; var removedValue = window[Period - 1]; _rollingSum -= removedValue; _rollingSumOfSquares -= removedValue * removedValue; return(meanValue2 - meanValue1 * meanValue1); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { // Until the windows is ready, the indicator returns the input value. decimal output = input; if (IsReady) { // Sort the windows by time, convert the observations ton double and transform it to a double array double[] series = window .OrderBy(i => i.Time) .Select(i => Convert.ToDouble(i.Value)) .ToArray <double>(); // Fit OLS Tuple <double, double> ols = Fit.Line(x: t, y: series); var alfa = (decimal)ols.Item1; var beta = (decimal)ols.Item2; // Make the projection. output = alfa + beta * (Period); } return(output); }
protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { var stop = 0; var src = input.Value; if (src == Src.FirstOrDefault()) { return(xEma); } Src.Add(src); if (Src.IsReady) { //PFE = sqrt(pow(close - close[Length], 2) + 100) var s1 = Src.Skip(1).FirstOrDefault(); var sL = Src.LastOrDefault(); var perfL = src - sL; PFE = Math.Sqrt((double)(perfL * perfL) + 100); //C2C = sum(sqrt(pow((close - close[1]), 2) + 1), Length) var perf1 = src - s1; var tosum = Math.Sqrt((double)(perf1 * perf1) + 1); C2C.Add(tosum); //xFracEff = iff(close - close[Length] > 0, round((PFE / C2C) * 100) , round(-(PFE / C2C) * 100)) double c2csum = 0; double xFracEff = 0; if (C2C.IsReady) { c2csum = C2C.Sum(); xFracEff = (perfL > 0) ? Math.Round(PFE / c2csum * 100) : Math.Round(-PFE / c2csum * 100); xEma.Update(input.Time, (decimal)xFracEff); } if (xEma.IsReady) { return(xEma); //Math.Min(Math.Max(xEma, -100), 100); } } return(0); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <DataPointBar> window, DataPointBar input) { if (!IsReady) { if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return(0m); } var value = GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) ? 1m : 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); return(value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples >= Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input); } return 0m; } var value = GetRealBody(input) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, input) ? 1m : 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, input) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window">The window for the input history</param> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (Samples == 1) { _prevValue = input.Value; return(Constants.Zero); } var difference = input.Value - _prevValue; _prevValue = input.Value; if (Samples > Period + 1) { _prevLoss *= (Period - 1); _prevGain *= (Period - 1); } if (difference < 0) { _prevLoss -= difference; } else { _prevGain += difference; } if (!IsReady) { return(Constants.Zero); } _prevLoss /= Period; _prevGain /= Period; var sum = _prevGain + _prevLoss; return(sum != 0 ? 100.0d * ((_prevGain - _prevLoss) / sum) : Constants.Zero); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window"></param> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { // Until the window is ready, the indicator returns the input value. if (window.Samples <= window.Size) { return(input); } // Sort the window by time, convert the observations to double and transform it to an array var series = window.Zip(timeWindow, (a, b) => (time: b, array: a)) .OrderBy(i => i.time) .Select(i => Convert.ToDouble(i.array.Value)) .ToArray(); // Fit OLS var ols = Fit.Line(x: _t, y: series); Intercept.Update(time, ols.Item1); Slope.Update(time, ols.Item2); // Calculate the fitted value corresponding to the input return(Intercept + Slope * Period); }
/// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input value to this indicator on this time step</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { decimal dominantCycle; List <double> Correlations; Vector <double> DTF; hpf.Update(input); sSmoother.Update(hpf.Current); sSmootherWindow.Add((double)sSmoother.Current.Value); if (!this.IsReady) { dominantCycle = 0m; } else { Correlations = EstimateAutocorrelations(); DTF = EstimateDFT(Correlations); dominantCycle = EstimateDominantCycle(DTF); } return(dominantCycle); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { int Mc = 0; int MRc = 0; decimal momersion = 50m; if (window.Count >= 3) { _multipliedDiffWindow.Add((window[0] - window[1]) * (window[1] - window[2])); } // Estimate the indicator if less than 50% of observation are zero. Avoid division by // zero and estimations with few real observations in case of forward filled data. if (this.IsReady && _multipliedDiffWindow.Count(obs => obs == 0) < 0.5 * _multipliedDiffWindow.Count) { Mc = _multipliedDiffWindow.Count(obs => obs > 0); MRc = _multipliedDiffWindow.Count(obs => obs < 0); momersion = 100m * Mc / (Mc + MRc); } return(momersion); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<TradeBar> window, TradeBar input) { if (!IsReady) { return 0m; } decimal value; if ( // 1st and 2nd of same color GetCandleColor(window[2]) == GetCandleColor(window[1]) && // 3rd opposite color (int)GetCandleColor(window[1]) == -(int)GetCandleColor(input) && // 3rd opens within 2nd rb input.Open < Math.Max(window[1].Close, window[1].Open) && input.Open > Math.Min(window[1].Close, window[1].Open) && // 3rd closes within 1st rb input.Close < Math.Max(window[2].Close, window[2].Open) && input.Close > Math.Min(window[2].Close, window[2].Open) && (( // when 1st is white GetCandleColor(window[2]) == CandleColor.White && // upside gap GetRealBodyGapUp(window[1], window[2]) ) || ( // when 1st is black GetCandleColor(window[2]) == CandleColor.Black && // downside gap GetRealBodyGapDown(window[1], window[2]) ) ) ) value = (int)GetCandleColor(window[2]); else value = 0; return value; }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <param name="window">The window for the input history</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { if (Samples == 1) { _prevValue = input; return(0m); } var difference = input.Value - _prevValue; _prevValue = input.Value; if (Samples > Period + 1) { _prevLoss *= (Period - 1); _prevGain *= (Period - 1); } if (difference < 0) { _prevLoss -= difference; } else { _prevGain += difference; } if (!IsReady) { return(0m); } _prevLoss /= Period; _prevGain /= Period; var sum = _prevGain + _prevLoss; return(sum != 0 ? 100m * ((_prevGain - _prevLoss) / sum) : 0m); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="window">The window of data held in this indicator</param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow<IBaseDataBar> window, IBaseDataBar input) { if (!IsReady) { if (Samples > Period - _bodyLongAveragePeriod) { _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]); } if (Samples > Period - _bodyDojiAveragePeriod) { _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[1]); } if (Samples > Period - _bodyShortAveragePeriod) { _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input); } return 0m; } decimal value; if ( // 1st: long GetRealBody(window[2]) > GetCandleAverage(CandleSettingType.BodyLong, _bodyLongPeriodTotal, window[2]) && // 2nd: doji GetRealBody(window[1]) <= GetCandleAverage(CandleSettingType.BodyDoji, _bodyDojiPeriodTotal, window[1]) && // 3rd: longer than short GetRealBody(input) > GetCandleAverage(CandleSettingType.BodyShort, _bodyShortPeriodTotal, input) && (( // 1st white GetCandleColor(window[2]) == CandleColor.White && // 3rd black GetCandleColor(input) == CandleColor.Black && // 3rd closes well within 1st rb input.Close < window[2].Close - GetRealBody(window[2]) * _penetration && // upside gap between 1st and 2nd GetCandleGapUp(window[1], window[2]) && // downside gap between 2nd and 3rd GetCandleGapDown(input, window[1]) ) || ( // 1st black GetCandleColor(window[2]) == CandleColor.Black && // 3rd white GetCandleColor(input) == CandleColor.White && // 3rd closes well within 1st rb input.Close > window[2].Close + GetRealBody(window[2]) * _penetration && // downside gap between 1st and 2nd GetCandleGapDown(window[1], window[2]) && // upside gap between 2nd and 3rd GetCandleGapUp(input, window[1]) ) ) ) value = (int)GetCandleColor(input); else value = 0m; // add the current range and subtract the first range: this is done after the pattern recognition // when avgPeriod is not 0, that means "compare with the previous candles" (it excludes the current candle) _bodyLongPeriodTotal += GetCandleRange(CandleSettingType.BodyLong, window[2]) - GetCandleRange(CandleSettingType.BodyLong, window[_bodyLongAveragePeriod - 1]); _bodyDojiPeriodTotal += GetCandleRange(CandleSettingType.BodyDoji, window[1]) - GetCandleRange(CandleSettingType.BodyDoji, window[_bodyDojiAveragePeriod]); _bodyShortPeriodTotal += GetCandleRange(CandleSettingType.BodyShort, input) - GetCandleRange(CandleSettingType.BodyShort, window[_bodyShortAveragePeriod + 1]); return value; }