Skip to content

Commit

Permalink
upd
Browse files Browse the repository at this point in the history
  • Loading branch information
m5l14i11 committed Apr 22, 2024
1 parent 2fbb1cd commit 16634c3
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 40 deletions.
120 changes: 81 additions & 39 deletions ta_lib/indicators/trend/src/supertrend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,42 @@ pub fn supertrend(
atr: &Series<f32>,
factor: f32,
) -> (Series<f32>, Series<f32>) {
let len = source.len();

let atr_mul = atr * factor;
let prev_close = close.shift(1);
let len = close.len();

let mut up = source - &atr_mul;
let mut dn = source + &atr_mul;
let basic_up = source - &atr_mul;
let mut up = Series::empty(len);

let basic_dn = source + &atr_mul;
let mut dn = Series::empty(len);

let prev_close = close.shift(1);
let mut direction = Series::empty(len);
let mut supertrend = Series::empty(len);

let trend_bull = Series::one(len);
let trend_bear = trend_bull.negate();
direction = iff!(&atr.shift(1).na(), trend_bull, direction);

for _ in 0..len {
let prev_up = nz!(up.shift(1), up);
up = iff!(up.sgt(&prev_up) | prev_close.slt(&prev_up), up, prev_up);
let prev_up = up.shift(1);
up = iff!(prev_close.sgt(&prev_up), basic_up.max(&prev_up), basic_up);

let prev_dn = nz!(dn.shift(1), dn);
dn = iff!(dn.slt(&prev_dn) | prev_close.sgt(&prev_dn), dn, prev_dn);
let prev_dn = dn.shift(1);
dn = iff!(prev_close.slt(&prev_dn), basic_dn.min(&prev_dn), basic_dn);

let prev_supertrend = supertrend.shift(1);
direction = nz!(direction.shift(1), direction);
direction = iff!(close.sgte(&prev_dn), trend_bull, direction);
direction = iff!(close.slte(&prev_up), trend_bear, direction);
}

direction = iff!(
&atr.shift(1).na(),
trend_bull,
iff!(
prev_supertrend.seq(&prev_dn),
iff!(close.sgt(&dn), trend_bear, trend_bull),
iff!(close.slt(&up), trend_bull, trend_bear)
)
);
let first_non_empty = direction
.iter()
.find(|&&el| el.is_some())
.map(|&el| -el.unwrap());

supertrend = iff!(direction.seq(&MINUS_ONE), up, dn);
}
direction = direction.nz(first_non_empty);

let supertrend = iff!(direction.seq(&ONE), up, dn);

(direction, supertrend)
}
Expand All @@ -51,37 +53,77 @@ mod tests {
use volatility::atr;

#[test]
fn test_supertrend() {
fn test_supertrend_up_dn() {
let high = Series::from([
6.649, 6.644, 6.645, 6.648, 6.644, 6.664, 6.627, 6.633, 6.608, 6.594, 6.593, 6.565,
6.556, 6.550, 6.561, 6.579, 6.610, 6.615, 6.591, 6.614, 6.637, 6.630,
]);
let low = Series::from([
6.634, 6.631, 6.632, 6.638, 6.605, 6.623, 6.600, 6.593, 6.578, 6.575, 6.558, 6.536,
6.536, 6.520, 6.543, 6.559, 6.565, 6.584, 6.581, 6.583, 6.609, 6.608,
]);
let close = Series::from([
6.644, 6.639, 6.638, 6.644, 6.641, 6.625, 6.624, 6.608, 6.582, 6.592, 6.558, 6.545,
6.544, 6.546, 6.560, 6.565, 6.610, 6.585, 6.590, 6.609, 6.621, 6.623,
]);
let hl2 = median_price(&high, &low);
let atr_period = 3;
let atr = atr(&high, &low, &close, Smooth::SMMA, atr_period);

let factor = 3.0;
let expected_supertrend = vec![
6.596499, 6.596499, 6.596833, 6.6052217, 6.6052217, 6.6052217, 6.6052217, 6.6052217,
6.680167, 6.6658287, 6.664719, 6.6389794, 6.6249866, 6.617658, 6.617658, 6.617658,
6.617658, 6.617658, 6.617658, 6.617658, 6.5427637, 6.5435085,
];
let expected_direction = vec![
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, 1.0, 1.0,
];

let (direction, supertrend) = supertrend(&hl2, &close, &atr, factor);
let result_direction: Vec<f32> = direction.into();
let result_supertrend: Vec<f32> = supertrend.into();

assert_eq!(high.len(), low.len());
assert_eq!(high.len(), close.len());
assert_eq!(result_direction, expected_direction);
assert_eq!(result_supertrend, expected_supertrend);
}

#[test]
fn test_supertrend_dn_up() {
let high = Series::from([
6.622, 6.650, 6.664, 6.687, 6.695, 6.647, 6.624, 6.607, 6.609, 6.614, 6.609, 6.590,
6.580, 6.580, 6.586, 6.587, 6.586, 6.574, 6.584, 6.577, 6.578, 6.583, 6.575, 6.577,
6.578, 6.567, 6.575, 6.588, 6.596, 6.600, 6.587, 6.573, 6.566, 6.586,
6.161, 6.15, 6.157, 6.174, 6.179, 6.192, 6.184, 6.183, 6.185, 6.193, 6.213, 6.201,
6.205, 6.188, 6.18, 6.194, 6.191, 6.184, 6.194, 6.188, 6.188, 6.195, 6.212, 6.21,
6.193, 6.178, 6.189, 6.197, 6.205, 6.232, 6.236, 6.222, 6.233, 6.231, 6.224, 6.219,
]);
let low = Series::from([
6.582, 6.614, 6.636, 6.637, 6.602, 6.606, 6.576, 6.579, 6.579, 6.587, 6.562, 6.566,
6.559, 6.551, 6.567, 6.556, 6.560, 6.541, 6.543, 6.564, 6.560, 6.557, 6.557, 6.565,
6.559, 6.552, 6.563, 6.567, 6.575, 6.570, 6.570, 6.541, 6.552, 6.555,
6.136, 6.135, 6.143, 6.155, 6.163, 6.17, 6.167, 6.17, 6.161, 6.165, 6.188, 6.183,
6.186, 6.168, 6.164, 6.176, 6.169, 6.175, 6.176, 6.171, 6.171, 6.182, 6.193, 6.18,
6.152, 6.161, 6.161, 6.183, 6.189, 6.193, 6.215, 6.205, 6.208, 6.213, 6.196, 6.202,
]);
let close = Series::from([
6.617, 6.645, 6.641, 6.679, 6.627, 6.624, 6.593, 6.607, 6.588, 6.608, 6.581, 6.579,
6.569, 6.574, 6.574, 6.578, 6.568, 6.543, 6.577, 6.571, 6.563, 6.575, 6.565, 6.573,
6.567, 6.563, 6.571, 6.578, 6.596, 6.574, 6.572, 6.556, 6.555, 6.579,
6.146, 6.148, 6.155, 6.174, 6.173, 6.172, 6.182, 6.176, 6.167, 6.193, 6.201, 6.198,
6.188, 6.174, 6.176, 6.191, 6.175, 6.184, 6.188, 6.179, 6.184, 6.195, 6.21, 6.192,
6.173, 6.174, 6.189, 6.194, 6.202, 6.231, 6.218, 6.208, 6.224, 6.22, 6.208, 6.204,
]);
let hl2 = median_price(&high, &low);
let atr_period = 3;
let atr = atr(&high, &low, &close, Smooth::SMMA, atr_period);

let factor = 3.0;
let expected_supertrend = vec![
6.7220016, 6.7220016, 6.7220016, 6.7220016, 6.7220016, 6.7220016, 6.7220016, 6.7220016,
6.71035, 6.7050667, 6.7022114, 6.679808, 6.658372, 6.653748, 6.653748, 6.653748,
6.653748, 6.644672, 6.644672, 6.644672, 6.639718, 6.639718, 6.632763, 6.627509,
6.6251726, 6.6122813, 6.6122813, 6.6122813, 6.6122813, 6.6122813, 6.6122813, 6.6122813,
6.6122813, 6.6122813,
6.223499, 6.207499, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326,
6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326,
6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.2073326, 6.1522994, 6.1522994,
6.1522994, 6.1522994, 6.1522994, 6.1522994, 6.1522994, 6.1522994, 6.1522994, 6.1522994,
6.1522994, 6.1580467, 6.1580467, 6.1580467,
];
let expected_direction = vec![
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
];

let (direction, supertrend) = supertrend(&hl2, &close, &atr, factor);
Expand Down
2 changes: 1 addition & 1 deletion ta_lib/strategies/signal/src/flip/supertrend_flip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Signal for SupertrendFlipSignal {
self.factor,
);

(direction.cross_under(&ZERO), direction.cross_over(&ZERO))
(direction.cross_over(&ZERO), direction.cross_under(&ZERO))
}
}

Expand Down

0 comments on commit 16634c3

Please sign in to comment.