vtse/vtse-server/src/market/generator.rs

67 lines
1.8 KiB
Rust
Raw Normal View History

2021-02-08 17:33:24 +00:00
use rand::{distributions::Uniform, prelude::Distribution};
2021-02-11 18:55:28 +00:00
use rand::{rngs::StdRng, SeedableRng};
use rust_decimal::Decimal;
2021-02-08 17:33:24 +00:00
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
2021-02-11 18:55:28 +00:00
pub(super) struct MarketModifier(Decimal);
impl MarketModifier {
pub(super) fn modifier(&self) -> Decimal {
self.0
}
}
2021-02-08 17:33:24 +00:00
#[derive(Clone, Debug)]
2021-02-11 18:55:28 +00:00
pub(super) struct MarketMultiplier {
rng: StdRng,
sample_range: Uniform<i64>,
volatility: Decimal,
2021-02-08 17:33:24 +00:00
old_price: MarketModifier,
2021-02-11 18:55:28 +00:00
buffer: Vec<MarketModifier>,
2021-02-08 17:33:24 +00:00
}
2021-02-11 18:55:28 +00:00
impl MarketMultiplier {
pub(super) fn new(volatility: Decimal, initial_value: Decimal) -> Self {
2021-02-08 17:33:24 +00:00
Self {
2021-02-11 18:55:28 +00:00
rng: StdRng::from_entropy(),
sample_range: Uniform::new_inclusive(-50, 50),
2021-02-08 17:33:24 +00:00
volatility,
old_price: MarketModifier(initial_value),
2021-02-11 18:55:28 +00:00
buffer: vec![],
2021-02-08 17:33:24 +00:00
}
}
}
2021-02-11 18:55:28 +00:00
impl Iterator for MarketMultiplier {
2021-02-08 17:33:24 +00:00
type Item = MarketModifier;
fn next(&mut self) -> Option<Self::Item> {
// Algorithm from https://stackoverflow.com/a/8597889
let rng_multiplier = self.sample_range.sample(&mut self.rng);
2021-02-11 18:55:28 +00:00
let delta = Decimal::new(2, 0) * self.volatility * Decimal::new(rng_multiplier, 2);
2021-02-08 17:33:24 +00:00
self.old_price.0 += self.old_price.0 * delta;
Some(self.old_price)
}
}
2021-02-11 18:55:28 +00:00
impl MarketMultiplier {
pub(super) fn next_n(&mut self, n: usize) -> Vec<MarketModifier> {
self.ensure_buffer_capacity(n);
let mut ret = self.buffer.split_off(n);
std::mem::swap(&mut ret, &mut self.buffer);
ret
}
pub(super) fn peek_n(&mut self, n: usize) -> &[MarketModifier] {
self.ensure_buffer_capacity(n);
&self.buffer[..n]
}
fn ensure_buffer_capacity(&mut self, n: usize) {
for _ in 0..(n - self.buffer.len()) {
let next_val = self.next().unwrap();
self.buffer.push(next_val);
}
}
}