use itertools::multiunzip;
use traquer::trend;
mod common;
#[test]
fn test_adx() {
let stats = common::test_data();
let result: (Vec<f64>, Vec<f64>, Vec<f64>) =
multiunzip(trend::adx(&stats.high, &stats.low, &stats.close, 14, 14));
assert_eq!(stats.close.len(), result.0.len());
assert_eq!(
vec![
31.860139412194698,
30.900411343329193,
29.846209753924423,
28.926644263612655,
29.10834871990969,
29.939197830151386,
29.09419668802638,
30.29237400866025,
29.60030469615574,
28.537858280042748,
32.473148424041746,
34.982949940305744,
33.47283006287883,
33.22624512306407,
34.306046041056824,
32.83133865336625,
33.02567539621716,
32.10723238925509,
37.32862815236502,
35.23477297887128,
],
result.0[14..]
);
assert_eq!(
vec![
26.730133235533003,
28.809316234232448,
28.26198015278067,
28.174104325301958,
26.454545579221207,
25.18695046089198,
24.47607630765512,
23.69367885417301,
23.152365451974088,
24.818266407121218,
23.34724730276131,
22.051913999559698,
23.91704820756414,
22.602128450065592,
21.10029388200336,
20.193259616585753,
19.03617008379953,
18.027067079868925,
16.20809033889095,
17.880973133699126,
],
result.1[14..]
);
assert_eq!(
vec![
10.317020581019671,
11.282545552195204,
12.179104454001054,
13.228521011257213,
14.289690573973955,
16.086895874937387,
17.27152240413718,
],
result.2[14 + 14 - 1..]
);
}
#[test]
fn test_shinohara() {
let stats = common::test_data();
let results =
trend::shinohara(&stats.high, &stats.low, &stats.close, 26).collect::<Vec<(f64, f64)>>();
assert_eq!(stats.close.len(), results.len());
assert_eq!(
vec![
(119.72458721822203, 126.54955949420238),
(95.38515682324336, 167.3688494557726),
(68.70621869411681, 146.27994868199906),
(85.35865719588207, 142.35182619352173),
(119.54886405652606, 125.70722906999697),
(139.72926160563833, 118.00938106154118),
(150.77427373025645, 143.57856018147575),
(150.9041867287, 133.74958218587676),
],
results[26..]
);
}
#[test]
fn test_vortex() {
let stats = common::test_data();
let (vi_pos, vi_neg): (Vec<f64>, Vec<f64>) =
trend::vortex(&stats.high, &stats.low, &stats.close, 16).unzip();
assert_eq!(stats.close.len(), vi_neg.len());
assert_eq!(
vec![
0.8610723090930696,
0.8159089697456218,
0.5782198030623583,
0.7200793857247078,
0.8358118890986928,
0.9355813847576413,
0.9484126915125689,
0.8489016637989781,
0.9131108818882286,
0.9790387062979787,
0.9343265196480259,
0.9443134085341751,
1.0302488811514465,
1.0364553935724832,
1.0553301509762798,
1.1219923299032897,
1.161732264987062,
1.1478332770638693,
],
vi_pos[16..]
);
assert_eq!(
vec![
1.029701151945177,
1.1817046446451998,
1.3803206728528217,
1.238892593460365,
1.1850444607043855,
1.061167502645104,
1.111042759028416,
1.1313347365841422,
0.9951327158267141,
0.9280527122256887,
0.9901265627745084,
0.9313767804581332,
0.8402113281909229,
0.891932290028499,
0.8280623772231498,
0.7860652938018367,
0.6974842970716879,
0.7557323147066469,
],
vi_neg[16..]
);
}
#[test]
fn test_asi() {
let stats = common::test_data();
let result =
trend::asi(&stats.open, &stats.high, &stats.low, &stats.close, 0.5).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
1863.9824746176116,
2518.870278279931,
1414.4607588834258,
200.16630207287312,
-287.17443333696406,
140.33438358003576,
-83.52599754837223,
-194.2381040936168,
-31.480027912299164,
-129.60148013703076,
-230.73994525705402,
-633.9245355218358,
-350.7353785342241,
-550.6900052273131,
-877.5564066919939,
-814.4248306013101,
-1068.1014776886707,
-852.6830438165487,
-850.5201255758901,
-706.8209334968981,
-591.3583165615997,
-540.0037631656671,
-558.3082289963969,
-129.2878803223134,
11.980599030152518,
-171.81932858713316,
-11.782721950164472,
224.08405151584364,
133.9193437940254,
296.08769712031574,
440.92175105199294,
499.93140160760476,
178.6712171227731,
],
result[1..]
);
}
#[test]
fn test_ulcer() {
let stats = common::test_data();
let result = trend::ulcer(&stats.close, 8).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert!(common::vec_eq(
&vec![
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
20.73223668909602,
19.094435269396094,
16.649343658592862,
14.662110635179326,
13.083755073024895,
12.845054285539643,
11.60084753454864,
10.833635700777663,
10.094706264836718,
8.405227208060785,
6.91887557627602,
4.390517821635424,
3.822504042165251,
2.511303218451697,
1.5486160074003668,
1.7365186635053362,
1.7365186635053362,
1.6390653783421978,
1.6390653783421978,
2.187009055695484,
],
&result
));
}
#[test]
fn test_supertrend() {
let stats = common::test_data();
let result =
trend::supertrend(&stats.high, &stats.low, &stats.close, 16, 3.0).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert!(common::vec_eq(
&vec![
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
22.87718629837036,
22.87718629837036,
22.87718629837036,
25.36115028045606,
25.5548271386142,
27.535275836318306,
28.482134516844127,
28.482134516844127,
30.372852510605856,
33.54470377638434,
33.54470377638434,
33.54470377638434,
34.55477737989572,
34.70432339242238,
35.73655158775987,
36.52801923545023,
39.78407957956028,
39.78407957956028,
],
&result
));
}
#[test]
fn test_rwi() {
let stats = common::test_data();
let result = trend::rwi(&stats.high, &stats.low, &stats.close, 16).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
(0.9498065403643551, 1.7412617466727387,),
(0.4556737540683345, 1.7685523890567207,),
(1.4057386211737706, 1.535472296106406,),
(1.3556485021734983, 0.9465833084480927,),
(0.8746671860087694, 0.9071038763955941,),
(1.7233013034774831, 0.754581037874933,),
(1.1384779666654379, 0.7193916946064202,),
(0.8296249568590155, 2.0526327677377094,),
(2.325650322092707, 0.5940724651955457,),
(1.8773568877196494, 0.28738638191882215,),
(1.1197267076507562, 1.3710140568798879,),
(1.3627638621436993, 0.9996428423372017,),
(1.5457049579330462, 0.6073614247767936,),
(1.1223183991371906, 0.8673129298714549,),
(1.4756091887717602, 0.7926835319767893,),
(1.1929354504792102, 0.7647051876347102,),
(2.6484633151147925, 0.21501740699560723,),
(1.111277033009784, 1.1996531008663207,),
],
result[16..]
);
}
#[test]
fn test_psar() {
let stats = common::test_data();
let result = trend::psar(&stats.high, &stats.low, None, None).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
45.34000015258789,
45.34000015258789,
46.08000183105469,
47.232801818847655,
74.9000015258789,
74.2899015045166,
73.07830544433594,
71.9151732265625,
70.7985662975,
69.7266236456,
68.697558699776,
67.70965635178496,
66.15027704392004,
64.68446049452703,
63.306592938097594,
61.41646552746385,
59.20681894419989,
56.74600076244864,
54.03056044208278,
51.695281766568144,
49.686942105625555,
47.95976999721493,
46.47440198398179,
37.349998474121094,
37.52697853088379,
37.98109943237304,
38.41705549780273,
38.835573320615225,
39.4837789177162,
40.09309217899112,
40.875244719222614,
41.82072043040582,
43.42143396044658
],
result[1..]
);
}
#[test]
fn test_dpo() {
let stats = common::test_data();
let result = trend::dpo(&stats.close, 16, None).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert!(common::vec_eq(
&vec![
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
2.0268754959106445,
-1.129373550415039,
-1.0500013828277588,
2.191876173019409,
1.8362512588500977,
1.141249656677246,
-1.5718750953674316,
1.324373483657837,
-0.6518747806549072,
-2.9000003337860107,
-1.6800007820129395,
-3.5431268215179443,
-1.048123836517334,
-2.2387490272521973,
-1.2106242179870605,
-0.8056254386901855,
-1.0631237030029297,
-2.404374599456787,
-0.057187557220458984,
],
&result
));
}
#[test]
fn test_zigzag_short() {
let mut stats = common::test_data();
let result = trend::zigzag(&stats.close, &stats.close, Some(3.0)).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
let expected = vec![
46.0,
f64::NAN,
65.11000061035156,
f64::NAN,
f64::NAN,
45.970001220703125,
50.45000076293945,
f64::NAN,
45.779998779296875,
47.560001373291016,
f64::NAN,
f64::NAN,
42.09000015258789,
44.529998779296875,
f64::NAN,
f64::NAN,
f64::NAN,
39.16999816894531,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
46.279998779296875,
44.439998626708984,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
51.400001525878906,
49.29499816894531,
];
assert!(common::vec_eq(&expected, &result));
stats.close[1] = 45.79999923706055;
let result = trend::zigzag(&stats.close, &stats.close, Some(3.0)).collect::<Vec<f64>>();
assert!(common::vec_eq(&expected, &result));
}
#[test]
fn test_zigzag_long() {
let stats = common::test_data();
let result = trend::zigzag(&stats.close, &stats.close, Some(15.0)).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
let expected = vec![
46.0,
f64::NAN,
65.11000061035156,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
39.16999816894531,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
49.29499816894531,
];
assert!(common::vec_eq(&expected, &result));
}
#[test]
fn test_chandelier() {
let stats = common::test_data();
let result =
trend::chandelier(&stats.high, &stats.low, &stats.close, 16, None).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
(57.04718828201294, 57.172812938690186,),
(57.70548936724663, 55.89451292157173,),
(46.74389268644154, 54.366104109212756,),
(38.661149517516606, 53.988848193665035,),
(35.36482660455658, 53.335170343685604,),
(35.94427432569819, 52.755722622544,),
(36.512135203489635, 52.077864949098256,),
(34.941374912680104, 51.58862386661677,),
(35.12835139671425, 51.401647382582624,),
(35.359704310441955, 51.17029446885492,),
(35.43503615888296, 50.79496338335337,),
(35.66409606516676, 50.56590347706957,),
(36.514276739026585, 50.47472167405936,),
(36.8733221106841, 50.11567630240184,),
(37.29655105370225, 49.92344635230361,),
(37.99301938803812, 49.68698091713766,),
(42.514079121796605, 49.9959191997366,),
(42.71382388104528, 49.796174440487924,),
],
result[16..]
);
}
#[test]
fn test_aroon() {
let stats = common::test_data();
let result = trend::aroon(&stats.high, &stats.low, 16).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
(12.5, 100.0),
(6.25, 100.0),
(0.0, 100.0),
(0.0, 93.75),
(0.0, 87.5),
(6.25, 81.25),
(0.0, 75.0),
(0.0, 68.75),
(12.5, 62.5),
(6.25, 56.25),
(0.0, 50.0),
(87.5, 43.75),
(100.0, 37.5),
(93.75, 31.25),
(100.0, 25.0),
(100.0, 18.75),
(100.0, 12.5),
(93.75, 6.25)
],
result[16..]
);
}
#[test]
fn test_decay() {
let stats = common::test_data();
let result = trend::decay(&stats.close, 6).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
46.0,
59.79999923706055,
65.11000061035156,
64.94333394368489,
64.77666727701822,
64.61000061035155,
64.44333394368488,
64.2766672770182,
64.11000061035153,
63.94333394368487,
63.776667277018205,
63.61000061035154,
63.44333394368488,
63.27666727701821,
63.11000061035155,
62.943333943684884,
62.77666727701822,
62.610000610351555,
62.44333394368489,
62.27666727701823,
62.11000061035156,
61.9433339436849,
61.776667277018234,
61.61000061035157,
61.443333943684905,
61.27666727701824,
61.11000061035158,
60.94333394368491,
60.77666727701825,
60.610000610351584,
60.44333394368492,
60.276667277018255,
60.11000061035159,
59.94333394368493,
],
result
);
}
#[test]
fn test_cks() {
let stats = common::test_data();
let result = trend::cks(&stats.high, &stats.low, &stats.close, 10, 6, None).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
(67.6907509613037, 45.472941443092346,),
(67.6907509613037, 44.81564668843155,),
(56.94367293548584, 43.89008291985695,),
(48.73130637435913, 42.49907267474625,),
(45.744354684859466, 42.35016562089468,),
(45.744354684859466, 42.05614904354642,),
(45.744354684859466, 41.80933426431385,),
(44.1798331584022, 41.51540073107094,),
(44.1798331584022, 41.32886081055174,),
(44.1798331584022, 41.30587463184031,),
(44.97471244987399, 41.25528709236234,),
(45.10474135747448, 41.12525818476185,),
(45.15626711491551, 41.07373242732082,),
(45.89573950925893, 41.07373242732082,),
(46.02406564378225, 41.07373242732082,),
(46.293558111996795, 41.07373242732082,),
(46.81820506263794, 41.07373242732082,),
(51.42338292368371, 41.07373242732082,),
(51.48204446346866, 43.91325859865124,),
],
result[10 + 6 - 1..]
);
}
#[test]
fn test_atr_stop() {
let stats = common::test_data();
let result =
trend::atr_stop(&stats.high, &stats.low, &stats.close, 3, Some(1.0)).collect::<Vec<_>>();
assert_eq!(stats.close.len(), result.len());
assert_eq!(
vec![
44.23999913533529,
44.23999913533529,
44.23999913533529,
44.23999913533529,
44.23999913533529,
44.23999913533529,
44.23999913533529,
44.23999913533529,
44.23999913533529,
45.928997064085365,
45.928997064085365,
45.73066542963256,
43.17044336544188,
43.17044336544188,
42.0190835835612,
42.0190835835612,
42.0190835835612,
38.98767765533553,
40.03911659566314,
40.789412640516964,
40.789412640516964,
42.62007105040772,
43.25671235513835,
43.25671235513835,
43.25671235513835,
44.38750850945975,
44.38750850945975,
45.17444870114444,
46.35963358640749,
47.45309012572023,
47.45309012572023,
],
result[3..]
);
}
#[test]
fn test_alligator() {
let stats = common::test_data();
let result: (Vec<f64>, Vec<f64>, Vec<f64>) =
multiunzip(trend::alligator(&stats.close, 6, 4, 4, 3, 3, 2));
assert_eq!(stats.close.len() + 4, result.0.len());
assert_eq!(
vec![
53.99166679382324,
53.40138912200928,
52.33282454808553,
51.24068691995409,
50.62723932884358,
49.881033028349464,
49.067527523624555,
47.90460629511845,
47.34217170914818,
46.49680983391743,
45.41400819493119,
44.70167339405074,
43.77972752319983,
43.43643980611705,
43.01036668311675,
42.84863905518518,
42.843865828458355,
42.89488844469511,
42.820740497735834,
43.25561713230916,
43.759680740140446,
43.87306705456854,
44.20755605682632,
44.78963017451184,
45.09802504370128,
45.62668761271167,
46.25557326490621,
47.112977975068326,
47.47664800738116,
],
result.0[6 - 1 + 4..&result.0.len() - 4 + 4]
);
assert_eq!(
vec![
57.16499996185303,
55.203749895095825,
52.89531272649765,
52.2839847356081,
50.960488971322775,
49.6653664233163,
49.13902516080998,
48.39176925207721,
47.54382693905791,
46.180370242440404,
45.76777737665452,
44.89333314693181,
43.66999986019886,
43.03749974256125,
42.07062434915727,
41.982968567043734,
41.70722669231161,
41.79042024811554,
42.04781510979271,
42.32336171381426,
42.35502147609556,
43.12376618336562,
43.912824332348436,
44.04461790593857,
44.50346369648274,
45.302597963096915,
45.6369483197348,
46.295211354242014,
47.07140889715124,
48.153557054333156,
48.43891733298619,
],
result.1[4 - 1 + 3..&result.1.len() - 4 + 3]
);
assert_eq!(
vec![
56.96999994913737,
57.229999966091576,
54.59333320900246,
51.718889212902674,
51.29592639624826,
49.860618156987776,
48.50041169775748,
48.186941589601986,
47.50796156836096,
46.671974378907315,
45.14464963680084,
44.93976601763285,
44.04984416434312,
42.699896109562076,
42.17993053625753,
41.17661974715346,
41.357746905003346,
41.198498292707306,
41.47899916698065,
41.925999342928506,
42.33400007057864,
42.37266696803224,
43.39177808041342,
44.35451831337457,
44.38301175115271,
44.88200819014022,
45.82133904773997,
46.094225828376125,
46.81948403817197,
47.679656534074276,
48.919771531342484,
49.0448470772101,
],
result.2[3 - 1 + 2..&result.0.len() - 4 + 2]
);
}
#[test]
fn test_ichimoku() {
let (c_win, b_win, lead_win, lag_win) = (3, 7, 13, 7);
let stats = common::test_data();
let result: (Vec<f64>, Vec<f64>, Vec<f64>, Vec<f64>, Vec<f64>) = multiunzip(trend::ichimoku(
&stats.high,
&stats.low,
&stats.close,
c_win,
b_win,
lead_win,
lag_win,
));
assert_eq!(stats.close.len() + b_win, result.0.len());
assert_eq!(
vec![
60.1200008392334,
60.4900016784668,
62.0,
54.07749938964844,
49.64999961853027,
47.67499923706055,
47.67499923706055,
47.96000099182129,
46.93000030517578,
46.93000030517578,
45.45000076293945,
44.60500144958496,
44.03499984741211,
43.01499938964844,
41.59000015258789,
40.420000076293945,
39.744998931884766,
40.59000015258789,
40.59000015258789,
42.114999771118164,
42.28499984741211,
42.454999923706055,
43.52449989318848,
44.864999771118164,
45.76500129699707,
46.51500129699707,
46.894500732421875,
47.11949920654297,
47.795000076293945,
48.28500175476074,
50.954999923706055,
51.28000068664551,
],
result.0[c_win - 1..result.0.len() - b_win]
);
assert_eq!(
vec![
59.45000076293945,
59.45000076293945,
59.45000076293945,
53.8799991607666,
49.64999961853027,
47.67499923706055,
46.53499984741211,
46.48000144958496,
45.45000076293945,
44.43000030517578,
44.25,
43.095001220703125,
41.849998474121094,
41.849998474121094,
40.60499954223633,
40.704999923706055,
40.704999923706055,
40.704999923706055,
41.77449989318848,
44.52499961853027,
44.69499969482422,
44.864999771118164,
45.24449920654297,
45.24449920654297,
46.260000228881836,
47.2400016784668,
49.65500068664551,
49.8799991607666,
],
result.1[c_win.max(b_win) - 1..result.0.len() - b_win]
);
assert_eq!(
vec![
54.55000019073486,
53.5625,
53.5625,
50.920000076293945,
48.28999996185303,
47.302499771118164,
45.99250030517578,
45.54250144958496,
44.74250030517578,
43.72249984741211,
42.920000076293945,
41.757500648498535,
40.79749870300293,
41.21999931335449,
40.59749984741211,
41.40999984741211,
41.49499988555908,
41.579999923706055,
42.64949989318848,
44.69499969482422,
45.230000495910645,
45.69000053405762,
46.06949996948242,
46.18199920654297,
47.02750015258789,
47.76250171661377,
50.30500030517578,
50.579999923706055,
],
result.2[b_win - 1 + b_win..]
);
assert_eq!(
vec![
58.310001373291016,
58.310001373291016,
58.310001373291016,
51.71999931335449,
47.30999946594238,
45.02499961853027,
44.349998474121094,
44.295000076293945,
43.26499938964844,
43.26499938964844,
43.26499938964844,
42.420000076293945,
41.849998474121094,
43.114999771118164,
43.114999771118164,
43.114999771118164,
43.49449920654297,
43.49449920654297,
43.60999870300293,
45.25,
47.834999084472656,
48.0049991607666,
],
result.3[lead_win - 1 + b_win..]
);
assert_eq!(
vec![
46.9900016784668,
45.779998779296875,
47.560001373291016,
46.150001525878906,
45.0,
42.09000015258789,
44.529998779296875,
42.27000045776367,
40.0,
41.13999938964844,
39.16999816894531,
41.720001220703125,
40.880001068115234,
42.040000915527344,
42.81999969482422,
43.150001525878906,
42.45000076293945,
45.43000030517578,
46.279998779296875,
44.439998626708984,
45.880001068115234,
47.70000076293945,
46.63999938964844,
48.27000045776367,
49.400001525878906,
51.400001525878906,
49.29499816894531,
],
result.4[..result.0.len() - b_win - lag_win]
);
}
#[test]
fn test_hurst() {
let stats = common::test_data();
let rets = stats
.close
.windows(2)
.map(|w| w[1] / w[0] - 1.0)
.collect::<Vec<_>>();
let result = trend::hurst(&rets, 16, None).collect::<Vec<_>>();
assert_eq!(rets.len(), result.len());
assert!(common::vec_close(
&[
0.717300003513944,
0.7040433063878732,
0.7870815790649716,
0.5852648888827561,
0.4372401978043943,
0.6284984091135501,
0.5407697086351437,
0.5950129675824667,
0.8070520438846511,
0.7513875353620354,
0.7370004550770194,
0.6775389374178914,
0.7450996515301547,
0.773309179173034,
0.5946959711202044,
0.23772640082555682,
0.20834665213422418,
0.10884312104017504
],
&result[16 - 1..]
));
}