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!()) }
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}