#[macro_export]
macro_rules! talib_cdl {
($name:ident, $talib_func:path) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
history_open: Vec<f64>,
history_high: Vec<f64>,
history_low: Vec<f64>,
history_close: Vec<f64>,
}
impl $name {
pub fn new() -> Self {
Self {
history_open: Vec::new(),
history_high: Vec::new(),
history_low: Vec::new(),
history_close: Vec::new(),
}
}
}
impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
type Output = f64;
fn next(&mut self, (open, high, low, close): (f64, f64, f64, f64)) -> Self::Output {
self.history_open.push(open);
self.history_high.push(high);
self.history_low.push(low);
self.history_close.push(close);
if let Ok(res) = $talib_func(
&self.history_open,
&self.history_high,
&self.history_low,
&self.history_close,
) {
*res.last().unwrap_or(&0) as f64
} else {
0.0
}
}
}
};
}
#[macro_export]
macro_rules! talib_1_in_1_out_i32 {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history: Vec::new(),
}
}
}
impl $crate::traits::Next<f64> for $name {
type Output = f64;
fn next(&mut self, input: f64) -> Self::Output {
self.history.push(input);
if let Ok(res) = $talib_func(&self.history, $( self.$param.clone() ),*) {
*res.last().unwrap_or(&0) as f64
} else {
0.0
}
}
}
};
}
#[macro_export]
macro_rules! talib_1_in_1_out_no_result {
($name:ident, $talib_func:path) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
history: Vec<f64>,
}
impl $name {
pub fn new() -> Self {
Self {
history: Vec::new(),
}
}
}
impl $crate::traits::Next<f64> for $name {
type Output = f64;
fn next(&mut self, input: f64) -> Self::Output {
self.history.push(input);
let res = $talib_func(&self.history);
*res.last().unwrap_or(&f64::NAN)
}
}
};
}
#[macro_export]
macro_rules! talib_1_in_1_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history: Vec::new(),
}
}
}
impl $crate::traits::Next<f64> for $name {
type Output = f64;
fn next(&mut self, input: f64) -> Self::Output {
self.history.push(input);
let res = $talib_func(&self.history, $( self.$param.clone() ),*).unwrap_or_default();
*res.last().unwrap_or(&f64::NAN)
}
}
};
}
#[macro_export]
macro_rules! talib_2_in_1_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history_high: Vec<f64>,
history_low: Vec<f64>,
}
impl $name {
#[allow(clippy::too_many_arguments)]
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history_high: Vec::new(),
history_low: Vec::new(),
}
}
}
impl $crate::traits::Next<(f64, f64)> for $name {
type Output = f64;
fn next(&mut self, (high, low): (f64, f64)) -> Self::Output {
self.history_high.push(high);
self.history_low.push(low);
let res = $talib_func(&self.history_high, &self.history_low, $( self.$param.clone() ),*).unwrap_or_default();
*res.last().unwrap_or(&f64::NAN)
}
}
};
}
#[macro_export]
macro_rules! talib_1_in_2_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history: Vec::new(),
}
}
}
impl $crate::traits::Next<f64> for $name {
type Output = (f64, f64);
fn next(&mut self, input: f64) -> Self::Output {
self.history.push(input);
if let Ok((res1, res2)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
(*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
} else {
(f64::NAN, f64::NAN)
}
}
}
};
}
#[macro_export]
macro_rules! talib_1_in_3_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history: Vec::new(),
}
}
}
impl $crate::traits::Next<f64> for $name {
type Output = (f64, f64, f64);
fn next(&mut self, input: f64) -> Self::Output {
self.history.push(input);
if let Ok((res1, res2, res3)) = $talib_func(&self.history, $( self.$param.clone() ),*) {
(*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN), *res3.last().unwrap_or(&f64::NAN))
} else {
(f64::NAN, f64::NAN, f64::NAN)
}
}
}
};
}
#[macro_export]
macro_rules! talib_2_in_2_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history_1: Vec<f64>,
history_2: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history_1: Vec::new(),
history_2: Vec::new(),
}
}
}
impl $crate::traits::Next<(f64, f64)> for $name {
type Output = (f64, f64);
fn next(&mut self, (in1, in2): (f64, f64)) -> Self::Output {
self.history_1.push(in1);
self.history_2.push(in2);
if let Ok((res1, res2)) = $talib_func(&self.history_1, &self.history_2, $( self.$param.clone() ),*) {
(*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
} else {
(f64::NAN, f64::NAN)
}
}
}
};
}
#[macro_export]
macro_rules! talib_3_in_1_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history_high: Vec<f64>,
history_low: Vec<f64>,
history_close: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history_high: Vec::new(),
history_low: Vec::new(),
history_close: Vec::new(),
}
}
}
impl $crate::traits::Next<(f64, f64, f64)> for $name {
type Output = f64;
fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
self.history_high.push(high);
self.history_low.push(low);
self.history_close.push(close);
let res = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*).unwrap_or_default();
*res.last().unwrap_or(&f64::NAN)
}
}
};
}
#[macro_export]
macro_rules! talib_3_in_2_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history_high: Vec<f64>,
history_low: Vec<f64>,
history_close: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history_high: Vec::new(),
history_low: Vec::new(),
history_close: Vec::new(),
}
}
}
impl $crate::traits::Next<(f64, f64, f64)> for $name {
type Output = (f64, f64);
fn next(&mut self, (high, low, close): (f64, f64, f64)) -> Self::Output {
self.history_high.push(high);
self.history_low.push(low);
self.history_close.push(close);
if let Ok((res1, res2)) = $talib_func(&self.history_high, &self.history_low, &self.history_close, $( self.$param.clone() ),*) {
(*res1.last().unwrap_or(&f64::NAN), *res2.last().unwrap_or(&f64::NAN))
} else {
(f64::NAN, f64::NAN)
}
}
}
};
}
#[macro_export]
macro_rules! talib_4_in_1_out {
($name:ident, $talib_func:path $(, $param:ident: $ptype:ty)*) => {
#[derive(Debug, Clone)]
#[allow(non_camel_case_types)]
pub struct $name {
$( pub $param: $ptype, )*
history_1: Vec<f64>,
history_2: Vec<f64>,
history_3: Vec<f64>,
history_4: Vec<f64>,
}
impl $name {
pub fn new($( $param: $ptype ),*) -> Self {
Self {
$( $param, )*
history_1: Vec::new(),
history_2: Vec::new(),
history_3: Vec::new(),
history_4: Vec::new(),
}
}
}
impl $crate::traits::Next<(f64, f64, f64, f64)> for $name {
type Output = f64;
fn next(&mut self, (in1, in2, in3, in4): (f64, f64, f64, f64)) -> Self::Output {
self.history_1.push(in1);
self.history_2.push(in2);
self.history_3.push(in3);
self.history_4.push(in4);
let res = $talib_func(&self.history_1, &self.history_2, &self.history_3, &self.history_4, $( self.$param.clone() ),*).unwrap_or_default();
*res.last().unwrap_or(&f64::NAN)
}
}
};
}