equity_scanner/
equity.rs

1use std::fmt::{self, Display};
2
3use crate::utils::{indicators::calculate_rsi, structs::HistoricalData};
4#[derive(Debug, Clone)]
5pub struct Equity {
6    pub historical_data: crate::utils::structs::HistoricalData,
7    pub ticker: String,
8    rsi_undervalued: f64,
9    rsi_overvalued: f64,
10}
11pub struct InvalidData;
12
13impl fmt::Display for InvalidData {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        write!(f, "An error has occured, Inalid data has been used.")
16    }
17}
18impl fmt::Debug for InvalidData {
19    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20        write!(f, "{{ file: {}, line: {} }}", file!(), line!()) // programmer-facing output
21    }
22}
23
24impl Equity {
25    pub fn new(ticker: String, historical_data: HistoricalData) -> Self {
26        Equity {
27            ticker,
28            historical_data,
29            rsi_undervalued: 25.0,
30            rsi_overvalued: 70.0,
31        }
32    }
33
34    pub fn current_rsi(&mut self, window: usize) -> Result<f64, InvalidData> {
35        Ok(*self.rsi_values(window)?.last().unwrap())
36    }
37    pub fn current_default_rsi(&mut self) -> Result<f64, InvalidData> {
38        self.current_rsi(14)
39    }
40    pub fn rsi_values(&mut self, window: usize) -> Result<Vec<f64>, InvalidData> {
41        calculate_rsi(&self.historical_data.close, window)
42    }
43    pub fn is_undervalued(&mut self) -> Result<bool, InvalidData> {
44        Ok(self.current_rsi(14).unwrap() < self.rsi_undervalued)
45    }
46    pub fn is_overvalued(&mut self) -> Result<bool, InvalidData> {
47        Ok(self.current_rsi(14).unwrap() > self.rsi_overvalued)
48    }
49}
50
51impl Display for Equity {
52    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53        let closing_price = self.historical_data.close[self.historical_data.close.len()-1];
54        write!(f, "{} at {}", self.ticker, closing_price)
55    }
56}