ux_indicators/
indicator.rs

1#![allow(dead_code)]
2#![allow(unused_variables)]
3#![allow(unused_imports)]
4
5use crate::indicators::SimpleMovingAverage;
6use crate::{Next};
7
8use std::collections::VecDeque;
9use std::collections::HashMap;
10use std::rc::Rc;
11use std::cell::RefCell;
12use crate::errors::Error;
13
14#[derive(Debug, Clone)]
15pub enum DataPoint {
16    Ohlcv(Ohlcv),
17    BidAsk(BidAsk),
18    Frame(Frame),
19}
20
21// used for input node
22#[derive(Debug, Clone)]
23pub struct Ohlcv {
24    // for syncing
25    timestamp: u64,
26    // values
27    open: f64,
28    high: f64,
29    low: f64,
30    close: f64,
31    volume: f64,
32}
33
34impl Ohlcv {
35    pub fn new() -> Self {
36        Self {
37            timestamp: 0,
38            open: 0.0,
39            high: 0.0,
40            low: 0.0,
41            close: 0.0,
42            volume: 0.0,
43        }
44    }
45}
46
47#[derive(Debug, Clone)]
48pub struct BidAsk {
49    // for syncing
50    timestamp: u64,
51    // price
52    price: f64,
53    // value
54    amount: f64,
55}
56
57impl BidAsk {
58    pub fn new() -> Self {
59        Self {
60            timestamp: 0,
61            price: 0.0,
62            amount: 0.0,
63        }
64    }
65}
66
67// is dataframe
68#[derive(Debug, Clone)]
69pub struct Frame {
70    // for syncing
71    timestamp: u64,
72    // value
73    data: f64,
74}
75
76impl Frame {
77    pub fn new() -> Self {
78        Self {
79            timestamp: 0,
80            data: 0.0,
81        }
82    }
83}
84
85#[derive(Debug, Clone, PartialEq)]
86pub enum SlotType {
87    Input,
88    Output,
89}
90
91// define slot
92#[derive(Debug, Clone)]
93pub struct Slot {
94    pub name: String,
95    slot_type: SlotType,
96    state: f64, // used to store value when it input type
97    pub changed: bool, // when it input type,
98    connected: bool, // when in input type,
99    connections: Vec<Rc<RefCell<Slot>>>, // used to keep references when it output type
100}
101
102impl Slot {
103    pub fn new(slot_type: SlotType) -> Self {
104        Self {
105            name: String::from("slot"),
106            slot_type: slot_type,
107            state: 0.0,
108            changed: false,
109            connected: false,
110            connections: vec![],
111        }
112    }
113    // output is multiple, input is single
114    pub fn connect(&mut self, wire: Rc<RefCell<Slot>>) -> Result<(), Error> {
115        if self.slot_type == SlotType::Output {
116            return Ok(())
117        }
118        // self.wire = Some(wire)
119        Err("The error message".into())
120    }
121    // pub fn wire(&self) -> Option<Rc<RefCell<Wire>>> {
122    //     // &self.wire
123    //     None
124    // }
125
126    // put data into buffer
127    pub fn put(&mut self, val: f64) {
128        if self.state != val {
129            self.changed = true;
130        }
131        self.state = val;
132    }
133
134    // fetch data from buffer 
135    pub fn get(&mut self) -> f64 {
136        self.changed = false;
137        self.state
138    }
139}
140
141pub type SlotPtr = *mut Slot;
142
143#[derive(Debug, Clone)]
144pub struct Indicator {
145    inputs: HashMap<String, Slot>,
146    outputs: HashMap<String, Slot>,
147}
148
149impl Indicator {
150    pub fn new() -> Self {
151        Self {
152            inputs: HashMap::new(),
153            outputs: HashMap::new(),
154        }
155    }
156    pub fn slot(&self, name: &str) -> Option<Rc<RefCell<Slot>>> {
157        None
158    }
159    pub fn stuff(&self) {
160
161    }
162}
163
164#[derive(Debug, Clone)]
165pub enum InputType {
166    Ohlcv,
167    BidAsk,
168    Frame,
169}
170
171#[derive(Debug, Clone)]
172pub struct Input {
173    input_type: InputType,
174    slots: Vec<Slot>,
175    timeseries: VecDeque<DataPoint>,
176}
177
178impl Input {
179    pub fn new(input_type: InputType) -> Self {
180        Self {
181            input_type: input_type,
182            slots: vec![],
183            timeseries: VecDeque::new(),
184        }
185    }
186    pub fn slot(&self, name: &str) -> Option<Rc<RefCell<Slot>>> {
187        None
188    }
189
190    pub fn push(&mut self, item: DataPoint) {
191        match item {
192            DataPoint::Ohlcv(_) => {
193                // let a: Ohlcv = val;
194                self.timeseries.push_back(item);
195            },
196            _ => {
197                print!("unhandled node type")
198            },
199        }
200    }
201}
202
203#[derive(Debug, Clone)]
204pub struct View {
205    plots: Vec<Rc<Plot>>,
206}
207
208impl View {
209    pub fn new() -> Self {
210        Self {
211            plots: vec![],
212        }
213    }
214
215    pub fn attach(&mut self, plot: Rc<Plot>){
216        self.plots.push(plot);
217    }
218}
219
220#[derive(Debug, Clone)]
221pub struct Plot {
222    view: Option<View>,
223    timeseries: VecDeque<Frame>,
224}
225
226impl Plot {
227    pub fn new() -> Self {
228        Self {
229            view: None,
230            timeseries: VecDeque::new(),
231        }
232    }
233    // draw to view
234    pub fn draw(&self){
235
236    }
237
238    pub fn slot(&self, name: &str) -> Option<Rc<RefCell<Slot>>> {
239        None
240    }
241}
242
243enum Node {
244    // Wire(Rc<RefCell<Wire>>),
245    Input(Rc<Input>),
246    Indicator(Rc<Indicator>),
247    Plot(Rc<Plot>),
248    View(Rc<View>),
249    Text(String),
250}
251
252pub fn example() {
253    let mut input: Input = Input::new(InputType::Ohlcv);
254
255    let indicator: Indicator = Indicator::new();
256
257    let plot: Plot = Plot::new();
258
259    // let input_wire: Rc<RefCell<Wire>> = Rc::new(RefCell::new(Wire::new()));
260    // let output_wire: Rc<RefCell<Wire>> = Rc::new(RefCell::new(Wire::new()));
261    let mut view: View = View::new();
262
263    // input -> indicator
264    let input_close = input.slot("close").unwrap();
265    let mut input_close = input_close.borrow_mut();
266    {    
267        let indicator_close = indicator.slot("close").unwrap();
268        let _ = input_close.connect(Rc::clone(&indicator_close));
269    }
270        
271    // // indicator -> plot
272    let indicator_output = indicator.slot("output").unwrap();
273    let mut indicator_output = indicator_output.borrow_mut();
274    {
275        let plot_close = plot.slot("close").unwrap();
276        let _ = indicator_output.connect(Rc::clone(&plot_close));
277    }
278    
279
280    let rcplot = Rc::new(plot);
281    // put plot into view
282    view.attach(Rc::clone(&rcplot));
283    
284    let a: &Plot = rcplot.as_ref();
285    a.draw();
286
287    input.push(DataPoint::Ohlcv(Ohlcv{
288        timestamp: 1,
289        open: 0.1,
290        high: 0.1,
291        low: 0.1,
292        close: 0.1,
293        volume: 0.1,
294    }));
295
296    // collect all to workspace
297    let workspace: Vec<Node> = vec![
298        Node::Input(Rc::new(input)),
299        Node::Indicator(Rc::new(indicator)),
300        Node::Plot(rcplot),
301        Node::View(Rc::new(view)),
302    ];
303
304    for item in workspace.iter() {
305        match item {
306            Node::View(val) => {
307                let a: &View = val;
308            },
309            Node::Plot(val) => {
310                let a: &Plot = val;
311            },
312            Node::Text(val) => {
313                let a: String = val.to_string();
314            },
315            _ => {
316                print!("unhandled node type")
317            },
318        }
319    } 
320}
321
322// pub struct Inticator {
323//     _impl: Box<dyn Next<f64, Output = Box<[f64]>>>,
324// }
325
326// impl Inticator {
327//     pub fn new(name: &str) -> Result<Inticator, JsValue> {
328//         match name {
329//             // 0 => Err(Error::from_kind(ErrorKind::InvalidParameter)),
330//             "ichimoku" => {
331//                 Ok(Inticator {
332//                     _impl: Box::new(SimpleMovingAverage::default()),
333//                 })
334//             }
335//             _ => {
336//                 Ok(Inticator {
337//                     _impl: Box::new(SimpleMovingAverage::default()),
338//                 })
339//             }
340//         }
341//     }
342
343//     pub fn get_contents(&self) -> u32 {
344//         0
345//     }
346// }