trtr

Trading simulator and techanalysis gym
git clone https://git.ea.contact/trtr
Log | Files | Refs | README

session.rs (1761B)


      1 use rand::Rng;
      2 use serde::{Deserialize, Serialize};
      3 
      4 use crate::data::Candle;
      5 
      6 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq)]
      7 #[serde(rename_all = "lowercase")]
      8 pub enum Direction {
      9     Long,
     10     Short,
     11 }
     12 
     13 pub struct ActivePrediction {
     14     pub target_index: usize,
     15     pub entry_price: f64,
     16     pub direction: Direction,
     17     pub fee_pct: f64,
     18 }
     19 
     20 #[derive(Serialize, Clone)]
     21 pub struct ResolvedPrediction {
     22     pub entry_price: f64,
     23     pub close_price: f64,
     24     pub direction: Direction,
     25     pub fee_pct: f64,
     26     pub profit: f64,
     27 }
     28 
     29 #[derive(Clone)]
     30 pub enum SseEvent {
     31     Candles { candles: Vec<Candle>, resolved: Option<ResolvedPrediction> },
     32     Predict { entry_price: f64, direction: Direction, bars_ahead: u32, fee_pct: f64 },
     33     PredictCancel,
     34 }
     35 
     36 pub struct SessionState {
     37     pub start_index: usize,
     38     pub current_index: usize,
     39     pub prediction: Option<ActivePrediction>,
     40     pub tx: tokio::sync::broadcast::Sender<SseEvent>,
     41 }
     42 
     43 impl SessionState {
     44     pub fn new(start_index: usize) -> Self {
     45         let (tx, _) = tokio::sync::broadcast::channel(256);
     46         Self {
     47             start_index,
     48             current_index: start_index + 99,
     49             prediction: None,
     50             tx,
     51         }
     52     }
     53 }
     54 
     55 pub fn random_start_index(total: usize, rng: &mut impl Rng) -> usize {
     56     let max = total.saturating_sub(5100);
     57     rng.random_range(0..=max)
     58 }
     59 
     60 pub fn resolve_prediction(pred: &ActivePrediction, close_price: f64) -> f64 {
     61     let gross_pct = match pred.direction {
     62         Direction::Long  => (close_price - pred.entry_price) / pred.entry_price,
     63         Direction::Short => (pred.entry_price - close_price) / pred.entry_price,
     64     };
     65     let fee_factor = (1.0 - pred.fee_pct / 100.0).powi(2);
     66     gross_pct * fee_factor * 100.0
     67 }