From 70b99ad870e06d1446672aa0861d1b2754bb9897 Mon Sep 17 00:00:00 2001 From: Pratik Bhadane Date: Wed, 1 Apr 2026 20:12:19 +0530 Subject: [PATCH] style: apply cargo fmt formatting Co-Authored-By: Claude Sonnet 4.6 --- crates/ferro_ta_core/src/aggregation.rs | 28 +++++++---------- crates/ferro_ta_core/src/attribution.rs | 6 +++- crates/ferro_ta_core/src/backtest.rs | 41 +++++++++++++++++-------- crates/ferro_ta_core/src/batch.rs | 30 +++++++++--------- crates/ferro_ta_core/src/crypto.rs | 8 ++--- crates/ferro_ta_core/src/extended.rs | 19 +++--------- crates/ferro_ta_core/src/momentum.rs | 9 ++++-- crates/ferro_ta_core/src/portfolio.rs | 31 ++++++++++--------- crates/ferro_ta_core/src/regime.rs | 7 +---- crates/ferro_ta_core/src/resampling.rs | 3 +- crates/ferro_ta_core/src/streaming.rs | 3 +- src/aggregation/mod.rs | 3 +- src/backtest/mod.rs | 29 ++++++++++++----- src/batch/mod.rs | 14 ++++----- src/regime/mod.rs | 7 ++--- src/resampling/mod.rs | 3 +- src/streaming/mod.rs | 15 ++------- 17 files changed, 128 insertions(+), 128 deletions(-) diff --git a/crates/ferro_ta_core/src/aggregation.rs b/crates/ferro_ta_core/src/aggregation.rs index 6d4648d..43c7464 100644 --- a/crates/ferro_ta_core/src/aggregation.rs +++ b/crates/ferro_ta_core/src/aggregation.rs @@ -21,14 +21,13 @@ type Ohlcv5AndLabels = (Vec, Vec, Vec, Vec, Vec, Vec Ohlcv5 { +pub fn aggregate_tick_bars(price: &[f64], size: &[f64], ticks_per_bar: usize) -> Ohlcv5 { assert!(ticks_per_bar >= 1, "ticks_per_bar must be >= 1"); let n = price.len(); - assert!(n > 0 && size.len() == n, "price and size must be non-empty and equal length"); + assert!( + n > 0 && size.len() == n, + "price and size must be non-empty and equal length" + ); let n_bars = n.div_ceil(ticks_per_bar); let mut out_open = Vec::with_capacity(n_bars); @@ -71,14 +70,13 @@ pub fn aggregate_tick_bars( /// /// # Panics /// Panics if `volume_threshold <= 0`, arrays are empty, or lengths differ. -pub fn aggregate_volume_bars_ticks( - price: &[f64], - size: &[f64], - volume_threshold: f64, -) -> Ohlcv5 { +pub fn aggregate_volume_bars_ticks(price: &[f64], size: &[f64], volume_threshold: f64) -> Ohlcv5 { assert!(volume_threshold > 0.0, "volume_threshold must be > 0"); let n = price.len(); - assert!(n > 0 && size.len() == n, "price and size must be non-empty and equal length"); + assert!( + n > 0 && size.len() == n, + "price and size must be non-empty and equal length" + ); let mut out_open: Vec = Vec::new(); let mut out_high: Vec = Vec::new(); @@ -140,11 +138,7 @@ pub fn aggregate_volume_bars_ticks( /// /// # Panics /// Panics if arrays are empty or have unequal lengths. -pub fn aggregate_time_bars( - price: &[f64], - size: &[f64], - labels: &[i64], -) -> Ohlcv5AndLabels { +pub fn aggregate_time_bars(price: &[f64], size: &[f64], labels: &[i64]) -> Ohlcv5AndLabels { let n = price.len(); assert!( n > 0 && size.len() == n && labels.len() == n, diff --git a/crates/ferro_ta_core/src/attribution.rs b/crates/ferro_ta_core/src/attribution.rs index 59dfb92..d7536b9 100644 --- a/crates/ferro_ta_core/src/attribution.rs +++ b/crates/ferro_ta_core/src/attribution.rs @@ -28,7 +28,11 @@ use std::collections::HashMap; pub fn trade_stats(pnl: &[f64], hold_bars: &[f64]) -> (f64, f64, f64, f64, f64) { let n = pnl.len(); assert!(n > 0, "pnl must be non-empty"); - assert_eq!(n, hold_bars.len(), "pnl and hold_bars must have equal length"); + assert_eq!( + n, + hold_bars.len(), + "pnl and hold_bars must have equal length" + ); let mut wins: Vec = Vec::new(); let mut losses: Vec = Vec::new(); diff --git a/crates/ferro_ta_core/src/backtest.rs b/crates/ferro_ta_core/src/backtest.rs index 4dd8f4a..5d99b55 100644 --- a/crates/ferro_ta_core/src/backtest.rs +++ b/crates/ferro_ta_core/src/backtest.rs @@ -287,7 +287,12 @@ pub struct StreamingSummary { // --------------------------------------------------------------------------- /// RSI threshold strategy: +1 when RSI <= oversold, -1 when RSI >= overbought, 0 otherwise. -pub fn rsi_threshold_signals(close: &[f64], timeperiod: usize, oversold: f64, overbought: f64) -> Vec { +pub fn rsi_threshold_signals( + close: &[f64], + timeperiod: usize, + oversold: f64, + overbought: f64, +) -> Vec { let rsi = crate::momentum::rsi(close, timeperiod); rsi.iter() .map(|&v| { @@ -1128,8 +1133,7 @@ pub fn compute_performance_metrics( } let mean_r: f64 = valid_r.iter().sum::() / n_valid as f64; - let variance: f64 = - valid_r.iter().map(|&v| (v - mean_r).powi(2)).sum::() / n_valid as f64; + let variance: f64 = valid_r.iter().map(|&v| (v - mean_r).powi(2)).sum::() / n_valid as f64; let std_r = variance.sqrt(); let downside_sq_sum: f64 = valid_r @@ -1253,13 +1257,19 @@ pub fn compute_performance_metrics( a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal) }); let p5 = pct_r[idx_5]; - let worst_bar = pct_r[..=idx_5].iter().copied().fold(f64::INFINITY, f64::min); + let worst_bar = pct_r[..=idx_5] + .iter() + .copied() + .fold(f64::INFINITY, f64::min); // Find 95th percentile in the remaining upper partition pct_r[idx_5..].select_nth_unstable_by(idx_95 - idx_5, |a, b| { a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal) }); let p95 = pct_r[idx_95]; - let best_bar = pct_r[idx_95..].iter().copied().fold(f64::NEG_INFINITY, f64::max); + let best_bar = pct_r[idx_95..] + .iter() + .copied() + .fold(f64::NEG_INFINITY, f64::max); let tail_ratio = if p5.abs() > 0.0 { p95.abs() / p5.abs() } else { @@ -1451,10 +1461,8 @@ pub fn extract_trades_ohlcv( } } else { if trade_entry_price > 0.0 { - let unreal_high = - trade_dir * (high[i] - trade_entry_price) / trade_entry_price; - let unreal_low = - trade_dir * (low[i] - trade_entry_price) / trade_entry_price; + let unreal_high = trade_dir * (high[i] - trade_entry_price) / trade_entry_price; + let unreal_low = trade_dir * (low[i] - trade_entry_price) / trade_entry_price; let bar_best = unreal_high.max(unreal_low); let bar_worst = unreal_high.min(unreal_low); if bar_best > trade_mfe { @@ -1615,8 +1623,12 @@ pub fn backtest_multi_asset_core( // Per-asset backtests let asset_strategy_returns: Vec> = (0..n_assets) .map(|j| { - let (_, strat_rets, _) = - single_asset_backtest(&close_2d[j], &constrained[j], commission_per_trade, slippage_bps); + let (_, strat_rets, _) = single_asset_backtest( + &close_2d[j], + &constrained[j], + commission_per_trade, + slippage_bps, + ); strat_rets }) .collect(); @@ -1757,7 +1769,9 @@ pub fn walk_forward_indices( } if folds.is_empty() { - return Err("No complete folds fit within n_bars with the given train/test sizes".to_string()); + return Err( + "No complete folds fit within n_bars with the given train/test sizes".to_string(), + ); } Ok(folds) @@ -2018,7 +2032,8 @@ mod tests { let signals: Vec = vec![0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0]; let config = BacktestConfig::default(); - let result = backtest_ohlcv_core(&open, &high, &low, &close, &signals, &config, None).unwrap(); + let result = + backtest_ohlcv_core(&open, &high, &low, &close, &signals, &config, None).unwrap(); assert_eq!(result.equity.len(), n); // Equity should be positive assert!(*result.equity.last().unwrap() > 0.0); diff --git a/crates/ferro_ta_core/src/batch.rs b/crates/ferro_ta_core/src/batch.rs index 21d55c4..353647b 100644 --- a/crates/ferro_ta_core/src/batch.rs +++ b/crates/ferro_ta_core/src/batch.rs @@ -46,11 +46,7 @@ fn validate_hlc_columns( return Ok((0, 0)); } let n = high[0].len(); - for (idx, (h, (l, c))) in high - .iter() - .zip(low.iter().zip(close.iter())) - .enumerate() - { + for (idx, (h, (l, c))) in high.iter().zip(low.iter().zip(close.iter())).enumerate() { if h.len() != n || l.len() != n || c.len() != n { return Err(format!( "column {idx}: high len={}, low len={}, close len={} — must all be {n}", @@ -358,24 +354,26 @@ fn compute_close_indicator( .collect()), "LINEARREG" => { let last_x = (timeperiod - 1) as f64; - Ok(rolling_linreg_apply(close, timeperiod, |slope, intercept| { - intercept + slope * last_x - })) + Ok(rolling_linreg_apply( + close, + timeperiod, + |slope, intercept| intercept + slope * last_x, + )) } "LINEARREG_SLOPE" => Ok(rolling_linreg_apply(close, timeperiod, |slope, _| slope)), - "LINEARREG_INTERCEPT" => { - Ok(rolling_linreg_apply(close, timeperiod, |_, intercept| { - intercept - })) - } + "LINEARREG_INTERCEPT" => Ok(rolling_linreg_apply(close, timeperiod, |_, intercept| { + intercept + })), "LINEARREG_ANGLE" => Ok(rolling_linreg_apply(close, timeperiod, |slope, _| { slope.atan() * 180.0 / std::f64::consts::PI })), "TSF" => { let forecast_x = timeperiod as f64; - Ok(rolling_linreg_apply(close, timeperiod, |slope, intercept| { - intercept + slope * forecast_x - })) + Ok(rolling_linreg_apply( + close, + timeperiod, + |slope, intercept| intercept + slope * forecast_x, + )) } _ => Err(format!( "unsupported close indicator for grouped execution: {name}" diff --git a/crates/ferro_ta_core/src/crypto.rs b/crates/ferro_ta_core/src/crypto.rs index f5cbb4c..21e714a 100644 --- a/crates/ferro_ta_core/src/crypto.rs +++ b/crates/ferro_ta_core/src/crypto.rs @@ -72,11 +72,11 @@ mod tests { fn test_mark_session_boundaries() { let ns_per_day: i64 = 86_400_000_000_000; let ts = vec![ - 0, // day 0 - ns_per_day / 2, // day 0 - ns_per_day, // day 1 + 0, // day 0 + ns_per_day / 2, // day 0 + ns_per_day, // day 1 ns_per_day + ns_per_day / 2, // day 1 - ns_per_day * 2, // day 2 + ns_per_day * 2, // day 2 ]; let result = mark_session_boundaries(&ts); assert_eq!(result, vec![0, 2, 4]); diff --git a/crates/ferro_ta_core/src/extended.rs b/crates/ferro_ta_core/src/extended.rs index 26d7014..44a47c4 100644 --- a/crates/ferro_ta_core/src/extended.rs +++ b/crates/ferro_ta_core/src/extended.rs @@ -215,16 +215,14 @@ pub fn supertrend( let lower_basic = hl2 - multiplier * atr[i]; // Adjust lower band - lower_band[i] = if lower_basic > lower_band[i - 1] || close[i - 1] < lower_band[i - 1] - { + lower_band[i] = if lower_basic > lower_band[i - 1] || close[i - 1] < lower_band[i - 1] { lower_basic } else { lower_band[i - 1] }; // Adjust upper band - upper_band[i] = if upper_basic < upper_band[i - 1] || close[i - 1] > upper_band[i - 1] - { + upper_band[i] = if upper_basic < upper_band[i - 1] || close[i - 1] > upper_band[i - 1] { upper_basic } else { upper_band[i - 1] @@ -269,11 +267,7 @@ pub fn supertrend( /// /// # Returns /// `(upper, middle, lower)` arrays. -pub fn donchian( - high: &[f64], - low: &[f64], - timeperiod: usize, -) -> (Vec, Vec, Vec) { +pub fn donchian(high: &[f64], low: &[f64], timeperiod: usize) -> (Vec, Vec, Vec) { let n = high.len(); let mut upper = vec![f64::NAN; n]; let mut lower = vec![f64::NAN; n]; @@ -305,12 +299,7 @@ pub fn donchian( /// /// Values near 100 indicate a choppy market; near 0 indicates trending. /// The first `timeperiod` values are `NaN`. -pub fn choppiness_index( - high: &[f64], - low: &[f64], - close: &[f64], - timeperiod: usize, -) -> Vec { +pub fn choppiness_index(high: &[f64], low: &[f64], close: &[f64], timeperiod: usize) -> Vec { let n = high.len(); let mut result = vec![f64::NAN; n]; if timeperiod < 1 || n <= timeperiod { diff --git a/crates/ferro_ta_core/src/momentum.rs b/crates/ferro_ta_core/src/momentum.rs index 113c178..648d74d 100644 --- a/crates/ferro_ta_core/src/momentum.rs +++ b/crates/ferro_ta_core/src/momentum.rs @@ -1,6 +1,5 @@ //! Momentum indicators. - /// Compute the Relative Strength Index (RSI). /// /// Returns values in the range `[0, 100]`. Uses Wilder's smoothing method @@ -119,8 +118,12 @@ pub fn stoch( for j in (win_start + 1)..=i { let h = high[j]; let l = low[j]; - if h > hh { hh = h; } - if l < ll { ll = l; } + if h > hh { + hh = h; + } + if l < ll { + ll = l; + } } let range = hh - ll; fastk_valid[i - fastk_start] = if range != 0.0 { diff --git a/crates/ferro_ta_core/src/portfolio.rs b/crates/ferro_ta_core/src/portfolio.rs index 513be3c..610511e 100644 --- a/crates/ferro_ta_core/src/portfolio.rs +++ b/crates/ferro_ta_core/src/portfolio.rs @@ -73,7 +73,10 @@ pub fn beta_full(asset_returns: &[f64], benchmark_returns: &[f64]) -> f64 { cov += da * db; var_b += db * db; } - assert!(var_b != 0.0, "benchmark_returns has zero variance; cannot compute beta"); + assert!( + var_b != 0.0, + "benchmark_returns has zero variance; cannot compute beta" + ); cov / var_b } @@ -225,7 +228,11 @@ pub fn relative_strength(asset_returns: &[f64], benchmark_returns: &[f64]) -> Ve for i in 0..n { cum_a *= 1.0 + asset_returns[i]; cum_b *= 1.0 + benchmark_returns[i]; - result[i] = if cum_b == 0.0 { f64::NAN } else { cum_a / cum_b }; + result[i] = if cum_b == 0.0 { + f64::NAN + } else { + cum_a / cum_b + }; } result } @@ -243,7 +250,10 @@ pub fn spread(a: &[f64], b: &[f64], hedge: f64) -> Vec { n > 0 && b.len() == n, "a and b must be non-empty and equal length" ); - a.iter().zip(b.iter()).map(|(&x, &y)| x - hedge * y).collect() + a.iter() + .zip(b.iter()) + .map(|(&x, &y)| x - hedge * y) + .collect() } // --------------------------------------------------------------------------- @@ -358,10 +368,7 @@ mod tests { #[test] fn test_portfolio_volatility_identity_cov() { // Identity covariance, equal weights => sqrt(sum(w_i^2)) - let cov = vec![ - vec![1.0, 0.0], - vec![0.0, 1.0], - ]; + let cov = vec![vec![1.0, 0.0], vec![0.0, 1.0]]; let w = vec![0.5, 0.5]; let vol = portfolio_volatility(&cov, &w); // w' I w = 0.25 + 0.25 = 0.5, sqrt = 0.7071... @@ -378,10 +385,7 @@ mod tests { #[test] fn test_portfolio_volatility_correlated() { // Fully correlated: cov = [[0.04, 0.04], [0.04, 0.04]] - let cov = vec![ - vec![0.04, 0.04], - vec![0.04, 0.04], - ]; + let cov = vec![vec![0.04, 0.04], vec![0.04, 0.04]]; let w = vec![0.5, 0.5]; // w' Σ w = 0.04, sqrt = 0.2 let vol = portfolio_volatility(&cov, &w); @@ -594,10 +598,7 @@ mod tests { #[test] fn test_compose_weighted_basic() { - let data = vec![ - vec![1.0, 2.0, 3.0], - vec![4.0, 5.0, 6.0], - ]; + let data = vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]]; let weights = vec![0.3, 0.7]; let cw = compose_weighted(&data, &weights); // bar 0: 1*0.3 + 4*0.7 = 3.1 diff --git a/crates/ferro_ta_core/src/regime.rs b/crates/ferro_ta_core/src/regime.rs index 285689a..27e9260 100644 --- a/crates/ferro_ta_core/src/regime.rs +++ b/crates/ferro_ta_core/src/regime.rs @@ -54,12 +54,7 @@ pub fn regime_combined( /// Detect structural breaks using a CUSUM (cumulative sum) approach. /// /// `window` must be >= 2. Returns `Vec`: `1` at break bars, `0` elsewhere. -pub fn detect_breaks_cusum( - series: &[f64], - window: usize, - threshold: f64, - slack: f64, -) -> Vec { +pub fn detect_breaks_cusum(series: &[f64], window: usize, threshold: f64, slack: f64) -> Vec { let n = series.len(); let mut out = vec![0i8; n]; if n < window || window < 2 { diff --git a/crates/ferro_ta_core/src/resampling.rs b/crates/ferro_ta_core/src/resampling.rs index 5a81f31..f573adf 100644 --- a/crates/ferro_ta_core/src/resampling.rs +++ b/crates/ferro_ta_core/src/resampling.rs @@ -197,8 +197,7 @@ mod tests { #[test] fn test_volume_bars_single_element() { - let (ro, rh, rl, rc, rv) = - volume_bars(&[10.0], &[12.0], &[8.0], &[11.0], &[50.0], 100.0); + let (ro, rh, rl, rc, rv) = volume_bars(&[10.0], &[12.0], &[8.0], &[11.0], &[50.0], 100.0); assert_eq!(rv.len(), 1); assert!((rv[0] - 50.0).abs() < 1e-10); assert!((ro[0] - 10.0).abs() < 1e-10); diff --git a/crates/ferro_ta_core/src/streaming.rs b/crates/ferro_ta_core/src/streaming.rs index 98f4f67..fd5d867 100644 --- a/crates/ferro_ta_core/src/streaming.rs +++ b/crates/ferro_ta_core/src/streaming.rs @@ -932,8 +932,7 @@ mod tests { if i + 1 < period { assert!(streaming[i].is_nan(), "bar {} should be NaN", i); } else { - let batch: f64 = - data[i + 1 - period..=i].iter().sum::() / period as f64; + let batch: f64 = data[i + 1 - period..=i].iter().sum::() / period as f64; assert!( approx_eq(streaming[i], batch, 1e-10), "bar {}: streaming={} batch={}", diff --git a/src/aggregation/mod.rs b/src/aggregation/mod.rs index 61938b0..f1e4c58 100644 --- a/src/aggregation/mod.rs +++ b/src/aggregation/mod.rs @@ -71,7 +71,8 @@ pub fn aggregate_volume_bars_ticks<'py>( "price and size must be non-empty and equal length", )); } - let (ro, rh, rl, rc, rv) = ferro_ta_core::aggregation::aggregate_volume_bars_ticks(p, s, volume_threshold); + let (ro, rh, rl, rc, rv) = + ferro_ta_core::aggregation::aggregate_volume_bars_ticks(p, s, volume_threshold); Ok(( ro.into_pyarray(py), rh.into_pyarray(py), diff --git a/src/backtest/mod.rs b/src/backtest/mod.rs index e98118c..09013ce 100644 --- a/src/backtest/mod.rs +++ b/src/backtest/mod.rs @@ -147,8 +147,8 @@ pub fn sma_crossover_signals<'py>( validation::validate_timeperiod(fast, "fast", 1)?; validation::validate_timeperiod(slow, "slow", 1)?; let prices = close.as_slice()?; - let out = core_bt::sma_crossover_signals(prices, fast, slow) - .map_err(|e| PyValueError::new_err(e))?; + let out = + core_bt::sma_crossover_signals(prices, fast, slow).map_err(|e| PyValueError::new_err(e))?; Ok(out.into_pyarray(py)) } @@ -202,8 +202,15 @@ pub fn backtest_core<'py>( validation::validate_equal_length(&[(c.len(), "close"), (s.len(), "signals")])?; let cm = commission.as_ref().map(|c| &c.inner); - let result = core_bt::backtest_core(c, s, cm, slippage_bps, initial_capital, commission_per_trade) - .map_err(|e| PyValueError::new_err(e))?; + let result = core_bt::backtest_core( + c, + s, + cm, + slippage_bps, + initial_capital, + commission_per_trade, + ) + .map_err(|e| PyValueError::new_err(e))?; Ok(( result.positions.into_pyarray(py), @@ -348,8 +355,14 @@ pub fn compute_performance_metrics<'py>( dict.set_item("calmar", metrics.calmar)?; dict.set_item("max_drawdown", metrics.max_drawdown)?; dict.set_item("avg_drawdown", metrics.avg_drawdown)?; - dict.set_item("max_drawdown_duration_bars", metrics.max_drawdown_duration_bars as i64)?; - dict.set_item("avg_drawdown_duration_bars", metrics.avg_drawdown_duration_bars)?; + dict.set_item( + "max_drawdown_duration_bars", + metrics.max_drawdown_duration_bars as i64, + )?; + dict.set_item( + "avg_drawdown_duration_bars", + metrics.avg_drawdown_duration_bars, + )?; dict.set_item("ulcer_index", metrics.ulcer_index)?; dict.set_item("omega_ratio", metrics.omega_ratio)?; dict.set_item("win_rate", metrics.win_rate)?; @@ -428,8 +441,8 @@ pub fn extract_trades_ohlcv<'py>( (l.len(), "low"), ])?; - let trades = core_bt::extract_trades_ohlcv(pos, fp, h, l) - .map_err(|e| PyValueError::new_err(e))?; + let trades = + core_bt::extract_trades_ohlcv(pos, fp, h, l).map_err(|e| PyValueError::new_err(e))?; let mut entry_bars: Vec = Vec::with_capacity(trades.len()); let mut exit_bars: Vec = Vec::with_capacity(trades.len()); diff --git a/src/batch/mod.rs b/src/batch/mod.rs index 6916a2d..0a6b2bf 100644 --- a/src/batch/mod.rs +++ b/src/batch/mod.rs @@ -27,9 +27,7 @@ use rayon::prelude::*; /// `result[j]` is column j (one time-series of length n_samples). fn numpy2d_to_columns(arr: &ndarray::ArrayView2<'_, f64>) -> Vec> { let (_n_samples, n_series) = arr.dim(); - (0..n_series) - .map(|j| arr.column(j).to_vec()) - .collect() + (0..n_series).map(|j| arr.column(j).to_vec()).collect() } /// Convert `Vec>` (columns) back into a numpy (n_samples, n_series) array. @@ -320,9 +318,8 @@ pub fn batch_adx<'py>( let c_cols = numpy2d_to_columns(&arr_c); let col_results: Vec> = py.allow_threads(|| { - let process = |i: usize| { - ferro_ta_core::momentum::adx(&h_cols[i], &l_cols[i], &c_cols[i], timeperiod) - }; + let process = + |i: usize| ferro_ta_core::momentum::adx(&h_cols[i], &l_cols[i], &c_cols[i], timeperiod); if parallel { (0..n_series).into_par_iter().map(process).collect() } else { @@ -369,8 +366,9 @@ pub fn run_close_indicators<'py>( .map(|r| r.map(|v| v.into_pyarray(py).unbind()).map_err(map_core_err)) .collect() } else { - let results = ferro_ta_core::batch::run_close_indicators(close_values, &names, &timeperiods) - .map_err(map_core_err)?; + let results = + ferro_ta_core::batch::run_close_indicators(close_values, &names, &timeperiods) + .map_err(map_core_err)?; Ok(results .into_iter() .map(|v| v.into_pyarray(py).unbind()) diff --git a/src/regime/mod.rs b/src/regime/mod.rs index f53bf99..22e8445 100644 --- a/src/regime/mod.rs +++ b/src/regime/mod.rs @@ -63,12 +63,11 @@ pub fn rolling_variance_break<'py>( ) -> PyResult>> { validation::validate_timeperiod(short_window, "short_window", 2)?; if long_window <= short_window { - return Err(PyValueError::new_err( - "long_window must be > short_window", - )); + return Err(PyValueError::new_err("long_window must be > short_window")); } let s = series.as_slice()?; - let result = ferro_ta_core::regime::rolling_variance_break(s, short_window, long_window, threshold); + let result = + ferro_ta_core::regime::rolling_variance_break(s, short_window, long_window, threshold); Ok(result.into_pyarray(py)) } diff --git a/src/resampling/mod.rs b/src/resampling/mod.rs index 8f5668d..4b99deb 100644 --- a/src/resampling/mod.rs +++ b/src/resampling/mod.rs @@ -38,7 +38,8 @@ pub fn volume_bars<'py>( "All input arrays must be non-empty and have equal length", )); } - let (ro, rh, rl, rc, rv) = ferro_ta_core::resampling::volume_bars(o, h, l, c, v, volume_threshold); + let (ro, rh, rl, rc, rv) = + ferro_ta_core::resampling::volume_bars(o, h, l, c, v, volume_threshold); Ok(( ro.into_pyarray(py), rh.into_pyarray(py), diff --git a/src/streaming/mod.rs b/src/streaming/mod.rs index b831f9e..3e3959e 100644 --- a/src/streaming/mod.rs +++ b/src/streaming/mod.rs @@ -209,10 +209,7 @@ impl StreamingBBands { } fn __repr__(&self) -> String { - format!( - "StreamingBBands(period={})", - self.inner.period() - ) + format!("StreamingBBands(period={})", self.inner.period()) } } @@ -287,10 +284,7 @@ impl StreamingStoch { } fn __repr__(&self) -> String { - format!( - "StreamingStoch(fastk_period={})", - self.inner.period() - ) + format!("StreamingStoch(fastk_period={})", self.inner.period()) } } @@ -363,10 +357,7 @@ impl StreamingSupertrend { } fn __repr__(&self) -> String { - format!( - "StreamingSupertrend(period={})", - self.inner.period() - ) + format!("StreamingSupertrend(period={})", self.inner.period()) } }