Added TimeSeries random generation using gaussian distributions. Started MACD (barley...).

dev
Griffiths Lott 3 years ago
parent 7fd3d80504
commit c3e1b50b5f
  1. 3
      Cargo.toml
  2. 35
      src/data/timeseries.rs
  3. 3
      src/indicators.rs
  4. 35
      src/indicators/macd.rs
  5. 16
      src/tests.rs

@ -8,4 +8,5 @@ edition = "2021"
[dependencies]
chrono = "0.4.23"
regex = "1.7.0"
polars = "0.25.1"
polars = "0.25.1"
probability = "0.20.3"

@ -2,8 +2,9 @@ use chrono::{DateTime, Utc};
use super::{Volume, TimeStamp, DynResult};
use polars::{prelude::DataFrame, df, prelude::{NamedFrom}};
use super::quotes::HOLC;
use probability::prelude::*;
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Candle {
pub high: f64,
pub open: f64,
@ -40,11 +41,16 @@ impl HOLC for Candle {
fn low(&self) -> f64 { self.low }
fn close(&self) -> f64 { self.close}
}
impl TimeStamp for Candle {
fn timestamp(&self) -> DateTime<Utc> {
self.timestamp
}
}
pub struct TimeSeries {
candles: Vec<Candle>
pub candles: Vec<Candle>
}
impl TimeSeries {
pub fn new(candles: Vec<Candle>) -> Self {
@ -65,8 +71,33 @@ impl TimeSeries {
pub fn as_vec(&self) -> Vec<Candle>{
return self.candles.clone()
}
pub fn generate_random(n_datapoints: usize, mut start_price: f64) -> Self {
let mut data: Vec<Candle> = vec![];
let inter_day_dist = Gaussian::new(1.0043,0.021);
let mut source = source::default(420);
let mut inter_sampler = Independent(&inter_day_dist, &mut source);
let intra_day_dist = Gaussian::new(1.003,0.011);
let mut source2 = source::default(69);
let mut intra_sampler = Independent(&intra_day_dist, &mut source2);
let day_moves = inter_sampler.take(n_datapoints).collect::<Vec<_>>();
let intraday_moves = intra_sampler.take(n_datapoints * 3).collect::<Vec<_>>();
for n in 0..n_datapoints {
let close = start_price * day_moves[n];
data.push( Candle::new(start_price * intraday_moves[n], start_price, start_price * intraday_moves[n+1], close, Some((18183.0 * intraday_moves[n+3]) as u64), Utc::now()));
start_price = close;
}
TimeSeries { candles: data }
}
}
pub fn create_timeseries_dataframe(timeseries_data: &Vec<Candle>) -> DynResult<DataFrame> {
let mut high = vec![];
let mut open = vec![];

@ -1,2 +1,3 @@
pub mod ma;
pub mod rsi;
pub mod rsi;
pub mod macd;

@ -0,0 +1,35 @@
use crate::indicators::ma::exponential_moving_average;
use crate::data::quotes::HOLC;
use crate::data::TimeStamp;
pub struct MACD {
upperBand: Vec<f64>,
lowerBand: Vec<f64>,
signalLine: Vec<f64>,
}
impl MACD {
pub fn new<C: HOLC + TimeStamp + Clone>(data: Vec<C>, upperBand: Option<usize>, lowerBand: Option<usize>, signalBand: Option<usize>) {
// This is going to need a custom implementation. It's not efficent to clone and iterate through the data 3 seperate times
let ub = upperBand.unwrap_or(26);
let lb = lowerBand.unwrap_or(12);
let sb = signalBand.unwrap_or(9);
let u_ema = exponential_moving_average(data.clone(), ub);
let l_ema = exponential_moving_average(data.clone(), lb);
let s_ema = exponential_moving_average(data.clone(), sb);
println!("u_ema = {:?}", u_ema);
println!("u_ema.len() = {:?}", u_ema.len());
println!("l_ema = {:?}", l_ema);
println!("l_ema.len() = {:?}", l_ema.len());
println!("s_ema = {:?}", s_ema);
println!("s_ema.len() = {:?}", s_ema.len());
}
}
fn moving_average_convergence_divergence<C: HOLC>(data: Vec<C>) {
}

@ -1,8 +1,9 @@
#[cfg(test)]
mod tests {
use crate::data::timeseries::Candle;
use crate::data::timeseries::{Candle, TimeSeries};
use crate::indicators::ma::exponential_moving_average;
use crate::indicators::rsi::relative_strength_index;
use crate::indicators::macd::MACD;
use crate::indicators::{ma};
use crate::data::quotes::{HOLC};
use chrono::Utc;
@ -109,4 +110,17 @@ mod tests {
let rsi_d = relative_strength_index(data, 14);
println!("rsi_d = {:?}", rsi_d);
}
#[test]
fn candle_gen() {
let data = TimeSeries::generate_random(50, 100.0);
for c in data.candles.iter() {
println!("c = {:?}", c);
}
}
#[test]
fn macd(){
let data = TimeSeries::generate_random(50, 100.0);
let x = MACD::new(data.candles, None,None,None);
}
}
Loading…
Cancel
Save