use charts::Chart;
use charts::SourceSeries;
use charts::utils::{highest, lowest};
pub struct Ichimoku<'chart> {
chart: &'chart Chart,
turning_line_period: usize,
standard_line_period: usize,
span_b_period: usize,
lagging_span_displacement: usize,
}
impl<'chart> Ichimoku<'chart> {
pub fn new(
chart: &'chart Chart,
turning_line_period: usize,
standard_line_period: usize,
span_b_period: usize,
lagging_span_displacement: usize,
) -> Self {
Ichimoku {
chart: chart,
turning_line_period: turning_line_period,
standard_line_period: standard_line_period,
span_b_period: span_b_period,
lagging_span_displacement: lagging_span_displacement,
}
}
pub fn default(chart: &'chart Chart) -> Self {
Ichimoku {
chart: chart,
turning_line_period: 9,
standard_line_period: 26,
span_b_period: 52,
lagging_span_displacement: 26,
}
}
pub fn turning_line(&self, index: usize) -> Option<f64> {
let lowest_val = match lowest(self.chart.low().offset(index), self.turning_line_period) {
None => {
return None;
}
Some(lowest_val) => lowest_val,
};
let highest_val = match highest(self.chart.high().offset(index), self.turning_line_period) {
None => {
return None;
}
Some(highest_val) => highest_val,
};
let result = (lowest_val + highest_val) / 2.0;
Some(result)
}
pub fn standard_line(&self, index: usize) -> Option<f64> {
let lowest_val = match lowest(self.chart.low().offset(index), self.standard_line_period) {
None => {
return None;
}
Some(lowest_val) => lowest_val,
};
let highest_val = match highest(self.chart.high().offset(index), self.standard_line_period)
{
None => {
return None;
}
Some(highest_val) => highest_val,
};
let result = (lowest_val + highest_val) / 2.0;
Some(result)
}
pub fn span_a(&self, index: i64) -> Option<f64> {
let normalized_index = index + (self.lagging_span_displacement as i64);
if normalized_index < 0 {
return None;
}
let normalized_index = normalized_index as usize;
let turning_line_val = match self.turning_line(normalized_index) {
None => {
return None;
}
Some(x) => x,
};
let standard_line_val = match self.standard_line(normalized_index) {
None => {
return None;
}
Some(x) => x,
};
let result = (turning_line_val + standard_line_val) / 2.0;
Some(result)
}
pub fn span_b(&self, index: i64) -> Option<f64> {
let normalized_index = index + (self.lagging_span_displacement as i64);
if normalized_index < 0 {
return None;
}
let normalized_index = normalized_index as usize;
let lowest_val = match lowest(
self.chart.low().offset(normalized_index),
self.span_b_period,
) {
None => {
return None;
}
Some(lowest_val) => lowest_val,
};
let highest_val = match highest(
self.chart.high().offset(normalized_index),
self.span_b_period,
) {
None => {
return None;
}
Some(highest_val) => highest_val,
};
let result = (lowest_val + highest_val) / 2.0;
Some(result)
}
pub fn lagging_line(&self, index: i64) -> Option<f64> {
let normalized_index = index - (self.lagging_span_displacement as i64);
if normalized_index < 0 {
return None;
}
let normalized_index = normalized_index as usize;
self.chart.close().get(normalized_index)
}
}