use serde::Deserialize;
fn default_true() -> bool {
true
}
fn default_stoch_d() -> usize {
3
}
#[derive(Debug, Deserialize)]
#[serde(tag = "op")]
pub enum Expr {
Data { name: String },
Const { value: f64 },
Average { of: Box<Expr>, n: usize },
Ema { of: Box<Expr>, n: usize },
Std { of: Box<Expr>, n: usize },
Rsi { of: Box<Expr>, n: usize },
PctChange { of: Box<Expr>, n: usize },
Rise { of: Box<Expr>, n: usize },
Shift { of: Box<Expr>, n: usize },
RollingMax { of: Box<Expr>, n: usize },
Atr {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
Natr {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
WillR {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
Cci {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
StochK {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
StochD {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
#[serde(default = "default_stoch_d")]
d: usize,
},
AroonUp { high: Box<Expr>, n: usize },
AroonDown { low: Box<Expr>, n: usize },
Adx {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
PlusDi {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
MinusDi {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
n: usize,
},
Obv { close: Box<Expr>, volume: Box<Expr> },
Mfi {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
volume: Box<Expr>,
n: usize,
},
Vwap {
high: Box<Expr>,
low: Box<Expr>,
close: Box<Expr>,
volume: Box<Expr>,
n: usize,
},
Fall { of: Box<Expr>, n: usize },
IsLargest { of: Box<Expr>, n: usize },
IsSmallest { of: Box<Expr>, n: usize },
Sustain {
of: Box<Expr>,
nwindow: usize,
nsatisfy: Option<usize>,
},
IsEntry { of: Box<Expr> },
IsExit { of: Box<Expr> },
Gt { l: Box<Expr>, r: Box<Expr> },
Lt { l: Box<Expr>, r: Box<Expr> },
Ge { l: Box<Expr>, r: Box<Expr> },
Le { l: Box<Expr>, r: Box<Expr> },
And { l: Box<Expr>, r: Box<Expr> },
Or { l: Box<Expr>, r: Box<Expr> },
Add { l: Box<Expr>, r: Box<Expr> },
Sub { l: Box<Expr>, r: Box<Expr> },
Mul { l: Box<Expr>, r: Box<Expr> },
Div { l: Box<Expr>, r: Box<Expr> },
Neg { of: Box<Expr> },
Ceil { of: Box<Expr> },
Rank {
of: Box<Expr>,
#[serde(default = "default_true")]
pct: bool,
#[serde(default = "default_true")]
ascending: bool,
},
Mask { of: Box<Expr>, by: Box<Expr> },
HoldUntil {
entry: Box<Expr>,
exit: Box<Expr>,
nstocks_limit: Option<usize>,
rank: Option<Box<Expr>>,
#[serde(default)]
stop_loss: Option<f64>,
#[serde(default)]
take_profit: Option<f64>,
#[serde(default)]
trail_stop: Option<f64>,
#[serde(default)]
trail_stop_activation: Option<f64>,
},
Rebalance {
of: Box<Expr>,
#[serde(default)]
freq: Option<String>,
#[serde(default)]
on: Option<Box<Expr>>,
},
Neutralize {
of: Box<Expr>,
by: Vec<Expr>,
#[serde(default = "default_true")]
add_const: bool,
},
NeutralizeIndustry {
of: Box<Expr>,
#[serde(default = "default_true")]
add_const: bool,
},
IndustryRank {
of: Box<Expr>,
#[serde(default)]
categories: Option<Vec<String>>,
},
GroupbyCategory { of: Box<Expr>, agg: String },
}