1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use crate::Trade;
use crate::modules::close::ModuleClose;
use crate::modules::open::ModuleOpen;
use crate::modules::high::ModuleHigh;
use crate::modules::low::ModuleLow;
use std::fmt::{Debug};
use crate::modules::weighted_price::ModuleWeightedPrice;
use crate::modules::directional_trade_ratio::ModuleDirectionalTradeRatio;
use crate::modules::directional_volume_ratio::ModuleDirectionalVolumeRatio;
use crate::modules::std_dev_prices::ModuleStdDevPrices;
use crate::modules::std_dev_sizes::ModuleStdDevSizes;
use crate::modules::volume::ModuleVolume;
use crate::modules::arithmetic_mean_price::ModuleArithmeticMeanPrice;
use crate::modules::time_velocity::ModuleTimeVelocity;
use crate::modules::num_trades::ModuleNumTrades;
mod open;
mod high;
mod low;
mod close;
mod volume;
mod directional_trade_ratio;
mod directional_volume_ratio;
mod std_dev_sizes;
mod std_dev_prices;
mod weighted_price;
mod arithmetic_mean_price;
mod time_velocity;
mod num_trades;
#[derive(Debug, Default)]
pub struct ModularCandle {
features: Vec<f64>,
}
impl ModularCandle {
pub fn from_modules(modules: &Vec<Box<dyn FeatureModule>>) -> Self {
let mut features: Vec<f64> = Vec::new();
for m in modules {
features.push(m.value());
}
Self {
features,
}
}
pub fn get_features(&self) -> &Vec<f64> {
&self.features
}
}
pub enum FeatureModules {
Open,
High,
Low,
Close,
Volume,
ArithmeticMeanPrice,
WeightedPrice,
NumTrades,
DirectionalTradeRatio,
DirectionalVolumeRatio,
StdDevPrices,
StdDevSizes,
TimeVelocity,
}
impl FeatureModules {
pub fn get_module(&self) -> Box<dyn FeatureModule> {
return match self {
FeatureModules::Open => Box::new(ModuleOpen::default()),
FeatureModules::High => Box::new(ModuleHigh::default()),
FeatureModules::Low => Box::new(ModuleLow::default()),
FeatureModules::Close => Box::new(ModuleClose::default()),
FeatureModules::Volume => Box::new(ModuleVolume::default()),
FeatureModules::ArithmeticMeanPrice => Box::new(ModuleArithmeticMeanPrice::default()),
FeatureModules::WeightedPrice => Box::new(ModuleWeightedPrice::default()),
FeatureModules::NumTrades => Box::new(ModuleNumTrades::default()),
FeatureModules::DirectionalTradeRatio => Box::new(ModuleDirectionalTradeRatio::default()),
FeatureModules::DirectionalVolumeRatio => Box::new(ModuleDirectionalVolumeRatio::default()),
FeatureModules::StdDevPrices => Box::new(ModuleStdDevPrices::new()),
FeatureModules::StdDevSizes => Box::new(ModuleStdDevSizes::new()),
FeatureModules::TimeVelocity => Box::new(ModuleTimeVelocity::default()),
}
}
}
pub trait FeatureModule: Debug {
fn name(&self) -> &str;
fn value(&self) -> f64;
fn update(&mut self, trade: &Trade, init: bool);
}
#[cfg(test)]
mod tests {
use crate::Trade;
pub const TRADES: [Trade; 10] = [
Trade{ timestamp: 0, price: 100.0, size: 10.0 },
Trade{ timestamp: 1, price: 101.0, size: -10.0 },
Trade{ timestamp: 2, price: 100.0, size: 20.0 },
Trade{ timestamp: 3, price: 102.0, size: 10.0 },
Trade{ timestamp: 4, price: 103.0, size: 10.0 },
Trade{ timestamp: 5, price: 104.0, size: -20.0 },
Trade{ timestamp: 6, price: 102.0, size: -10.0 },
Trade{ timestamp: 7, price: 101.0, size: 10.0 },
Trade{ timestamp: 8, price: 102.0, size: 30.0 },
Trade{ timestamp: 9, price: 105.0, size: 10.0 },
];
}