/* TA-LIB Copyright (c) 1999-2025, Mario Fortier
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * - Neither name of author nor the names of its contributors
 *   may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Important:
 *  This file is automatically generated by the utility ta_codegen.
 *  Any modifications will be lost on next execution of ta_codegen.
 *
 *  Modifications should instead be done with the "C" source file
 *  in ta-lib\src\ta_func
 */

/* List of contributors:
 *
 *  Initial  Name/description
 *  -------------------------------------------------------------------
 *  AC       Angelo Ciceri
 *
 *
 * Change history:
 *
 *  MMDDYY BY   Description
 *  -------------------------------------------------------------------
 *  122605 AC   Creation
 */

// Import types from parent module
use super::*;

// Allow non-snake-case names to maintain TA-Lib API compatibility
#[allow(non_snake_case)]
#[allow(unused_variables)]
#[allow(dead_code)]
#[allow(unused_mut)]
#[allow(unused_assignments)]
impl Core {
    /// Lookback period for [`Core::cdlhikkakemod`]: the number of leading input values consumed
    /// before the first output value can be produced.
    pub fn cdlhikkakemod_lookback(&self) -> usize {
        #[allow(non_snake_case)]
        let Near_rangeType: i32 = self.candle_settings.near.range_type;
        #[allow(non_snake_case)]
        let Near_avgPeriod: i32 = self.candle_settings.near.avg_period;
        #[allow(non_snake_case)]
        let Near_factor: f64 = self.candle_settings.near.factor;
        return ((1).max(Near_avgPeriod) + 5) as usize;
    }
    /// A four-candle pattern: two successively narrower inside bars, then a breakout bar, with the
    /// second candle closing near one extreme of its range. Bullish or bearish reversal signal.
    /// Bullish (+) or bearish (-) reversal; per the code's note it is significant in a downtrend
    /// (bull) or uptrend (bear), context the code does not verify.
    ///
    /// # Notes
    ///
    /// * Does not verify the prior trend (downtrend for bullish, uptrend for bearish) that this
    ///   reversal pattern assumes.
    ///
    /// # Arguments
    ///
    /// * `startIdx` — Start index of the requested calculation range.
    /// * `endIdx` — End index of the requested calculation range (inclusive).
    /// * `inOpen` — Open prices per bar.
    /// * `inHigh` — High prices per bar.
    /// * `inLow` — Low prices per bar.
    /// * `inClose` — Close prices per bar.
    /// * `outBegIdx` — Set to the input index of the first output value.
    /// * `outNBElement` — Set to the number of output values written.
    /// * `outInteger` — +100 bullish hikkake bar, -100 bearish; +200 confirmed bullish, -200
    ///   confirmed bearish (confirmation adds another +/-100); 0 otherwise.
    ///
    /// # Errors
    ///
    /// Returns [`RetCode::OutOfRangeStartIndex`] when `endIdx < startIdx`.
    ///
    /// # Panics
    ///
    /// Input slices must cover `startIdx..=endIdx` and output slices must hold the number of values
    /// produced for that range: undersized slices panic or, for functions that forward to unchecked
    /// internals, cause undefined behavior. Sizing every output slice to the input length is always
    /// sufficient.
    ///
    /// # Examples
    ///
    /// ```
    /// use ta_lib::{Core, RetCode};
    ///
    /// let open: Vec<f64> = (0..252).map(|i| 100.0 + 10.0 * (0.1 * i as f64 - 0.05).sin()).collect();
    /// let high: Vec<f64> = (0..252).map(|i| 101.0 + 10.0 * (0.1 * i as f64).sin()).collect();
    /// let low: Vec<f64> = (0..252).map(|i| 99.0 + 10.0 * (0.1 * i as f64).sin()).collect();
    /// let close: Vec<f64> = (0..252).map(|i| 100.0 + 10.0 * (0.1 * i as f64).sin()).collect();
    ///
    /// let core = Core::new();
    /// let mut out_beg = 0;
    /// let mut out_nb = 0;
    /// let mut out = vec![0i32; 252];
    ///
    /// let ret = core.cdlhikkakemod(
    ///     0, open.len() - 1, &open, &high, &low, &close,
    ///     &mut out_beg, &mut out_nb, &mut out,
    /// );
    /// assert_eq!(ret, RetCode::Success);
    /// assert!(out_nb > 0);
    /// ```
    ///
    /// # See also
    ///
    /// [`Core::cdlhikkake`]
    ///
    /// Further reading:
    /// [ta-lib.org/functions/cdlhikkakemod](https://ta-lib.org/functions/cdlhikkakemod/)
    #[doc(alias = "ModifiedHikkake")]
    #[doc(alias = "ModifiedHikkakePattern")]
    pub fn cdlhikkakemod(
        &self,
        startIdx: usize,
        endIdx: usize,
        inOpen: &[f64],
        inHigh: &[f64],
        inLow: &[f64],
        inClose: &[f64],
        outBegIdx: &mut usize,
        outNBElement: &mut usize,
        outInteger: &mut [i32],
    ) -> RetCode {
        if endIdx < startIdx {
            return RetCode::OutOfRangeStartIndex;
        }
        let mut startIdx = startIdx;
        let mut NearPeriodTotal: f64 = 0.0_f64;
        let mut i: usize = 0_usize;
        let mut outIdx: usize = 0_usize;
        let mut NearTrailingIdx: usize = 0_usize;
        let mut lookbackTotal: usize = 0_usize;
        let mut patternIdx: usize = 0_usize;
        let mut patternResult: i32 = 0_i32;
        #[allow(non_snake_case)]
        let Near_rangeType: i32 = self.candle_settings.near.range_type;
        #[allow(non_snake_case)]
        let Near_avgPeriod: i32 = self.candle_settings.near.avg_period;
        #[allow(non_snake_case)]
        let Near_factor: f64 = self.candle_settings.near.factor;
        // Identify the minimum number of price bar needed
        // to calculate at least one output.
        lookbackTotal = self.cdlhikkakemod_lookback();
        // Move up the start index if there is not
        // enough initial data.
        if startIdx < lookbackTotal {
            startIdx = lookbackTotal;
        }
        // Make sure there is still something to evaluate.
        if startIdx > endIdx {
            (*outBegIdx) = 0;
            (*outNBElement) = 0;
            return RetCode::Success;
        }
        // Do the calculation using tight loops.
        // Add-up the initial period, except for the last value.
        NearPeriodTotal = 0.0;
        NearTrailingIdx = startIdx - 3 - (Near_avgPeriod) as usize;
        i = NearTrailingIdx;
        while i < startIdx - 3 {
            let mut _candlerange_0: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_0 = (inClose[i - 2] - inOpen[i - 2]).abs();
                }
                1 => {
                    _candlerange_0 = inHigh[i - 2] - inLow[i - 2];
                }
                2 => {
                    _candlerange_0 = inHigh[i - 2] - inLow[i - 2] - (inClose[i - 2] - inOpen[i - 2]).abs();
                }
                _ => {
                    _candlerange_0 = 0.0;
                }
            }
            NearPeriodTotal += _candlerange_0;
            i += 1;
        }
        patternIdx = 0;
        patternResult = 0;
        i = startIdx - 3;
        while i < startIdx {
            // copy here the pattern recognition code below
            if inHigh[i - 2] < inHigh[i - 3] &&
               inLow[i - 2] > inLow[i - 3] &&   // 2nd: lower high and higher low than 1st
               inHigh[i - 1] < inHigh[i - 2] &&
               inLow[i - 1] > inLow[i - 2] &&   // 3rd: lower high and higher low than 2nd
               (inHigh[i] < inHigh[i - 1] && inLow[i] < inLow[i - 1] && inClose[i - 2] <= inLow[i - 2] + ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (inClose[i - 2] - inOpen[i - 2]).abs(), 1 => (inHigh[i - 2]) - (inLow[i - 2]), _ => (inHigh[i - 2]) - (inLow[i - 2]) - ((inClose[i - 2]) - (inOpen[i - 2])).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) || inHigh[i] > inHigh[i - 1] && inLow[i] > inLow[i - 1] && inClose[i - 2] >= inHigh[i - 2] - ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (inClose[i - 2] - inOpen[i - 2]).abs(), 1 => (inHigh[i - 2]) - (inLow[i - 2]), _ => (inHigh[i - 2]) - (inLow[i - 2]) - ((inClose[i - 2]) - (inOpen[i - 2])).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 }))) // (bull) 4th: lower high and lower low (bull) 2nd: close near the low (bear) 4th: higher high and higher low (bull) 2nd: close near the top
            {
                patternResult = 100 * (if inHigh[i] < inHigh[i - 1] { 1 } else { 0 - 1 });
                patternIdx = i;
            } else if i <= patternIdx + 3 &&
               (patternResult > 0 && inClose[i] > inHigh[patternIdx - 1] || patternResult < 0 && inClose[i] < inLow[patternIdx - 1]) // search for confirmation if modified hikkake was no more than 3 bars ago close higher than the high of 3rd close lower than the low of 3rd
            {
                patternIdx = 0;
            }
            let mut _candlerange_1: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_1 = (inClose[i - 2] - inOpen[i - 2]).abs();
                }
                1 => {
                    _candlerange_1 = inHigh[i - 2] - inLow[i - 2];
                }
                2 => {
                    _candlerange_1 = inHigh[i - 2] - inLow[i - 2] - (inClose[i - 2] - inOpen[i - 2]).abs();
                }
                _ => {
                    _candlerange_1 = 0.0;
                }
            }
            let mut _candlerange_2: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_2 = (inClose[NearTrailingIdx - 2] - inOpen[NearTrailingIdx - 2]).abs();
                }
                1 => {
                    _candlerange_2 = inHigh[NearTrailingIdx - 2] - inLow[NearTrailingIdx - 2];
                }
                2 => {
                    _candlerange_2 = inHigh[NearTrailingIdx - 2] - inLow[NearTrailingIdx - 2] - (inClose[NearTrailingIdx - 2] - inOpen[NearTrailingIdx - 2]).abs();
                }
                _ => {
                    _candlerange_2 = 0.0;
                }
            }
            NearPeriodTotal += _candlerange_1 - _candlerange_2;
            NearTrailingIdx += 1;
            i += 1;
        }
        i = startIdx;
        // Proceed with the calculation for the requested range.
        // Must have:
        // - first candle
        // - second candle: candle with range less than first candle and close near the bottom (near the top)
        // - third candle: lower high and higher low than 2nd
        // - fourth candle: lower high and lower low (higher high and higher low) than 3rd
        // outInteger[hikkake bar] is positive (1 to 100) or negative (-1 to -100) meaning bullish or bearish hikkake
        // Confirmation could come in the next 3 days with:
        // - a day that closes higher than the high (lower than the low) of the 3rd candle
        // outInteger[confirmationbar] is equal to 100 + the bullish hikkake result or -100 - the bearish hikkake result
        // Note: if confirmation and a new hikkake come at the same bar, only the new hikkake is reported (the new hikkake
        // overwrites the confirmation of the old hikkake);
        // the user should consider that modified hikkake is a reversal pattern, while hikkake could be both a reversal
        // or a continuation pattern, so bullish (bearish) modified hikkake is significant when appearing in a downtrend
        // (uptrend)
        outIdx = 0;
        loop {
            if inHigh[i - 2] < inHigh[i - 3] &&
               inLow[i - 2] > inLow[i - 3] &&   // 2nd: lower high and higher low than 1st
               inHigh[i - 1] < inHigh[i - 2] &&
               inLow[i - 1] > inLow[i - 2] &&   // 3rd: lower high and higher low than 2nd
               (inHigh[i] < inHigh[i - 1] && inLow[i] < inLow[i - 1] && inClose[i - 2] <= inLow[i - 2] + ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (inClose[i - 2] - inOpen[i - 2]).abs(), 1 => (inHigh[i - 2]) - (inLow[i - 2]), _ => (inHigh[i - 2]) - (inLow[i - 2]) - ((inClose[i - 2]) - (inOpen[i - 2])).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) || inHigh[i] > inHigh[i - 1] && inLow[i] > inLow[i - 1] && inClose[i - 2] >= inHigh[i - 2] - ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (inClose[i - 2] - inOpen[i - 2]).abs(), 1 => (inHigh[i - 2]) - (inLow[i - 2]), _ => (inHigh[i - 2]) - (inLow[i - 2]) - ((inClose[i - 2]) - (inOpen[i - 2])).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 }))) // (bull) 4th: lower high and lower low (bull) 2nd: close near the low (bear) 4th: higher high and higher low (bull) 2nd: close near the top
            {
                patternResult = 100 * (if inHigh[i] < inHigh[i - 1] { 1 } else { 0 - 1 });
                patternIdx = i;
                outInteger[outIdx] = (patternResult) as i32;
                outIdx += 1;
            } else if i <= patternIdx + 3 &&
               (patternResult > 0 && inClose[i] > inHigh[patternIdx - 1] || patternResult < 0 && inClose[i] < inLow[patternIdx - 1]) // search for confirmation if modified hikkake was no more than 3 bars ago close higher than the high of 3rd close lower than the low of 3rd
            {
                outInteger[outIdx] = (patternResult + (100 * (if patternResult > 0 { 1 } else { 0 - 1 })) as i32) as i32;
                outIdx += 1;
                patternIdx = 0;
            } else {
                outInteger[outIdx] = 0;
                outIdx += 1;
            }
            let mut _candlerange_3: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_3 = (inClose[i - 2] - inOpen[i - 2]).abs();
                }
                1 => {
                    _candlerange_3 = inHigh[i - 2] - inLow[i - 2];
                }
                2 => {
                    _candlerange_3 = inHigh[i - 2] - inLow[i - 2] - (inClose[i - 2] - inOpen[i - 2]).abs();
                }
                _ => {
                    _candlerange_3 = 0.0;
                }
            }
            let mut _candlerange_4: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_4 = (inClose[NearTrailingIdx - 2] - inOpen[NearTrailingIdx - 2]).abs();
                }
                1 => {
                    _candlerange_4 = inHigh[NearTrailingIdx - 2] - inLow[NearTrailingIdx - 2];
                }
                2 => {
                    _candlerange_4 = inHigh[NearTrailingIdx - 2] - inLow[NearTrailingIdx - 2] - (inClose[NearTrailingIdx - 2] - inOpen[NearTrailingIdx - 2]).abs();
                }
                _ => {
                    _candlerange_4 = 0.0;
                }
            }
            NearPeriodTotal += _candlerange_3 - _candlerange_4;
            NearTrailingIdx += 1;
            i += 1;
            if !(i <= endIdx) { break; }
        }
        // All done. Indicate the output limits and return.
        (*outNBElement) = outIdx;
        (*outBegIdx) = startIdx;
        return RetCode::Success;
    }
    /// Unchecked variant of [`Core::cdlhikkakemod`], used for internal cross-indicator calls.
    ///
    /// Skips parameter validation and uses unchecked indexing internally. Every argument must
    /// satisfy the constraints documented on [`Core::cdlhikkakemod`]; an out-of-range parameter, an
    /// input slice not covering `startIdx..=endIdx`, or an undersized output slice may panic or
    /// cause undefined behavior. Prefer [`Core::cdlhikkakemod`].
    #[inline]
    pub fn cdlhikkakemod_unguarded(
        &self,
        mut startIdx: usize,
        endIdx: usize,
        inOpen: &[f64],
        inHigh: &[f64],
        inLow: &[f64],
        inClose: &[f64],
        outBegIdx: &mut usize,
        outNBElement: &mut usize,
        outInteger: &mut [i32],
    ) -> RetCode {
        let mut NearPeriodTotal: f64 = 0.0_f64;
        let mut i: usize = 0_usize;
        let mut outIdx: usize = 0_usize;
        let mut NearTrailingIdx: usize = 0_usize;
        let mut lookbackTotal: usize = 0_usize;
        let mut patternIdx: usize = 0_usize;
        let mut patternResult: i32 = 0_i32;
        #[allow(non_snake_case)]
        let Near_rangeType: i32 = self.candle_settings.near.range_type;
        #[allow(non_snake_case)]
        let Near_avgPeriod: i32 = self.candle_settings.near.avg_period;
        #[allow(non_snake_case)]
        let Near_factor: f64 = self.candle_settings.near.factor;
        unsafe {
        assert!(endIdx < inOpen.len());
        assert!(endIdx < inHigh.len());
        assert!(endIdx < inLow.len());
        assert!(endIdx < inClose.len());
        let _assertLb = self.cdlhikkakemod_lookback();
        let _assertStart = if startIdx > _assertLb { startIdx } else { _assertLb };
        assert!(_assertStart > endIdx || endIdx - _assertStart < outInteger.len());
        lookbackTotal = self.cdlhikkakemod_lookback();
        if startIdx < lookbackTotal {
            startIdx = lookbackTotal;
        }
        if startIdx > endIdx {
            (*outBegIdx) = 0;
            (*outNBElement) = 0;
            return RetCode::Success;
        }
        NearPeriodTotal = 0.0;
        NearTrailingIdx = startIdx - 3 - (Near_avgPeriod) as usize;
        i = NearTrailingIdx;
        while i < startIdx - 3 {
            let mut _candlerange_0: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_0 = (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs();
                }
                1 => {
                    _candlerange_0 = *inHigh.as_ptr().add(i - 2) - *inLow.as_ptr().add(i - 2);
                }
                2 => {
                    _candlerange_0 = *inHigh.as_ptr().add(i - 2) - *inLow.as_ptr().add(i - 2) - (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs();
                }
                _ => {
                    _candlerange_0 = 0.0;
                }
            }
            NearPeriodTotal += _candlerange_0;
            i += 1;
        }
        patternIdx = 0;
        patternResult = 0;
        i = startIdx - 3;
        while i < startIdx {
            if *inHigh.as_ptr().add(i - 2) < *inHigh.as_ptr().add(i - 3) && *inLow.as_ptr().add(i - 2) > *inLow.as_ptr().add(i - 3) && *inHigh.as_ptr().add(i - 1) < *inHigh.as_ptr().add(i - 2) && *inLow.as_ptr().add(i - 1) > *inLow.as_ptr().add(i - 2) && (*inHigh.as_ptr().add(i) < *inHigh.as_ptr().add(i - 1) && *inLow.as_ptr().add(i) < *inLow.as_ptr().add(i - 1) && *inClose.as_ptr().add(i - 2) <= *inLow.as_ptr().add(i - 2) + ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs(), 1 => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)), _ => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)) - ((*inClose.as_ptr().add(i - 2)) - (*inOpen.as_ptr().add(i - 2))).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) || *inHigh.as_ptr().add(i) > *inHigh.as_ptr().add(i - 1) && *inLow.as_ptr().add(i) > *inLow.as_ptr().add(i - 1) && *inClose.as_ptr().add(i - 2) >= *inHigh.as_ptr().add(i - 2) - ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs(), 1 => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)), _ => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)) - ((*inClose.as_ptr().add(i - 2)) - (*inOpen.as_ptr().add(i - 2))).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 }))) {
                patternResult = 100 * (if *inHigh.as_ptr().add(i) < *inHigh.as_ptr().add(i - 1) { 1 } else { 0 - 1 });
                patternIdx = i;
            } else if i <= patternIdx + 3 && (patternResult > 0 && *inClose.as_ptr().add(i) > *inHigh.as_ptr().add(patternIdx - 1) || patternResult < 0 && *inClose.as_ptr().add(i) < *inLow.as_ptr().add(patternIdx - 1)) {
                patternIdx = 0;
            }
            let mut _candlerange_1: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_1 = (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs();
                }
                1 => {
                    _candlerange_1 = *inHigh.as_ptr().add(i - 2) - *inLow.as_ptr().add(i - 2);
                }
                2 => {
                    _candlerange_1 = *inHigh.as_ptr().add(i - 2) - *inLow.as_ptr().add(i - 2) - (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs();
                }
                _ => {
                    _candlerange_1 = 0.0;
                }
            }
            let mut _candlerange_2: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_2 = (*inClose.as_ptr().add(NearTrailingIdx - 2) - *inOpen.as_ptr().add(NearTrailingIdx - 2)).abs();
                }
                1 => {
                    _candlerange_2 = *inHigh.as_ptr().add(NearTrailingIdx - 2) - *inLow.as_ptr().add(NearTrailingIdx - 2);
                }
                2 => {
                    _candlerange_2 = *inHigh.as_ptr().add(NearTrailingIdx - 2) - *inLow.as_ptr().add(NearTrailingIdx - 2) - (*inClose.as_ptr().add(NearTrailingIdx - 2) - *inOpen.as_ptr().add(NearTrailingIdx - 2)).abs();
                }
                _ => {
                    _candlerange_2 = 0.0;
                }
            }
            NearPeriodTotal += _candlerange_1 - _candlerange_2;
            NearTrailingIdx += 1;
            i += 1;
        }
        i = startIdx;
        outIdx = 0;
        loop {
            if *inHigh.as_ptr().add(i - 2) < *inHigh.as_ptr().add(i - 3) && *inLow.as_ptr().add(i - 2) > *inLow.as_ptr().add(i - 3) && *inHigh.as_ptr().add(i - 1) < *inHigh.as_ptr().add(i - 2) && *inLow.as_ptr().add(i - 1) > *inLow.as_ptr().add(i - 2) && (*inHigh.as_ptr().add(i) < *inHigh.as_ptr().add(i - 1) && *inLow.as_ptr().add(i) < *inLow.as_ptr().add(i - 1) && *inClose.as_ptr().add(i - 2) <= *inLow.as_ptr().add(i - 2) + ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs(), 1 => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)), _ => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)) - ((*inClose.as_ptr().add(i - 2)) - (*inOpen.as_ptr().add(i - 2))).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) || *inHigh.as_ptr().add(i) > *inHigh.as_ptr().add(i - 1) && *inLow.as_ptr().add(i) > *inLow.as_ptr().add(i - 1) && *inClose.as_ptr().add(i - 2) >= *inHigh.as_ptr().add(i - 2) - ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs(), 1 => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)), _ => (*inHigh.as_ptr().add(i - 2)) - (*inLow.as_ptr().add(i - 2)) - ((*inClose.as_ptr().add(i - 2)) - (*inOpen.as_ptr().add(i - 2))).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 }))) {
                patternResult = 100 * (if *inHigh.as_ptr().add(i) < *inHigh.as_ptr().add(i - 1) { 1 } else { 0 - 1 });
                patternIdx = i;
                *outInteger.as_mut_ptr().add(outIdx) = (patternResult) as i32;
                outIdx += 1;
            } else if i <= patternIdx + 3 && (patternResult > 0 && *inClose.as_ptr().add(i) > *inHigh.as_ptr().add(patternIdx - 1) || patternResult < 0 && *inClose.as_ptr().add(i) < *inLow.as_ptr().add(patternIdx - 1)) {
                *outInteger.as_mut_ptr().add(outIdx) = (patternResult + (100 * (if patternResult > 0 { 1 } else { 0 - 1 })) as i32) as i32;
                outIdx += 1;
                patternIdx = 0;
            } else {
                *outInteger.as_mut_ptr().add(outIdx) = 0;
                outIdx += 1;
            }
            let mut _candlerange_3: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_3 = (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs();
                }
                1 => {
                    _candlerange_3 = *inHigh.as_ptr().add(i - 2) - *inLow.as_ptr().add(i - 2);
                }
                2 => {
                    _candlerange_3 = *inHigh.as_ptr().add(i - 2) - *inLow.as_ptr().add(i - 2) - (*inClose.as_ptr().add(i - 2) - *inOpen.as_ptr().add(i - 2)).abs();
                }
                _ => {
                    _candlerange_3 = 0.0;
                }
            }
            let mut _candlerange_4: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_4 = (*inClose.as_ptr().add(NearTrailingIdx - 2) - *inOpen.as_ptr().add(NearTrailingIdx - 2)).abs();
                }
                1 => {
                    _candlerange_4 = *inHigh.as_ptr().add(NearTrailingIdx - 2) - *inLow.as_ptr().add(NearTrailingIdx - 2);
                }
                2 => {
                    _candlerange_4 = *inHigh.as_ptr().add(NearTrailingIdx - 2) - *inLow.as_ptr().add(NearTrailingIdx - 2) - (*inClose.as_ptr().add(NearTrailingIdx - 2) - *inOpen.as_ptr().add(NearTrailingIdx - 2)).abs();
                }
                _ => {
                    _candlerange_4 = 0.0;
                }
            }
            NearPeriodTotal += _candlerange_3 - _candlerange_4;
            NearTrailingIdx += 1;
            i += 1;
            if !(i <= endIdx) { break; }
        }
        (*outNBElement) = outIdx;
        (*outBegIdx) = startIdx;
        return RetCode::Success;
        } // unsafe
    }
}
/***************/
/* End of File */
/***************/
