use itertools::multiunzip; use traquer::trend; mod common; #[test] fn test_adx() { let stats = common::test_data(); let result: (Vec, Vec, Vec) = 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::>(); assert_eq!(stats.close.len(), results.len()); assert_eq!( vec![ //(f64::NAN, 130.9311144714237), (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, Vec) = 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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::>(); 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, Vec, Vec) = 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, Vec, Vec, Vec, Vec) = 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::>(); let result = trend::hurst(&rets, 16, None).collect::>(); assert_eq!(rets.len(), result.len()); assert!(common::vec_close( &vec![ 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..] )); }