qust 0.1.5

A crate for finance quantative reserach
Documentation
use itertools::{izip, Itertools};
use crate::{
    ds::{aa::*, types::*, roll::*},
    sig::{livesig::*, posi::{M1, Dire::*}},
    stats::pnl::{Stra, DiStra, CalcStra, DtToDa, Stral},
    trade::di::Di,
    idct::pms::const_pms::*,
};
pub trait ExtractCond {
    type Output;
    fn extract_cond(&self) -> Self::Output;
}

pub struct StraCond(pub Stra, pub CondWeight, pub CondWeight);

impl StraCond {
    pub fn get_cond_m(&self, di: &mut Di) -> vv32 {
        let grp = Grp(di.pcon.price.t.iter().map(|x| x.date()).collect_vec());
        izip!(self.1.0.iter(), self.2.0.iter())
            .fold(vec![], |mut acc, (cond1, cond2)| {
                let w = cond1.1;
                let cond_x = &cond1.0;
                let cond_y = &cond2.0;
                cond_x.init(di);
                cond_y.init(di);
                let f_x = cond_x.cond(di);
                let f_y = cond_y.cond(di);
                let mut res = vec![0f32; di.len()];
                for i in 0..di.len() {
                    res[i] = if f_x(i, i) || f_y(i, i) { w } else { 0f32 };
                };
                acc.push(grp.apply(&res, |x| *x.last().unwrap()).1);
                acc
            })
    }

    pub fn get_stra_m(&self, di: &mut Di) -> (vda, v32, vv32) {
        let pnl = di.pnl(&self.0.1, &cs1).da();
        let m_vec = pnl.1[2].clone();
        let cond_m = self.get_cond_m(di);
        (pnl.0.clone(), m_vec, cond_m)
    }
}

pub struct EstMoney(pub usize);
impl EstMoney {
    fn est_money(&self, m: &v32, cond: &vv32) -> v32 {
        let n = self.0;
        let mut w_v = vec![0f32; m.len()];
        for i in 1..m.len() + 1 {
            let start = if i <= n { 0 } else { i - n };
            let m_ori = &m[start..i];
            let mut res_now = vec![0f32; n];
            for j in 0..cond.len() {
                let w_now = cond[j][i-1];
                if w_now != 0f32 {
                    izip!(res_now.iter_mut(), cond[j][start..i].iter(), m_ori.iter())
                        .for_each(|(x, y, z)| *x += y * z * w_now);
                }
            }
            w_v[i-1] = res_now.max();
        }
        w_v.lag(1)
    }
}
impl CalcStra for EstMoney {
    type Output = (vda, v32);
    fn calc_stra(&self, distra: &mut DiStra) -> Self::Output {
        let stra_cond = distra.1.extract_cond();
        let kk = stra_cond.get_stra_m(&mut distra.0);
        let m = self.est_money(&kk.1, &kk.2);
        (kk.0, m)
    }
}

impl ExtractCond for Stra {
    type Output = StraCond;
    fn extract_cond(&self) -> Self::Output {
        let (ptm, cond_weight1, cond_weight2) = self.1.extract_cond();
        StraCond(Stra(self.0.clone(), ptm), cond_weight1, cond_weight2)
    }
}
impl ExtractCond for Ptm {
    type Output = (Ptm, CondWeight, CondWeight);
    fn extract_cond(&self) -> Self::Output {
        match self {
            Ptm::Ptm1(_, _) => panic!(),
            Ptm::Ptm2(m, stp1, stp2) => {
                let (stp_new1, cond_weight1) = stp1.extract_cond();
                let (stp_new2, cond_weight2) = stp2.extract_cond();
                (Ptm::Ptm2(m.clone(), stp_new1, stp_new2), cond_weight1, cond_weight2)
            }
        }
    }
}
impl ExtractCond for Stp {
    type Output = (Stp, CondWeight);
    fn extract_cond(&self) -> Self::Output {
        match self {
            Stp::Stp(_) => panic!(),
            Stp::StpWeight(box_stp, cond_weight) => {
                (*box_stp.clone(), cond_weight.clone())
            }
        }
    }
}

pub trait ExtendCond {
    type Output;
    fn extend_cond(&self) -> Self::Output;
}

impl ExtendCond for Stral {
    type Output = Stral;
    fn extend_cond(&self) -> Self::Output {
        self.0
            .iter()
            .fold(Stral(vec![]), |x, y| x + y.extend_cond())
    }
}

impl ExtendCond for Stra {
    type Output = Stral;
    fn extend_cond(&self) -> Self::Output {
        let ptm_vec = self.1.extend_cond();
        let stra_vec = ptm_vec.iter()
            .map(|x| {
                Stra(self.0.clone(), x.clone())
            })
            .collect_vec();
        Stral(stra_vec)
    }
}

impl ExtendCond for Ptm {
    type Output = Vec<Ptm>;
    fn extend_cond(&self) -> Self::Output {
        match self {
            Ptm::Ptm1(_, _) => panic!(""),
            Ptm::Ptm2(m, stp1, stp2) => {
                let stp_vec1 = stp1.extend_cond();
                let stp_vec2 = stp2.extend_cond();
                izip!(stp_vec1.into_iter(), stp_vec2.into_iter())
                    .map(|(x, y)| Ptm::Ptm2({
                        let m_f = m.get_init_weight();
                        let m_new = M1(m_f * x.1);
                        Box::new(m_new)
                    }, x.0, y.0))
                    .collect_vec()
            }
        }
    }
}

impl ExtendCond for Stp {
    type Output = Vec<(Stp, f32)>;
    fn extend_cond(&self) -> Self::Output {
        match self {
            Stp::Stp(_) => panic!(""),
            Stp::StpWeight(stp, weight) => {
                let stp_new = *stp.clone();
                weight.0.iter()
                    .map(|x| {
                        (stp_new.attach_box_cond(and, &x.0, &Lo), x.1)
                    })
                    .collect_vec()
            }
        }
    }
}

pub trait ExtendDire {
    type Output;
    fn extend_dire(&self) -> Self::Output;
}

impl ExtendDire for Stral {
    type Output = Stral;
    fn extend_dire(&self) -> Self::Output {
        self.0
            .iter()
            .fold(Stral(vec![]), |x, y| x + y.extend_dire())
    }
}

impl ExtendDire for Stra {
    type Output = Stral;
    fn extend_dire(&self) -> Self::Output {
        match self {
            Stra(_, Ptm::Ptm1(_, _)) => {
                Stral(vec![self.clone()])
            },
            Stra(di_name, Ptm::Ptm2(m, stp1, stp2)) => {
                Stral(vec![
                    Stra(di_name.clone(), Ptm::Ptm1(m.clone(), stp1.clone())),
                    Stra(di_name.clone(), Ptm::Ptm1(m.clone(), stp2.clone())),
                    ])
            } 
        }
    }
}