chore: prepare v1.1.0 release

Update version numbers across Rust, Python, and documentation files to 1.1.0. Enhance the .gitignore to include macOS dSYM files and plans directory. Introduce new dependencies in the Rust core library and update the README to reflect recent performance benchmarks and backtesting engine capabilities. Add new artifacts to the benchmarks manifest and improve documentation for the backtesting engine API.
This commit is contained in:
Pratik Bhadane
2026-03-30 12:45:52 +05:30
parent 2d776b6f90
commit 436954138f
174 changed files with 29297 additions and 10773 deletions
+2 -13
View File
@@ -2,7 +2,7 @@ use crate::validation;
use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1};
use pyo3::prelude::*;
/// Chaikin Accumulation/Distribution Line. Cumulates (close - low - (high - close)) / (high - low) * volume.
/// Chaikin Accumulation/Distribution Line.
#[pyfunction]
pub fn ad<'py>(
py: Python<'py>,
@@ -22,17 +22,6 @@ pub fn ad<'py>(
(closes.len(), "close"),
(vols.len(), "volume"),
])?;
let mut result = vec![0.0_f64; n];
let mut ad_val = 0.0_f64;
for i in 0..n {
let hl = highs[i] - lows[i];
let clv = if hl != 0.0 {
((closes[i] - lows[i]) - (highs[i] - closes[i])) / hl
} else {
0.0
};
ad_val += clv * vols[i];
result[i] = ad_val;
}
let result = ferro_ta_core::volume::ad(highs, lows, closes, vols);
Ok(result.into_pyarray(py))
}
+1 -31
View File
@@ -2,8 +2,6 @@ use crate::validation;
use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use ta::indicators::ExponentialMovingAverage;
use ta::Next;
/// Chaikin A/D Oscillator: fast EMA of AD minus slow EMA of AD.
#[pyfunction]
@@ -35,34 +33,6 @@ pub fn adosc<'py>(
(closes.len(), "close"),
(vols.len(), "volume"),
])?;
// Compute raw AD values
let mut ad_vals = vec![0.0_f64; n];
let mut ad_val = 0.0_f64;
for i in 0..n {
let hl = highs[i] - lows[i];
let clv = if hl != 0.0 {
((closes[i] - lows[i]) - (highs[i] - closes[i])) / hl
} else {
0.0
};
ad_val += clv * vols[i];
ad_vals[i] = ad_val;
}
// Apply fast and slow EMA to AD
let mut fast_ema = ExponentialMovingAverage::new(fastperiod)
.map_err(|e| PyValueError::new_err(e.to_string()))?;
let mut slow_ema = ExponentialMovingAverage::new(slowperiod)
.map_err(|e| PyValueError::new_err(e.to_string()))?;
let warmup = slowperiod - 1;
let mut result = vec![f64::NAN; n];
for (i, &v) in ad_vals.iter().enumerate() {
let fast = fast_ema.next(v);
let slow = slow_ema.next(v);
if i >= warmup {
result[i] = fast - slow;
}
}
let result = ferro_ta_core::volume::adosc(highs, lows, closes, vols, fastperiod, slowperiod);
Ok(result.into_pyarray(py))
}
+2 -11
View File
@@ -2,7 +2,7 @@ use crate::validation;
use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1};
use pyo3::prelude::*;
/// On Balance Volume: cumulates volume * sign(close - prev_close); bar 0 uses volume.
/// On Balance Volume: cumulates volume * sign(close - prev_close).
#[pyfunction]
pub fn obv<'py>(
py: Python<'py>,
@@ -13,15 +13,6 @@ pub fn obv<'py>(
let vols = volume.as_slice()?;
let n = closes.len();
validation::validate_equal_length(&[(n, "close"), (vols.len(), "volume")])?;
let mut result = vec![0.0_f64; n];
let mut obv_val = 0.0_f64;
for i in 1..n {
if closes[i] > closes[i - 1] {
obv_val += vols[i];
} else if closes[i] < closes[i - 1] {
obv_val -= vols[i];
}
result[i] = obv_val;
}
let result = ferro_ta_core::volume::obv(closes, vols);
Ok(result.into_pyarray(py))
}