extern crate nalgebra as na;
use crate::BoxErr;
pub fn simple_kalman_filter(series: &Vec<f64>) -> (Vec<f64>, Vec<f64>) {
let mut x = 0.0;
let mut p = 0.0;
let q: f64 = 1e-5;
let r: f64 = 1e-2;
let mut xs = vec![0.0; series.len()];
let mut ps = vec![0.0; series.len()];
for (i, z) in series.iter().enumerate() {
let x_pred = x;
let p_pred = p + q;
let k: f64 = p_pred / (p_pred + r);
x = x_pred + k * (z - x_pred);
p = (1.0 - k) * p_pred;
xs[i] = x;
ps[i] = p;
}
(xs, ps)
}
pub fn dynamic_hedge_kalman_filter(x: &Vec<f64>, y: &Vec<f64>) -> Result<Vec<f64>, BoxErr> {
let size: usize = x.len();
let q: f64 = 10e-6; let r: f64 = 0.1f64.powf(2.0);
let mut xhat: Vec<f64> = vec![0.0; size]; let mut p: Vec<f64> = vec![0.0; size]; let mut xhatminus: Vec<f64> = vec![0.0; size]; let mut pminus: Vec<f64> = vec![0.0; size]; let mut k: Vec<f64> = vec![0.0; size];
xhat[0] = 0.0;
p[0] = 1.0;
for i in 1..size {
xhatminus[i] = xhat[i - 1];
pminus[i] = p[i - 1] + q;
k[i] = pminus[i] / (pminus[i] + r);
xhat[i] = xhatminus[i] + k[i] * (y[i] - xhatminus[i]);
p[i] = (1.0 - k[i]) * pminus[i];
}
Ok(xhat) }
#[cfg(test)]
mod tests {
use super::*;
use crate::get_test_data;
use crate::metrics::spread_dynamic;
#[test]
fn tests_simple_kalman_filter() {
let (series_1, series_2) = get_test_data();
let dummy_spread: Vec<f64> = spread_dynamic(&series_1, &series_2).unwrap();
let res = simple_kalman_filter(&dummy_spread);
dbg!(res);
}
#[test]
fn tests_dynamic_hedge_kalman_filter() {
let (series_1, series_2) = get_test_data();
let res = dynamic_hedge_kalman_filter(&series_1, &series_2);
dbg!(res);
}
}