chore: release v1.0.2
This commit is contained in:
@@ -14,3 +14,57 @@ pub(super) fn linreg(window: &[f64]) -> (f64, f64) {
|
||||
let intercept = (sum_y - slope * sum_x) / n;
|
||||
(slope, intercept)
|
||||
}
|
||||
|
||||
pub(crate) fn rolling_linreg_apply<F>(prices: &[f64], timeperiod: usize, mut map: F) -> Vec<f64>
|
||||
where
|
||||
F: FnMut(f64, f64) -> f64,
|
||||
{
|
||||
let n = prices.len();
|
||||
let mut result = vec![f64::NAN; n];
|
||||
if timeperiod == 0 || n < timeperiod {
|
||||
return result;
|
||||
}
|
||||
|
||||
if prices.iter().any(|value| !value.is_finite()) {
|
||||
for end in (timeperiod - 1)..n {
|
||||
let window = &prices[(end + 1 - timeperiod)..=end];
|
||||
let (slope, intercept) = linreg(window);
|
||||
result[end] = map(slope, intercept);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let period = timeperiod as f64;
|
||||
let last_x = (timeperiod - 1) as f64;
|
||||
let sum_x = last_x * period / 2.0;
|
||||
let sum_x2 = last_x * period * (2.0 * period - 1.0) / 6.0;
|
||||
let denom = period * sum_x2 - sum_x * sum_x;
|
||||
|
||||
let mut sum_y = prices[..timeperiod].iter().sum::<f64>();
|
||||
let mut sum_xy = prices[..timeperiod]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, &value)| idx as f64 * value)
|
||||
.sum::<f64>();
|
||||
|
||||
for end in (timeperiod - 1)..n {
|
||||
let slope = if denom != 0.0 {
|
||||
(period * sum_xy - sum_x * sum_y) / denom
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let intercept = (sum_y - slope * sum_x) / period;
|
||||
result[end] = map(slope, intercept);
|
||||
|
||||
if end + 1 < n {
|
||||
let outgoing = prices[end + 1 - timeperiod];
|
||||
let incoming = prices[end + 1];
|
||||
let prev_sum_y = sum_y;
|
||||
|
||||
sum_y = prev_sum_y - outgoing + incoming;
|
||||
sum_xy = sum_xy - (prev_sum_y - outgoing) + last_x * incoming;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user