/* 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
 *  -------------------------------------------------------------------
 *  121104 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::cdl3linestrike`]: the number of leading input values consumed
    /// before the first output value can be produced.
    pub fn cdl3linestrike_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 (Near_avgPeriod + 3) as usize;
    }
    /// A four-candle pattern: three same-color candles with consecutively higher (or lower) closes,
    /// each opening within or near the prior real body, then a fourth opposite-color candle that
    /// opens beyond the third close and closes past the first candle's open. TA-Lib emits a signed
    /// continuation-style signal keyed to the color of the first three candles. +100 = three-white
    /// (bullish) strike, -100 = three-black (bearish) strike; traditionally read as significant
    /// only inside a trend matching the first three candles.
    ///
    /// # Notes
    ///
    /// * Does not verify the surrounding trend the pattern classically assumes for significance.
    ///
    /// # 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 for a white (rising) three-line strike, -100 for a black (falling)
    ///   three-line strike, 0 otherwise. Sign is the color of the first three candles:
    ///   candlecolor(i-1)*100.
    ///
    /// # 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.cdl3linestrike(
    ///     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::cdl3whitesoldiers`] · [`Core::cdl3blackcrows`]
    ///
    /// Further reading:
    /// [ta-lib.org/functions/cdl3linestrike](https://ta-lib.org/functions/cdl3linestrike/)
    #[doc(alias = "Three-LineStrike")]
    #[doc(alias = "3-LineStrike")]
    pub fn cdl3linestrike(
        &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; 4 as usize] = [0.0_f64; 4 as usize];
        let mut i: usize = 0_usize;
        let mut outIdx: usize = 0_usize;
        let mut totIdx: usize = 0_usize;
        let mut NearTrailingIdx: usize = 0_usize;
        let mut lookbackTotal: usize = 0_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;
        // Identify the minimum number of price bar needed
        // to calculate at least one output.
        lookbackTotal = self.cdl3linestrike_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[3] = 0.0;
        NearPeriodTotal[2] = 0.0;
        NearTrailingIdx = startIdx - (Near_avgPeriod) as usize;
        i = NearTrailingIdx;
        while i < startIdx {
            let mut _candlerange_0: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_0 = (inClose[i - 3] - inOpen[i - 3]).abs();
                }
                1 => {
                    _candlerange_0 = inHigh[i - 3] - inLow[i - 3];
                }
                2 => {
                    _candlerange_0 = inHigh[i - 3] - inLow[i - 3] - (inClose[i - 3] - inOpen[i - 3]).abs();
                }
                _ => {
                    _candlerange_0 = 0.0;
                }
            }
            NearPeriodTotal[3] = NearPeriodTotal[3] + _candlerange_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;
                }
            }
            NearPeriodTotal[2] = NearPeriodTotal[2] + _candlerange_1;
            i += 1;
        }
        i = startIdx;
        // Proceed with the calculation for the requested range.
        // Must have:
        // - three white soldiers (three black crows): three white (black) candlesticks with consecutively higher (lower) closes,
        // each opening within or near the previous real body
        // - fourth candle: black (white) candle that opens above (below) prior candle's close and closes below (above)
        // the first candle's open
        // The meaning of "near" is specified with TA_SetCandleSettings;
        // outInteger is positive (1 to 100) when bullish or negative (-1 to -100) when bearish;
        // the user should consider that 3-line strike is significant when it appears in a trend in the same direction of
        // the first three candles, while this function does not consider it
        outIdx = 0;
        loop {
            if (if inClose[i - 3] >= inOpen[i - 3] { 1 } else { 0 - 1 }) == (if inClose[i - 2] >= inOpen[i - 2] { 1 } else { 0 - 1 }) && // three with same color
               (if inClose[i - 2] >= inOpen[i - 2] { 1 } else { 0 - 1 }) == (if inClose[i - 1] >= inOpen[i - 1] { 1 } else { 0 - 1 }) &&
               (if inClose[i] >= inOpen[i] { 1 } else { 0 - 1 }) == 0 - (if inClose[i - 1] >= inOpen[i - 1] { 1 } else { 0 - 1 }) && // 4th opposite color
               inOpen[i - 2] >= (inOpen[i - 3]).min(inClose[i - 3]) - ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal[3]) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (inClose[i - 3] - inOpen[i - 3]).abs(), 1 => (inHigh[i - 3]) - (inLow[i - 3]), _ => (inHigh[i - 3]) - (inLow[i - 3]) - ((inClose[i - 3]) - (inOpen[i - 3])).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) && // 2nd opens within/near 1st rb
               inOpen[i - 2] <= (inOpen[i - 3]).max(inClose[i - 3]) + ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal[3]) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (inClose[i - 3] - inOpen[i - 3]).abs(), 1 => (inHigh[i - 3]) - (inLow[i - 3]), _ => (inHigh[i - 3]) - (inLow[i - 3]) - ((inClose[i - 3]) - (inOpen[i - 3])).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) &&
               inOpen[i - 1] >= (inOpen[i - 2]).min(inClose[i - 2]) - ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal[2]) / (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 })) && // 3rd opens within/near 2nd rb
               inOpen[i - 1] <= (inOpen[i - 2]).max(inClose[i - 2]) + ((Near_factor) * (if (Near_avgPeriod) != 0 { (NearPeriodTotal[2]) / (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 })) &&
               ((if inClose[i - 1] >= inOpen[i - 1] { 1 } else { 0 - 1 }) == 1 && inClose[i - 1] > inClose[i - 2] && inClose[i - 2] > inClose[i - 3] && inOpen[i] > inClose[i - 1] && inClose[i] < inOpen[i - 3] || ((if inClose[i - 1] >= inOpen[i - 1] { 1 } else { 0 - 1 })) as i32 == 0 - 1 && inClose[i - 1] < inClose[i - 2] && inClose[i - 2] < inClose[i - 3] && inOpen[i] < inClose[i - 1] && inClose[i] > inOpen[i - 3]) // if three white consecutive higher closes 4th opens above prior close 4th closes below 1st open if three black consecutive lower closes 4th opens below prior close 4th closes above 1st open
            {
                outInteger[outIdx] = ((if inClose[i - 1] >= inOpen[i - 1] { 1 } else { 0 - 1 }) * 100) as i32;
                outIdx += 1;
            } else {
                outInteger[outIdx] = 0;
                outIdx += 1;
            }
            // 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( totIdx = 3; totIdx >= 2; totIdx -= 1 )
            totIdx = 3;
            loop {
                let mut _candlerange_2: f64;
                match Near_rangeType {
                    0 => {
                        _candlerange_2 = (inClose[i - totIdx] - inOpen[i - totIdx]).abs();
                    }
                    1 => {
                        _candlerange_2 = inHigh[i - totIdx] - inLow[i - totIdx];
                    }
                    2 => {
                        _candlerange_2 = inHigh[i - totIdx] - inLow[i - totIdx] - (inClose[i - totIdx] - inOpen[i - totIdx]).abs();
                    }
                    _ => {
                        _candlerange_2 = 0.0;
                    }
                }
                let mut _candlerange_3: f64;
                match Near_rangeType {
                    0 => {
                        _candlerange_3 = (inClose[NearTrailingIdx - totIdx] - inOpen[NearTrailingIdx - totIdx]).abs();
                    }
                    1 => {
                        _candlerange_3 = inHigh[NearTrailingIdx - totIdx] - inLow[NearTrailingIdx - totIdx];
                    }
                    2 => {
                        _candlerange_3 = inHigh[NearTrailingIdx - totIdx] - inLow[NearTrailingIdx - totIdx] - (inClose[NearTrailingIdx - totIdx] - inOpen[NearTrailingIdx - totIdx]).abs();
                    }
                    _ => {
                        _candlerange_3 = 0.0;
                    }
                }
                NearPeriodTotal[totIdx] = NearPeriodTotal[totIdx] + (_candlerange_2 - _candlerange_3);
                if totIdx == 2 { break; }
                totIdx -= 1;
            }
            i += 1;
            NearTrailingIdx += 1;
            if !(i <= endIdx) { break; }
        }
        // All done. Indicate the output limits and return.
        (*outNBElement) = outIdx;
        (*outBegIdx) = startIdx;
        return RetCode::Success;
    }
    /// Unchecked variant of [`Core::cdl3linestrike`], used for internal cross-indicator calls.
    ///
    /// Skips parameter validation and uses unchecked indexing internally. Every argument must
    /// satisfy the constraints documented on [`Core::cdl3linestrike`]; 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::cdl3linestrike`].
    #[inline]
    pub fn cdl3linestrike_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; 4 as usize] = [0.0_f64; 4 as usize];
        let mut i: usize = 0_usize;
        let mut outIdx: usize = 0_usize;
        let mut totIdx: usize = 0_usize;
        let mut NearTrailingIdx: usize = 0_usize;
        let mut lookbackTotal: usize = 0_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;
        unsafe {
        assert!(endIdx < inOpen.len());
        assert!(endIdx < inHigh.len());
        assert!(endIdx < inLow.len());
        assert!(endIdx < inClose.len());
        let _assertLb = self.cdl3linestrike_lookback();
        let _assertStart = if startIdx > _assertLb { startIdx } else { _assertLb };
        assert!(_assertStart > endIdx || endIdx - _assertStart < outInteger.len());
        lookbackTotal = self.cdl3linestrike_lookback();
        if startIdx < lookbackTotal {
            startIdx = lookbackTotal;
        }
        if startIdx > endIdx {
            (*outBegIdx) = 0;
            (*outNBElement) = 0;
            return RetCode::Success;
        }
        *NearPeriodTotal.as_mut_ptr().add(3) = 0.0;
        *NearPeriodTotal.as_mut_ptr().add(2) = 0.0;
        NearTrailingIdx = startIdx - (Near_avgPeriod) as usize;
        i = NearTrailingIdx;
        while i < startIdx {
            let mut _candlerange_0: f64;
            match Near_rangeType {
                0 => {
                    _candlerange_0 = (*inClose.as_ptr().add(i - 3) - *inOpen.as_ptr().add(i - 3)).abs();
                }
                1 => {
                    _candlerange_0 = *inHigh.as_ptr().add(i - 3) - *inLow.as_ptr().add(i - 3);
                }
                2 => {
                    _candlerange_0 = *inHigh.as_ptr().add(i - 3) - *inLow.as_ptr().add(i - 3) - (*inClose.as_ptr().add(i - 3) - *inOpen.as_ptr().add(i - 3)).abs();
                }
                _ => {
                    _candlerange_0 = 0.0;
                }
            }
            *NearPeriodTotal.as_mut_ptr().add(3) = *NearPeriodTotal.as_ptr().add(3) + _candlerange_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;
                }
            }
            *NearPeriodTotal.as_mut_ptr().add(2) = *NearPeriodTotal.as_ptr().add(2) + _candlerange_1;
            i += 1;
        }
        i = startIdx;
        outIdx = 0;
        loop {
            if (if *inClose.as_ptr().add(i - 3) >= *inOpen.as_ptr().add(i - 3) { 1 } else { 0 - 1 }) == (if *inClose.as_ptr().add(i - 2) >= *inOpen.as_ptr().add(i - 2) { 1 } else { 0 - 1 }) && (if *inClose.as_ptr().add(i - 2) >= *inOpen.as_ptr().add(i - 2) { 1 } else { 0 - 1 }) == (if *inClose.as_ptr().add(i - 1) >= *inOpen.as_ptr().add(i - 1) { 1 } else { 0 - 1 }) && (if *inClose.as_ptr().add(i) >= *inOpen.as_ptr().add(i) { 1 } else { 0 - 1 }) == 0 - (if *inClose.as_ptr().add(i - 1) >= *inOpen.as_ptr().add(i - 1) { 1 } else { 0 - 1 }) && *inOpen.as_ptr().add(i - 2) >= (*inOpen.as_ptr().add(i - 3)).min(*inClose.as_ptr().add(i - 3)) - ((Near_factor) * (if (Near_avgPeriod) != 0 { (*NearPeriodTotal.as_ptr().add(3)) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (*inClose.as_ptr().add(i - 3) - *inOpen.as_ptr().add(i - 3)).abs(), 1 => (*inHigh.as_ptr().add(i - 3)) - (*inLow.as_ptr().add(i - 3)), _ => (*inHigh.as_ptr().add(i - 3)) - (*inLow.as_ptr().add(i - 3)) - ((*inClose.as_ptr().add(i - 3)) - (*inOpen.as_ptr().add(i - 3))).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) && *inOpen.as_ptr().add(i - 2) <= (*inOpen.as_ptr().add(i - 3)).max(*inClose.as_ptr().add(i - 3)) + ((Near_factor) * (if (Near_avgPeriod) != 0 { (*NearPeriodTotal.as_ptr().add(3)) / (Near_avgPeriod as f64) } else { match Near_rangeType { 0 => (*inClose.as_ptr().add(i - 3) - *inOpen.as_ptr().add(i - 3)).abs(), 1 => (*inHigh.as_ptr().add(i - 3)) - (*inLow.as_ptr().add(i - 3)), _ => (*inHigh.as_ptr().add(i - 3)) - (*inLow.as_ptr().add(i - 3)) - ((*inClose.as_ptr().add(i - 3)) - (*inOpen.as_ptr().add(i - 3))).abs() } }) / (if (Near_rangeType) == 2 { 2.0 } else { 1.0 })) && *inOpen.as_ptr().add(i - 1) >= (*inOpen.as_ptr().add(i - 2)).min(*inClose.as_ptr().add(i - 2)) - ((Near_factor) * (if (Near_avgPeriod) != 0 { (*NearPeriodTotal.as_ptr().add(2)) / (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 })) && *inOpen.as_ptr().add(i - 1) <= (*inOpen.as_ptr().add(i - 2)).max(*inClose.as_ptr().add(i - 2)) + ((Near_factor) * (if (Near_avgPeriod) != 0 { (*NearPeriodTotal.as_ptr().add(2)) / (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 })) && ((if *inClose.as_ptr().add(i - 1) >= *inOpen.as_ptr().add(i - 1) { 1 } else { 0 - 1 }) == 1 && *inClose.as_ptr().add(i - 1) > *inClose.as_ptr().add(i - 2) && *inClose.as_ptr().add(i - 2) > *inClose.as_ptr().add(i - 3) && *inOpen.as_ptr().add(i) > *inClose.as_ptr().add(i - 1) && *inClose.as_ptr().add(i) < *inOpen.as_ptr().add(i - 3) || ((if *inClose.as_ptr().add(i - 1) >= *inOpen.as_ptr().add(i - 1) { 1 } else { 0 - 1 })) as i32 == 0 - 1 && *inClose.as_ptr().add(i - 1) < *inClose.as_ptr().add(i - 2) && *inClose.as_ptr().add(i - 2) < *inClose.as_ptr().add(i - 3) && *inOpen.as_ptr().add(i) < *inClose.as_ptr().add(i - 1) && *inClose.as_ptr().add(i) > *inOpen.as_ptr().add(i - 3)) {
                *outInteger.as_mut_ptr().add(outIdx) = ((if *inClose.as_ptr().add(i - 1) >= *inOpen.as_ptr().add(i - 1) { 1 } else { 0 - 1 }) * 100) as i32;
                outIdx += 1;
            } else {
                *outInteger.as_mut_ptr().add(outIdx) = 0;
                outIdx += 1;
            }
            // for( totIdx = 3; totIdx >= 2; totIdx -= 1 )
            totIdx = 3;
            loop {
                let mut _candlerange_2: f64;
                match Near_rangeType {
                    0 => {
                        _candlerange_2 = (*inClose.as_ptr().add(i - totIdx) - *inOpen.as_ptr().add(i - totIdx)).abs();
                    }
                    1 => {
                        _candlerange_2 = *inHigh.as_ptr().add(i - totIdx) - *inLow.as_ptr().add(i - totIdx);
                    }
                    2 => {
                        _candlerange_2 = *inHigh.as_ptr().add(i - totIdx) - *inLow.as_ptr().add(i - totIdx) - (*inClose.as_ptr().add(i - totIdx) - *inOpen.as_ptr().add(i - totIdx)).abs();
                    }
                    _ => {
                        _candlerange_2 = 0.0;
                    }
                }
                let mut _candlerange_3: f64;
                match Near_rangeType {
                    0 => {
                        _candlerange_3 = (*inClose.as_ptr().add(NearTrailingIdx - totIdx) - *inOpen.as_ptr().add(NearTrailingIdx - totIdx)).abs();
                    }
                    1 => {
                        _candlerange_3 = *inHigh.as_ptr().add(NearTrailingIdx - totIdx) - *inLow.as_ptr().add(NearTrailingIdx - totIdx);
                    }
                    2 => {
                        _candlerange_3 = *inHigh.as_ptr().add(NearTrailingIdx - totIdx) - *inLow.as_ptr().add(NearTrailingIdx - totIdx) - (*inClose.as_ptr().add(NearTrailingIdx - totIdx) - *inOpen.as_ptr().add(NearTrailingIdx - totIdx)).abs();
                    }
                    _ => {
                        _candlerange_3 = 0.0;
                    }
                }
                *NearPeriodTotal.as_mut_ptr().add(totIdx) = *NearPeriodTotal.as_ptr().add(totIdx) + (_candlerange_2 - _candlerange_3);
                if totIdx == 2 { break; }
                totIdx -= 1;
            }
            i += 1;
            NearTrailingIdx += 1;
            if !(i <= endIdx) { break; }
        }
        (*outNBElement) = outIdx;
        (*outBegIdx) = startIdx;
        return RetCode::Success;
        } // unsafe
    }
}
/***************/
/* End of File */
/***************/
