diff --git a/Cargo.lock b/Cargo.lock index d45f681..56f3f21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -30,13 +30,14 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -77,13 +78,13 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -124,9 +125,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -142,9 +143,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "bitvec" @@ -169,47 +170,26 @@ dependencies = [ [[package]] name = "borsh" -version = "0.10.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +checksum = "bf617fabf5cdbdc92f774bfe5062d870f228b80056d41180797abf48bed4056e" dependencies = [ "borsh-derive", - "hashbrown 0.13.2", + "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "0.10.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +checksum = "f404657a7ea7b5249e36808dff544bc88a28f26e0ac40009f674b7a009d14be3" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "once_cell", "proc-macro-crate", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "syn 2.0.39", + "syn_derive", ] [[package]] @@ -240,12 +220,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "bytemuck" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" - [[package]] name = "byteorder" version = "1.5.0" @@ -273,6 +247,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.31" @@ -288,27 +268,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - -[[package]] -name = "const-cstr" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" - [[package]] name = "const-oid" version = "0.7.1" @@ -331,47 +290,11 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "libc", -] - -[[package]] -name = "core-text" -version = "19.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" -dependencies = [ - "core-foundation", - "core-graphics", - "foreign-types", - "libc", -] - [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -387,18 +310,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crossbeam-queue" @@ -481,27 +395,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "displaydoc" version = "0.2.4" @@ -510,16 +403,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading", + "syn 2.0.39", ] [[package]] @@ -528,18 +412,6 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" -[[package]] -name = "dwrote" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" -dependencies = [ - "lazy_static", - "libc", - "winapi", - "wio", -] - [[package]] name = "either" version = "1.9.0" @@ -563,9 +435,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" dependencies = [ "libc", "windows-sys", @@ -583,68 +455,18 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" -[[package]] -name = "fdeflate" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" -dependencies = [ - "simd-adler32", -] - [[package]] name = "finl_unicode" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" -[[package]] -name = "flate2" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "float-ord" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "font-kit" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21fe28504d371085fae9ac7a3450f0b289ab71e07c8e57baa3fb68b9e57d6ce5" -dependencies = [ - "bitflags 1.3.2", - "byteorder", - "core-foundation", - "core-graphics", - "core-text", - "dirs-next", - "dwrote", - "float-ord", - "freetype", - "lazy_static", - "libc", - "log", - "pathfinder_geometry", - "pathfinder_simd", - "walkdir", - "winapi", - "yeslogic-fontconfig-sys", -] - [[package]] name = "foreign-types" version = "0.3.2" @@ -669,27 +491,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "freetype" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" -dependencies = [ - "freetype-sys", - "libc", -] - -[[package]] -name = "freetype-sys" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" -dependencies = [ - "cmake", - "libc", - "pkg-config", -] - [[package]] name = "funty" version = "2.0.0" @@ -698,9 +499,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -713,9 +514,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -723,15 +524,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -751,38 +552,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -808,25 +609,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", "wasi", ] -[[package]] -name = "gif" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" -dependencies = [ - "color_quant", - "weezl", -] - [[package]] name = "gimli" version = "0.28.0" @@ -835,9 +626,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -845,7 +636,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -858,25 +649,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", ] [[package]] name = "hashbrown" -version = "0.13.2" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ - "ahash 0.8.3", -] - -[[package]] -name = "hashbrown" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" -dependencies = [ - "ahash 0.8.3", + "ahash 0.8.6", "allocator-api2", ] @@ -886,7 +668,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.1", + "hashbrown 0.14.2", ] [[package]] @@ -918,9 +700,9 @@ checksum = "bcdc571e566521512579aab40bf807c5066e1765fb36857f16ed7595c13567c6" [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -967,7 +749,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -989,16 +771,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1020,21 +802,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "image" -version = "0.24.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "jpeg-decoder", - "num-rational", - "num-traits", - "png", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -1047,12 +814,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.2", ] [[package]] @@ -1066,9 +833,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itertools" @@ -1085,17 +852,11 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "jpeg-decoder" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" - [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -1111,19 +872,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" - -[[package]] -name = "libloading" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" -dependencies = [ - "cfg-if", - "windows-sys", -] +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libm" @@ -1133,15 +884,15 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1178,14 +929,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", - "simd-adler32", ] [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", @@ -1269,17 +1019,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.17" @@ -1317,11 +1056,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -1338,7 +1077,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1349,9 +1088,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" dependencies = [ "cc", "libc", @@ -1383,7 +1122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", + "parking_lot_core 0.9.9", ] [[package]] @@ -1402,13 +1141,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "smallvec", "windows-targets", ] @@ -1419,25 +1158,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "pathfinder_geometry" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" -dependencies = [ - "log", - "pathfinder_simd", -] - -[[package]] -name = "pathfinder_simd" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0444332826c70dc47be74a7c6a5fc44e23a7905ad6858d4162b658320455ef93" -dependencies = [ - "rustc_version", -] - [[package]] name = "pem-rfc7468" version = "0.3.1" @@ -1493,65 +1213,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "chrono", - "font-kit", - "image", - "lazy_static", - "num-traits", - "pathfinder_geometry", - "plotters-backend", - "plotters-bitmap", - "plotters-svg", - "ttf-parser", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-bitmap" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cebbe1f70205299abc69e8b295035bb52a6a70ee35474ad10011f0a4efb8543" -dependencies = [ - "gif", - "image", - "plotters-backend", -] - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "png" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1560,11 +1221,34 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "0.1.5" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", ] [[package]] @@ -1652,29 +1336,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall 0.2.16", - "thiserror", -] - [[package]] name = "regex" -version = "1.10.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -1684,9 +1357,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -1695,9 +1368,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d84fdd47036b038fc80dd333d10b6aab10d5d31f4a366e20014def75328d33" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rend" @@ -1714,7 +1387,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -1796,9 +1469,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.32.0" +version = "1.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" +checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" dependencies = [ "arrayvec", "borsh", @@ -1812,9 +1485,9 @@ dependencies = [ [[package]] name = "rust_decimal_macros" -version = "1.32.0" +version = "1.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86444b802de0b10ac5e563b5ddb43b541b9705de4e01a50e82194d2b183c1835" +checksum = "2e43721f4ef7060ebc2c3ede757733209564ca8207f47674181bcd425dd76945" dependencies = [ "quote", "rust_decimal", @@ -1826,22 +1499,13 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustix" -version = "0.38.18" +version = "0.38.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" +checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", @@ -1854,15 +1518,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "schannel" version = "0.1.22" @@ -1907,39 +1562,33 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" - [[package]] name = "serde" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "itoa", "ryu", "serde", @@ -1947,13 +1596,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1999,12 +1648,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "simdutf8" version = "0.1.4" @@ -2022,15 +1665,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -2038,9 +1681,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys", @@ -2089,7 +1732,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", "atoi", "bitflags 1.3.2", "byteorder", @@ -2201,15 +1844,27 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -2239,13 +1894,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix", "windows-sys", ] @@ -2275,22 +1930,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2310,9 +1965,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "bytes", @@ -2322,20 +1977,20 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", "windows-sys", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2361,9 +2016,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -2374,12 +2029,20 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.5.11" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "serde", + "indexmap 2.1.0", + "toml_datetime", + "winnow", ] [[package]] @@ -2390,20 +2053,19 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -2418,7 +2080,6 @@ dependencies = [ "hex", "hmac-sha256", "ord_subset", - "plotters", "rand", "reqwest", "rust_decimal", @@ -2436,12 +2097,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "ttf-parser" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff" - [[package]] name = "typenum" version = "1.17.0" @@ -2500,9 +2155,9 @@ checksum = "110352d4e9076c67839003c7788d8604e24dcded13e0b375af3efaa8cf468517" [[package]] name = "uuid" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" [[package]] name = "vcpkg" @@ -2516,16 +2171,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -2543,9 +2188,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2553,24 +2198,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if", "js-sys", @@ -2580,9 +2225,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2590,39 +2235,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "weezl" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" - [[package]] name = "winapi" version = "0.3.9" @@ -2639,15 +2278,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2655,10 +2285,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ "windows-targets", ] @@ -2729,6 +2359,15 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -2739,15 +2378,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "wio" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" -dependencies = [ - "winapi", -] - [[package]] name = "wyz" version = "0.5.1" @@ -2758,19 +2388,27 @@ dependencies = [ ] [[package]] -name = "yeslogic-fontconfig-sys" -version = "3.2.0" +name = "zerocopy" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" dependencies = [ - "const-cstr", - "dlib", - "once_cell", - "pkg-config", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index d71132e..67da6a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,4 +24,3 @@ thirtyfour = { version = "0.28.1", features = ["tokio-runtime"]} ord_subset = "3.1.1" rust_decimal = "1.29.1" rust_decimal_macros = "1.29.1" -plotters = "0.3.1" diff --git a/src/coex/exchange_team.rs b/src/coex/exchange_team.rs index f9c1a16..6242c84 100644 --- a/src/coex/exchange_team.rs +++ b/src/coex/exchange_team.rs @@ -1,6 +1,6 @@ use crate::coex::assets_managing_team::*; use crate::coex::order_team::*; -use crate::coex::strategy_team::AllData; +use crate::strategy_team::AllData; use crate::coin_health_check_team::request_others::{CoinPriceData, ExchangeInfo, TradeFee}; use crate::database_control::*; use crate::decimal_funcs::{decimal, decimal_add, decimal_div, decimal_mul, decimal_sub}; diff --git a/src/coex.rs b/src/coex/mod.rs similarity index 76% rename from src/coex.rs rename to src/coex/mod.rs index 9a9b0a1..b507f0e 100644 --- a/src/coex.rs +++ b/src/coex/mod.rs @@ -1,4 +1,3 @@ pub mod assets_managing_team; pub mod exchange_team; pub mod order_team; -pub mod strategy_team; diff --git a/src/coex/order_team.rs b/src/coex/order_team.rs index 52e057b..a6b4854 100644 --- a/src/coex/order_team.rs +++ b/src/coex/order_team.rs @@ -11,8 +11,7 @@ use crate::URL_TEST; // use crates use crate::coex::assets_managing_team::*; use crate::coex::exchange_team::*; -use crate::coex::strategy_team::AllData; -use crate::coex::strategy_team::TimeData; +use crate::strategy_team::{AllData, TimeData}; use crate::coin_health_check_team::request_others::{CoinPriceData, ExchangeInfo, TradeFee}; use crate::database_control::*; use crate::decimal_funcs::*; diff --git a/src/coex/strategy_team.rs b/src/coex/strategy_team.rs deleted file mode 100644 index d270ae2..0000000 --- a/src/coex/strategy_team.rs +++ /dev/null @@ -1,7727 +0,0 @@ -use crate::coex::exchange_team::*; -use crate::coex::order_team::*; -use crate::coin_health_check_team::request_others::CoinPriceData; -use crate::database_control::*; -use crate::value_estimation_team; -use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; -use crate::value_estimation_team::indicators::bollingerband::{bollingerband, BollingerBandData}; -use crate::value_estimation_team::indicators::ema::{ema, EmaData}; -use crate::value_estimation_team::indicators::heatmap_volume::{ - heatmap_volume, HeatMapLevel, HeatmapVolumeData, -}; -use crate::value_estimation_team::indicators::macd::{ema_macd, EmaMacd}; -use crate::value_estimation_team::indicators::rsi::{rsi, RsiData}; -use crate::value_estimation_team::indicators::sma::{sma, SmaData}; -use crate::value_estimation_team::indicators::stoch_rsi::{stoch_rsi, StochRsiData}; -use crate::value_estimation_team::indicators::supertrend::{supertrend, SupertrendData}; -use csv::{DeserializeRecordsIter, StringRecord}; -use futures::future::try_join_all; -use rust_decimal::prelude::ToPrimitive; -use rust_decimal::Decimal; -use serde::Deserialize; -use sqlx::FromRow; -use std::{cmp::Ordering, sync::Arc}; -use tokio::sync::Mutex; -use tokio::time::{sleep, Duration, Instant}; - -use crate::signal_association::signal_decision::*; - -#[derive(PartialEq)] -pub enum MA { - Sma, - Ema, - Tema, -} - -#[derive(Debug)] -pub struct AllData { - pub valid_symbol_vec: Vec, - pub rt_price_1m_vec: Vec<(String, Vec)>, - pub rt_price_30m_vec: Vec<(String, Vec)>, - pub rt_price_1d_vec: Vec<(String, Vec)>, - pub rt_price_1w_vec: Vec<(String, Vec)>, - pub rt_price_1mon_vec: Vec<(String, Vec)>, -} -impl AllData { - pub fn new() -> AllData { - let a = AllData { - valid_symbol_vec: Vec::new(), - rt_price_1m_vec: Vec::new(), - rt_price_30m_vec: Vec::new(), - rt_price_1d_vec: Vec::new(), - rt_price_1w_vec: Vec::new(), - rt_price_1mon_vec: Vec::new(), - }; - a - } -} - -#[derive(Debug, Deserialize, Clone)] -struct OpcloData { - price: f64, - server_epoch: u64, - usdt_volume: f64, - up_down: String, -} - -#[derive(Debug, Deserialize, Clone)] -struct PriceData { - opclo_price: f64, - open_price: f64, - close_price: f64, - high_price: f64, - low_price: f64, - close_time: u64, - quote_asset_volume: f64, - candle_type: String, -} - -#[derive(Debug, FromRow)] -pub struct TimeData { - pub server_epoch: u64, - pub local_epoch: u64, - pub epoch_difference: i64, - pub server_ymdhs: String, - pub local_ymdhs: String, - pub last_server_epoch: u64, - pub last_server_ymdhs: String, -} - -#[derive(Debug, FromRow)] -struct ServerEpoch { - server_epoch: u64, -} - -#[derive(Debug, FromRow)] -struct Record { - symbol: String, - suggested_price: Decimal, - close_time: u64, - registered_server_epoch: u64, - registerer: u16, - is_long: u8, -} - -pub async fn execute_strategists( - all_data: &AllData, -) -> Result<(), Box> { - strategist_001(all_data).await?; - strategist_002(all_data).await?; - strategist_003(all_data).await?; - strategist_004(all_data).await?; - strategist_005(all_data).await?; - strategist_006(all_data).await?; - - Ok(()) -} - -pub async fn strategist_001( - alldata: &AllData, -) -> Result<(), Box> { - // print rt_price for debugging - // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); - // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); - - // // 1st filtering: supertrend(ATR period 10, multiplier: 1.3, 30m close price), the area should be in SELL area. - // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - // let mut filtered_2nd_symbols_arc: Arc>> = - // Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - // let mut task_vec = Vec::new(); - // let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - // for symbol in valid_symbol_vec_c { - // let mut opclo_30m_vec: Vec = Vec::new(); - // let mut supertrend_vec: Vec = Vec::new(); - // let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - // let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - // task_vec.push(tokio::spawn(async move { - // let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - // let supertrend_option_30m = - // supertrend(&symbol, &rt_price_30m_vec_c, 10, 1.3, true).await; - - // if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { - // opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - // supertrend_vec = supertrend_option_30m.unwrap(); - - // if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { - // let supertrend_search_result = supertrend_vec.binary_search_by_key( - // &opclo_30m_vec.last().unwrap().close_time, - // |SupertrendData { - // band_value, - // signal, - // area, - // close_time, - // }| *close_time, - // ); - // if supertrend_search_result.is_ok() { - // if supertrend_vec[supertrend_search_result.unwrap()] - // .area - // .contains("DOWN") - // { - // let mut filtered_2nd_symbols_lock = - // filtered_2nd_symbols_arc_c.lock().await; - // filtered_2nd_symbols_lock - // .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - // } - // } - // } - // } - // })); - // } - // try_join_all(task_vec).await?; - - // 1st filtering: making basic form - let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_2nd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - for symbol in valid_symbol_vec_c { - let mut opclo_30m_vec: Vec = Vec::new(); - - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - - if opclo_30m_option.is_some() { - opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let mut filtered_2nd_symbols_lock = - filtered_2nd_symbols_arc_c.lock().await; - filtered_2nd_symbols_lock - .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - } - } - })); - } - try_join_all(task_vec).await?; - - // 2nd filtering: lookup tables if the tradepair is already there - let inspect_table_name_1 = String::from("buy_ordered_coin_list"); - let inspect_table_name_2 = String::from("sell_ordered_coin_list"); - let inspect_table_name_3 = String::from("pre_suggested_coin_list"); - let inspect_table_name_4 = String::from("suggested_coin_list"); - - let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_3rd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - - let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); - for element in filtered_2nd_iter { - let mut exists_condition_build = String::from("symbol=\'"); - exists_condition_build.push_str(element.0.as_str()); - exists_condition_build.push_str("\' AND registerer="); - exists_condition_build.push_str(1.to_string().as_str()); - // exists_condition_build.push_str("\' AND close_time="); - // exists_condition_build.push_str(element.1.to_string().as_str()); - let exists_condition = Some(exists_condition_build); - let exists_condition_c = exists_condition.clone(); - let inspect_table_name_1_c = inspect_table_name_1.clone(); - let inspect_table_name_2_c = inspect_table_name_2.clone(); - let inspect_table_name_3_c = inspect_table_name_3.clone(); - let inspect_table_name_4_c = inspect_table_name_4.clone(); - let element_c = element.clone(); - let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let inspect_result_1 = - exists_record(&inspect_table_name_1_c, &exists_condition_c).await; - let inspect_result_2 = - exists_record(&inspect_table_name_2_c, &exists_condition_c).await; - let inspect_result_3 = - exists_record(&inspect_table_name_3_c, &exists_condition_c).await; - let inspect_result_4 = - exists_record(&inspect_table_name_4_c, &exists_condition_c).await; - - if inspect_result_1 == false - && inspect_result_2 == false - && inspect_result_3 == false - && inspect_result_4 == false - { - let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; - filtered_3rd_symbols_lock.push(element_c); - } - })); - } - try_join_all(task_vec).await?; - - // 3rd filtering: BollingerBand (length 10, stddev: 2.5, 30m close price) the current price should be under the lowerband of BB. - let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); - let sma10_30m_data: Vec<(String, Vec)> = sma( - 10, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - - let bb10_30m_data: Vec<(String, Vec)> = - bollingerband( - 10, - 3.0, - &sma10_30m_data, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - - let mut task_vec = Vec::new(); - let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_4th_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) - for element in filtered_3rd_symbols_c { - let mut bb10_30m_vec: Vec = Vec::new(); - let bb10_30m_option = bb10_30m_data.iter().position(|x| *x.0 == element.0); - let bb10_30m_option_c = bb10_30m_option.clone(); - let element_c = element.clone(); - let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); - - if bb10_30m_option_c.is_some() { - bb10_30m_vec = bb10_30m_data[bb10_30m_option_c.unwrap()].1.clone(); - - if bb10_30m_vec.len() >= 3 { - let bb10_30m_vec_c = bb10_30m_vec.clone(); - let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec) - .await - .unwrap(); - task_vec.push(tokio::spawn(async move { - let bb_search_result = bb10_30m_vec_c.binary_search_by_key( - &element_c.1, - |&BollingerBandData { - sma, - upperband, - lowerband, - close_time, - }| close_time, - ); - if bb_search_result.is_ok() { - if bb10_30m_vec_c[bb_search_result.unwrap()].lowerband > current_price { - let mut filtered_4th_symbols_lock = - filtered_4th_symbols_arc_c.lock().await; - filtered_4th_symbols_lock.push(element_c); - } - } - })); - } - } - } - try_join_all(task_vec).await?; - - // 4th filtering: the current price should be lower than lowest price from the latest 20 candles. - let mut task_vec = Vec::new(); - let filtered_4th_symbols_c = filtered_4th_symbols_arc.lock().await.clone(); - let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_5th_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_5th_symbols)); // (symbol, closetime) - for element in filtered_4th_symbols_c { - let rt_price_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == element.0); - let element_c = element.clone(); - let filtered_5th_symbols_arc_c = Arc::clone(&filtered_5th_symbols_arc); - - if rt_price_30m_option.is_some() { - let mut rt_price_30m_vec_c = alldata.rt_price_30m_vec[rt_price_30m_option.unwrap()].1.clone(); - let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec) - .await - .unwrap(); - - task_vec.push(tokio::spawn(async move { - if rt_price_30m_vec_c.len() >= 21 { - rt_price_30m_vec_c.pop(); - rt_price_30m_vec_c.reverse(); - rt_price_30m_vec_c.truncate(20); - - let lowest_price_option = rt_price_30m_vec_c.iter() - .enumerate() - .min_by(|(_, a), (_, b)| { - a.low_price - .partial_cmp(&b.low_price) - .expect("Nan was forbidden.") - }) - .map(|(index, _)| index); - - if lowest_price_option.is_some() { - let lowest_price = rt_price_30m_vec_c[lowest_price_option.unwrap()].low_price; - if lowest_price > current_price { - let mut filtered_5th_symbols_lock = - filtered_5th_symbols_arc_c.lock().await; - filtered_5th_symbols_lock.push(element_c); - } - } - } - })); - } - } - try_join_all(task_vec).await?; - - // 5th filtering: RSI (length: 10, 30m close price) the current index should be lower than 30. - let filtered_5th_symbol_c = filtered_5th_symbols_arc.lock().await.clone(); - let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( - 10, - &alldata.rt_price_30m_vec, - &filtered_5th_symbol_c, - ) - .await?; - let mut task_vec = Vec::new(); - let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - let mut filtered_6th_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_6th_symbols)); // (symbol, closetime) - - for element in filtered_5th_symbol_c { - let rsi10_30m_option = rsi10_30m_data.iter().position(|x| *x.0 == element.0); - let filtered_6th_symbols_arc_c = Arc::clone(&filtered_6th_symbols_arc); - - if rsi10_30m_option.is_some() { - let mut rsi10_30m_vec = rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); - - if rsi10_30m_vec.len() >= 3 { - let element_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let rsi_search_result = rsi10_30m_vec.binary_search_by_key( - &element.1, - |&RsiData { - rsi_value, - close_time, - }| close_time, - ); - if rsi_search_result.is_ok() { - if rsi10_30m_vec[rsi_search_result.unwrap()].rsi_value <= 20.0 { - let mut filtered_6th_symbols_lock = - filtered_6th_symbols_arc_c.lock().await; - filtered_6th_symbols_lock.push(element_c); - - } - } - })); - } - } - } - try_join_all(task_vec).await?; - - // 6th filtering: StochRSI (RSI length: 14, Stoch length: 14, smooth k: 3, smooth d: 3) smooth kn <= 10, kn-1 <= 25.0 - let filtered_6th_symbol_c = filtered_6th_symbols_arc.lock().await.clone(); - let mut rsi14_30m_data: Vec<(String, Vec)> = rsi( - 14, - &alldata.rt_price_30m_vec, - &filtered_6th_symbol_c, - ) - .await?; - let stoch_rsi_data = stoch_rsi(&rsi14_30m_data, 14, 3, 3).await?; - let mut stoch_rsi14_30m_vec: Vec = Vec::new(); - let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_6th_symbol_c { - let stoch_rsi14_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); - - if stoch_rsi14_30m_option.is_some() { - stoch_rsi14_30m_vec = stoch_rsi_data[stoch_rsi14_30m_option.unwrap()].1.clone(); - - if stoch_rsi14_30m_vec.len() >= 3 { - let stoch_rsi_search_result = stoch_rsi14_30m_vec.binary_search_by_key( - &element.1, - |&StochRsiData { - k, - d, - close_time, - }| close_time, - ); - if stoch_rsi_search_result.is_ok() { - if stoch_rsi14_30m_vec[stoch_rsi_search_result.unwrap()].k <= 10.0 && stoch_rsi14_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= 25.0 { - filtered_7th_symbols.push(element); - } - } - } - } - } - - // 7th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least. - let mut filtered_8th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_7th_symbols { - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let heatmap_volume_option = - heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) - .await; - if heatmap_volume_option.is_some() { - let heatmap_volume_vec = heatmap_volume_option.unwrap(); - let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( - &element.1, - |HeatmapVolumeData { - heatmap_value, - heatmap_level, - close_time, - }| *close_time, - ); - if heatmap_search_result.is_ok() { - if heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::Medium - || - heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::High - || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::ExtraHigh - { - filtered_8th_symbols.push(element); - } - } - } - } - } - } - - // final job: adding price information to filtered results - let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) - let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); - let mut task_vec = Vec::new(); - for element in filtered_8th_symbols { - let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - - let elememt_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - if rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .is_some() - { - let mut filtered_symbols_lock: tokio::sync::MutexGuard< - '_, - Vec<(String, i64, f64)>, - > = filtered_symbols_arc_c.lock().await; - filtered_symbols_lock.push(( - elememt_c.0, - elememt_c.1, - rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .unwrap() - .close_price, - )); - } - } - })); - } - - try_join_all(task_vec).await?; - - // 6th filtering condition: MACD - // let mut opclo_30m_vec: Vec = Vec::new(); - // let mut ema3_1d_vec: &Vec = &Vec::new(); - // let mut ema10_1d_vec: &Vec = &Vec::new(); - - // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - // for element in filtered_6th_symbols { - // let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0); - // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0); - - // if ema3_1d_option.is_some() && ema10_1d_option.is_some() { - // ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1; - // ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1; - - // if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { - // let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; - // // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); - - // // if macd_search_result.is_ok() { - // if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 { - // filtered_7th_symbols.push(element); - // } - // // } - // } - // } - // } - let a = filtered_symbols_arc.lock().await.clone(); - insert_pre_suggested_coins(1, false, &a, alldata).await; - - Ok(()) -} - -pub async fn strategist_002( - alldata: &AllData, -) -> Result<(), Box> { - // print rt_price for debugging - // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); - // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); - - // 1st filtering: making basic form - let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_2nd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - for symbol in valid_symbol_vec_c { - let mut opclo_30m_vec: Vec = Vec::new(); - - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - - if opclo_30m_option.is_some() { - opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let mut filtered_2nd_symbols_lock = - filtered_2nd_symbols_arc_c.lock().await; - filtered_2nd_symbols_lock - .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - } - } - })); - } - try_join_all(task_vec).await?; - - // 2nd filtering: lookup tables if the tradepair is already there - let inspect_table_name_1 = String::from("buy_ordered_coin_list"); - let inspect_table_name_2 = String::from("sell_ordered_coin_list"); - let inspect_table_name_3 = String::from("pre_suggested_coin_list"); - let inspect_table_name_4 = String::from("suggested_coin_list"); - - let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_3rd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - - let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); - for element in filtered_2nd_iter { - let mut exists_condition_build = String::from("symbol=\'"); - exists_condition_build.push_str(element.0.as_str()); - exists_condition_build.push_str("\' AND registerer="); - exists_condition_build.push_str(2.to_string().as_str()); - // exists_condition_build.push_str("\' AND close_time="); - // exists_condition_build.push_str(element.1.to_string().as_str()); - - let exists_condition = Some(exists_condition_build); - let exists_condition_c = exists_condition.clone(); - let inspect_table_name_1_c = inspect_table_name_1.clone(); - let inspect_table_name_2_c = inspect_table_name_2.clone(); - let inspect_table_name_3_c = inspect_table_name_3.clone(); - let inspect_table_name_4_c = inspect_table_name_4.clone(); - let element_c = element.clone(); - let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let inspect_result_1 = - exists_record(&inspect_table_name_1_c, &exists_condition_c).await; - let inspect_result_2 = - exists_record(&inspect_table_name_2_c, &exists_condition_c).await; - let inspect_result_3 = - exists_record(&inspect_table_name_3_c, &exists_condition_c).await; - let inspect_result_4 = - exists_record(&inspect_table_name_4_c, &exists_condition_c).await; - - if inspect_result_1 == false - && inspect_result_2 == false - && inspect_result_3 == false - && inspect_result_4 == false - { - let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; - filtered_3rd_symbols_lock.push(element_c); - } - })); - } - try_join_all(task_vec).await?; - - // 3rd filtering: EMA30 > EMA 150 - let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); - let ema30_30m_data: Vec<(String, Vec)> = ema( - 30, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - let ema150_30m_data: Vec<(String, Vec)> = ema( - 150, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - - let mut task_vec = Vec::new(); - let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_4th_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) - for element in filtered_3rd_symbols_c { - let mut ema30_30m_vec: Vec = Vec::new(); - let mut ema150_30m_vec: Vec = Vec::new(); - let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0); - let ema30_30m_option_c = ema30_30m_option.clone(); - let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0); - let ema150_30m_option_c = ema150_30m_option.clone(); - let element_c = element.clone(); - let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); - - if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() { - ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone(); - ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone(); - - if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 { - let ema30_30m_vec_c = ema30_30m_vec.clone(); - let ema150_30m_vec_c = ema150_30m_vec.clone(); - - task_vec.push(tokio::spawn(async move { - let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( - &element_c.1, - |&EmaData { - ema_value, - close_time, - }| close_time, - ); - let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( - &element_c.1, - |&EmaData { - ema_value, - close_time, - }| close_time, - ); - - if ema30_search_result.is_ok() && ema150_search_result.is_ok() { - if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value - { - let mut filtered_4th_symbols_lock = - filtered_4th_symbols_arc_c.lock().await; - filtered_4th_symbols_lock.push(element_c); - } - } - })); - } - } - } - try_join_all(task_vec).await?; - - // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth dn == 0, kn == 0, kn-1 < 5 - let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone(); - let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( - 10, - &alldata.rt_price_30m_vec, - &filtered_4th_symbol_c, - ) - .await?; - let stoch_rsi_data = stoch_rsi(&rsi10_30m_data, 10, 3, 3).await?; - let mut stoch_rsi10_30m_vec: Vec = Vec::new(); - let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_4th_symbol_c { - let stoch_rsi10_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); - - if stoch_rsi10_30m_option.is_some() { - stoch_rsi10_30m_vec = stoch_rsi_data[stoch_rsi10_30m_option.unwrap()].1.clone(); - - if stoch_rsi10_30m_vec.len() >= 3 { - let stoch_rsi_search_result = stoch_rsi10_30m_vec.binary_search_by_key( - &element.1, - |&StochRsiData { - k, - d, - close_time, - }| close_time, - ); - if stoch_rsi_search_result.is_ok() { - if stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k <= 5.0 && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].d <= 5.0 && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= 5.0 { - filtered_5th_symbols.push(element); - } - } - } - } - } - - // 7th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least. - let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_5th_symbols { - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let heatmap_volume_option = - heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) - .await; - if heatmap_volume_option.is_some() { - let heatmap_volume_vec = heatmap_volume_option.unwrap(); - let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( - &element.1, - |HeatmapVolumeData { - heatmap_value, - heatmap_level, - close_time, - }| *close_time, - ); - if heatmap_search_result.is_ok() { - if - // heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - // == HeatMapLevel::Medium - // || - heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::High - || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::ExtraHigh - { - filtered_6th_symbols.push(element); - } - } - } - } - } - } - - // final job: adding price information to filtered results - let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) - let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); - let mut task_vec = Vec::new(); - for element in filtered_6th_symbols { - let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - - let elememt_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - if rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .is_some() - { - let mut filtered_symbols_lock: tokio::sync::MutexGuard< - '_, - Vec<(String, i64, f64)>, - > = filtered_symbols_arc_c.lock().await; - filtered_symbols_lock.push(( - elememt_c.0, - elememt_c.1, - rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .unwrap() - .close_price, - )); - } - } - })); - } - - try_join_all(task_vec).await?; - - let a = filtered_symbols_arc.lock().await.clone(); - insert_pre_suggested_coins(2, false, &a, alldata).await; - - Ok(()) -} - -pub async fn strategist_003( - alldata: &AllData, -) -> Result<(), Box> { - // print rt_price for debugging - // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); - // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); - - // 1st filtering: supertrend(ATR period 100, multiplier: 3.0, 30m close price), the area should be in UP area. - let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_2nd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - for symbol in valid_symbol_vec_c { - let mut opclo_30m_vec: Vec = Vec::new(); - let mut supertrend_vec: Vec = Vec::new(); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - let supertrend_option_30m = - supertrend(&symbol, &rt_price_30m_vec_c, 100, 3.0, true).await; - - if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { - opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - supertrend_vec = supertrend_option_30m.unwrap(); - - if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { - let supertrend_search_result = supertrend_vec.binary_search_by_key( - &opclo_30m_vec.last().unwrap().close_time, - |SupertrendData { - band_value, - signal, - area, - close_time, - }| *close_time, - ); - if supertrend_search_result.is_ok() { - if supertrend_vec[supertrend_search_result.unwrap()] - .area - .contains("UP") - { - let mut filtered_2nd_symbols_lock = - filtered_2nd_symbols_arc_c.lock().await; - filtered_2nd_symbols_lock - .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - } - } - } - } - })); - } - try_join_all(task_vec).await?; - - // 2nd filtering: lookup tables if the tradepair is already there - let inspect_table_name_1 = String::from("buy_ordered_coin_list"); - let inspect_table_name_2 = String::from("sell_ordered_coin_list"); - let inspect_table_name_3 = String::from("pre_suggested_coin_list"); - let inspect_table_name_4 = String::from("suggested_coin_list"); - - let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_3rd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - - let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); - for element in filtered_2nd_iter { - let mut exists_condition_build = String::from("symbol=\'"); - exists_condition_build.push_str(element.0.as_str()); - exists_condition_build.push_str("\' AND registerer="); - exists_condition_build.push_str(3.to_string().as_str()); - // exists_condition_build.push_str("\' AND close_time="); - // exists_condition_build.push_str(element.1.to_string().as_str()); - let exists_condition = Some(exists_condition_build); - let exists_condition_c = exists_condition.clone(); - let inspect_table_name_1_c = inspect_table_name_1.clone(); - let inspect_table_name_2_c = inspect_table_name_2.clone(); - let inspect_table_name_3_c = inspect_table_name_3.clone(); - let inspect_table_name_4_c = inspect_table_name_4.clone(); - let element_c = element.clone(); - let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let inspect_result_1 = - exists_record(&inspect_table_name_1_c, &exists_condition_c).await; - let inspect_result_2 = - exists_record(&inspect_table_name_2_c, &exists_condition_c).await; - let inspect_result_3 = - exists_record(&inspect_table_name_3_c, &exists_condition_c).await; - let inspect_result_4 = - exists_record(&inspect_table_name_4_c, &exists_condition_c).await; - - if inspect_result_1 == false - && inspect_result_2 == false - && inspect_result_3 == false - && inspect_result_4 == false - { - let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; - filtered_3rd_symbols_lock.push(element_c); - } - })); - } - try_join_all(task_vec).await?; - - // 3rd filtering: EMA30 > EMA 150 - let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); - let ema30_30m_data: Vec<(String, Vec)> = ema( - 30, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - let ema150_30m_data: Vec<(String, Vec)> = ema( - 150, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - - let mut task_vec = Vec::new(); - let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_4th_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) - for element in filtered_3rd_symbols_c { - let mut ema30_30m_vec: Vec = Vec::new(); - let mut ema150_30m_vec: Vec = Vec::new(); - let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0); - let ema30_30m_option_c = ema30_30m_option.clone(); - let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0); - let ema150_30m_option_c = ema150_30m_option.clone(); - let element_c = element.clone(); - let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); - - if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() { - ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone(); - ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone(); - - if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 { - let ema30_30m_vec_c = ema30_30m_vec.clone(); - let ema150_30m_vec_c = ema150_30m_vec.clone(); - - task_vec.push(tokio::spawn(async move { - let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( - &element_c.1, - |&EmaData { - ema_value, - close_time, - }| close_time, - ); - let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( - &element_c.1, - |&EmaData { - ema_value, - close_time, - }| close_time, - ); - - if ema30_search_result.is_ok() && ema150_search_result.is_ok() { - if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value - { - let mut filtered_4th_symbols_lock = - filtered_4th_symbols_arc_c.lock().await; - filtered_4th_symbols_lock.push(element_c); - } - } - })); - } - } - } - try_join_all(task_vec).await?; - - // 4th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) 20 > k > kn-1 > kn-2 > kn-3, - let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone(); - let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( - 10, - &alldata.rt_price_30m_vec, - &filtered_4th_symbol_c, - ) - .await?; - let stoch_rsi_data = stoch_rsi(&rsi10_30m_data, 10, 3, 3).await?; - let mut stoch_rsi10_30m_vec: Vec = Vec::new(); - let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_4th_symbol_c { - let stoch_rsi10_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); - - if stoch_rsi10_30m_option.is_some() { - stoch_rsi10_30m_vec = stoch_rsi_data[stoch_rsi10_30m_option.unwrap()].1.clone(); - - if stoch_rsi10_30m_vec.len() >= 3 { - let stoch_rsi_search_result = stoch_rsi10_30m_vec.binary_search_by_key( - &element.1, - |&StochRsiData { - k, - d, - close_time, - }| close_time, - ); - if stoch_rsi_search_result.is_ok() { - if 10.0 > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-2].k && - stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-2].k <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-3].k { - filtered_5th_symbols.push(element); - } - } - } - } - } - - // final job: adding price information to filtered results - let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) - let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); - let mut task_vec = Vec::new(); - for element in filtered_5th_symbols { - let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - - let elememt_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - if rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .is_some() - { - let mut filtered_symbols_lock: tokio::sync::MutexGuard< - '_, - Vec<(String, i64, f64)>, - > = filtered_symbols_arc_c.lock().await; - filtered_symbols_lock.push(( - elememt_c.0, - elememt_c.1, - rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .unwrap() - .close_price, - )); - } - } - })); - } - - try_join_all(task_vec).await?; - - // 6th filtering condition: MACD - // let mut opclo_30m_vec: Vec = Vec::new(); - // let mut ema3_1d_vec: &Vec = &Vec::new(); - // let mut ema10_1d_vec: &Vec = &Vec::new(); - - // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - // for element in filtered_6th_symbols { - // let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0); - // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0); - - // if ema3_1d_option.is_some() && ema10_1d_option.is_some() { - // ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1; - // ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1; - - // if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { - // let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; - // // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); - - // // if macd_search_result.is_ok() { - // if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 { - // filtered_7th_symbols.push(element); - // } - // // } - // } - // } - // } - let a = filtered_symbols_arc.lock().await.clone(); - insert_pre_suggested_coins(3, false, &a, alldata).await; - - Ok(()) -} - -pub async fn strategist_004( - alldata: &AllData, -) -> Result<(), Box> { - // print rt_price for debugging - // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); - // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); - - // 1st filtering: supertrend(ATR period 10, multiplier: 2.0, 30m close price), the area should be in UP area. - let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_2nd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - for symbol in valid_symbol_vec_c { - let mut opclo_30m_vec: Vec = Vec::new(); - let mut supertrend_vec: Vec = Vec::new(); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - let supertrend_option_30m = - supertrend(&symbol, &rt_price_30m_vec_c, 10, 2.0, true).await; - - if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { - opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - supertrend_vec = supertrend_option_30m.unwrap(); - - if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { - let supertrend_search_result = supertrend_vec.binary_search_by_key( - &opclo_30m_vec.last().unwrap().close_time, - |SupertrendData { - band_value, - signal, - area, - close_time, - }| *close_time, - ); - if supertrend_search_result.is_ok() { - if supertrend_vec[supertrend_search_result.unwrap()] - .area - .contains("UP") - { - let mut filtered_2nd_symbols_lock = - filtered_2nd_symbols_arc_c.lock().await; - filtered_2nd_symbols_lock - .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - } - } - } - } - })); - } - try_join_all(task_vec).await?; - - // 2nd filtering: lookup tables if the tradepair is already there - let inspect_table_name_1 = String::from("buy_ordered_coin_list"); - let inspect_table_name_2 = String::from("sell_ordered_coin_list"); - let inspect_table_name_3 = String::from("pre_suggested_coin_list"); - let inspect_table_name_4 = String::from("suggested_coin_list"); - - let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_3rd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - - let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); - for element in filtered_2nd_iter { - let mut exists_condition_build = String::from("symbol=\'"); - exists_condition_build.push_str(element.0.as_str()); - exists_condition_build.push_str("\' AND registerer="); - exists_condition_build.push_str(4.to_string().as_str()); - // exists_condition_build.push_str("\' AND close_time="); - // exists_condition_build.push_str(element.1.to_string().as_str()); - let exists_condition = Some(exists_condition_build); - let exists_condition_c = exists_condition.clone(); - let inspect_table_name_1_c = inspect_table_name_1.clone(); - let inspect_table_name_2_c = inspect_table_name_2.clone(); - let inspect_table_name_3_c = inspect_table_name_3.clone(); - let inspect_table_name_4_c = inspect_table_name_4.clone(); - let element_c = element.clone(); - let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let inspect_result_1 = - exists_record(&inspect_table_name_1_c, &exists_condition_c).await; - let inspect_result_2 = - exists_record(&inspect_table_name_2_c, &exists_condition_c).await; - let inspect_result_3 = - exists_record(&inspect_table_name_3_c, &exists_condition_c).await; - let inspect_result_4 = - exists_record(&inspect_table_name_4_c, &exists_condition_c).await; - - if inspect_result_1 == false - && inspect_result_2 == false - && inspect_result_3 == false - && inspect_result_4 == false - { - let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; - filtered_3rd_symbols_lock.push(element_c); - } - })); - } - try_join_all(task_vec).await?; - - // 3rd filtering: EMA30 >= EMA 150 - let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); - let ema30_30m_data: Vec<(String, Vec)> = ema( - 30, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - let ema150_30m_data: Vec<(String, Vec)> = ema( - 150, - &alldata.rt_price_30m_vec, - &filtered_3rd_symbols_c, - ) - .await?; - - let mut task_vec = Vec::new(); - let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_4th_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) - for element in filtered_3rd_symbols_c { - let mut ema30_30m_vec: Vec = Vec::new(); - let mut ema150_30m_vec: Vec = Vec::new(); - let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0); - let ema30_30m_option_c = ema30_30m_option.clone(); - let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0); - let ema150_30m_option_c = ema150_30m_option.clone(); - let element_c = element.clone(); - let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); - - if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() { - ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone(); - ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone(); - - if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 { - let ema30_30m_vec_c = ema30_30m_vec.clone(); - let ema150_30m_vec_c = ema150_30m_vec.clone(); - - task_vec.push(tokio::spawn(async move { - let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( - &element_c.1, - |&EmaData { - ema_value, - close_time, - }| close_time, - ); - let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( - &element_c.1, - |&EmaData { - ema_value, - close_time, - }| close_time, - ); - - if ema30_search_result.is_ok() && ema150_search_result.is_ok() { - if ema30_30m_vec_c[ema30_search_result.unwrap()-9].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-9].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-8].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-8].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-7].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-7].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-6].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-6].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-5].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-5].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-4].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-4].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value >= ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && - ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value - { - let mut filtered_4th_symbols_lock = - filtered_4th_symbols_arc_c.lock().await; - filtered_4th_symbols_lock.push(element_c); - } - } - })); - } - } - } - try_join_all(task_vec).await?; - - // 4th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be Normal or Low. - let filtered_4th_symbols_c = filtered_4th_symbols_arc.lock().await.clone(); - let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_4th_symbols_c { - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let heatmap_volume_option = - heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) - .await; - if heatmap_volume_option.is_some() { - let heatmap_volume_vec = heatmap_volume_option.unwrap(); - let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( - &element.1, - |HeatmapVolumeData { - heatmap_value, - heatmap_level, - close_time, - }| *close_time, - ); - if heatmap_search_result.is_ok() { - if (heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::Low - || - heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::Normal) && - (heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level - == HeatMapLevel::Low - || - heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level - == HeatMapLevel::Normal - ) - { - filtered_5th_symbols.push(element); - } - } - } - } - } - } - - // final job: adding price information to filtered results - let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) - let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); - let mut task_vec = Vec::new(); - for element in filtered_5th_symbols { - let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - - let elememt_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - if rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .is_some() - { - let mut filtered_symbols_lock: tokio::sync::MutexGuard< - '_, - Vec<(String, i64, f64)>, - > = filtered_symbols_arc_c.lock().await; - filtered_symbols_lock.push(( - elememt_c.0, - elememt_c.1, - rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .unwrap() - .close_price, - )); - } - } - })); - } - - try_join_all(task_vec).await?; - - let a = filtered_symbols_arc.lock().await.clone(); - insert_pre_suggested_coins(4, false, &a, alldata).await; - - Ok(()) -} - -pub async fn strategist_005( - alldata: &AllData, -) -> Result<(), Box> { - // print rt_price for debugging - // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); - // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); - - // 1st filtering: supertrend(ATR period 30, multiplier: 6.0, 30m close price), the area should be in UP area. - let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_2nd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - for symbol in valid_symbol_vec_c { - let mut opclo_30m_vec: Vec = Vec::new(); - let mut supertrend_vec: Vec = Vec::new(); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - let supertrend_option_30m = - supertrend(&symbol, &rt_price_30m_vec_c, 30, 6.0, true).await; - - if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { - opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - supertrend_vec = supertrend_option_30m.unwrap(); - - if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { - let supertrend_search_result = supertrend_vec.binary_search_by_key( - &opclo_30m_vec.last().unwrap().close_time, - |SupertrendData { - band_value, - signal, - area, - close_time, - }| *close_time, - ); - if supertrend_search_result.is_ok() { - if supertrend_vec[supertrend_search_result.unwrap()] - .signal.as_ref().is_some_and(|signal| signal.contains("BUY")) - { - let mut filtered_2nd_symbols_lock = - filtered_2nd_symbols_arc_c.lock().await; - filtered_2nd_symbols_lock - .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - } - } - } - } - })); - } - try_join_all(task_vec).await?; - - // 2nd filtering: lookup tables if the tradepair is already there - let inspect_table_name_1 = String::from("buy_ordered_coin_list"); - let inspect_table_name_2 = String::from("sell_ordered_coin_list"); - let inspect_table_name_3 = String::from("pre_suggested_coin_list"); - let inspect_table_name_4 = String::from("suggested_coin_list"); - - let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_3rd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - - let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); - for element in filtered_2nd_iter { - let mut exists_condition_build = String::from("symbol=\'"); - exists_condition_build.push_str(element.0.as_str()); - exists_condition_build.push_str("\' AND registerer="); - exists_condition_build.push_str(5.to_string().as_str()); - // exists_condition_build.push_str("\' AND close_time="); - // exists_condition_build.push_str(element.1.to_string().as_str()); - let exists_condition = Some(exists_condition_build); - let exists_condition_c = exists_condition.clone(); - let inspect_table_name_1_c = inspect_table_name_1.clone(); - let inspect_table_name_2_c = inspect_table_name_2.clone(); - let inspect_table_name_3_c = inspect_table_name_3.clone(); - let inspect_table_name_4_c = inspect_table_name_4.clone(); - let element_c = element.clone(); - let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let inspect_result_1 = - exists_record(&inspect_table_name_1_c, &exists_condition_c).await; - let inspect_result_2 = - exists_record(&inspect_table_name_2_c, &exists_condition_c).await; - let inspect_result_3 = - exists_record(&inspect_table_name_3_c, &exists_condition_c).await; - let inspect_result_4 = - exists_record(&inspect_table_name_4_c, &exists_condition_c).await; - - if inspect_result_1 == false - && inspect_result_2 == false - && inspect_result_3 == false - && inspect_result_4 == false - { - let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; - filtered_3rd_symbols_lock.push(element_c); - } - })); - } - try_join_all(task_vec).await?; - - // 3rd filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be Normal or Low. - let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); - let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_3rd_symbols_c { - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let heatmap_volume_option = - heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) - .await; - if heatmap_volume_option.is_some() { - let heatmap_volume_vec = heatmap_volume_option.unwrap(); - let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( - &element.1, - |HeatmapVolumeData { - heatmap_value, - heatmap_level, - close_time, - }| *close_time, - ); - if heatmap_search_result.is_ok() { - if (heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::Low - || - heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level - == HeatMapLevel::Normal) && - (heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level - == HeatMapLevel::Low - || - heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level - == HeatMapLevel::Normal) && - (heatmap_volume_vec[heatmap_search_result.unwrap()-2].heatmap_level - == HeatMapLevel::Low - || - heatmap_volume_vec[heatmap_search_result.unwrap()-2].heatmap_level - == HeatMapLevel::Normal) - { - filtered_4th_symbols.push(element); - } - } - } - } - } - } - - // final job: adding price information to filtered results - let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) - let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); - let mut task_vec = Vec::new(); - for element in filtered_4th_symbols { - let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - - let elememt_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - if rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .is_some() - { - let mut filtered_symbols_lock: tokio::sync::MutexGuard< - '_, - Vec<(String, i64, f64)>, - > = filtered_symbols_arc_c.lock().await; - filtered_symbols_lock.push(( - elememt_c.0, - elememt_c.1, - rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .unwrap() - .close_price, - )); - } - } - })); - } - - try_join_all(task_vec).await?; - - let a = filtered_symbols_arc.lock().await.clone(); - insert_pre_suggested_coins(5, false, &a, alldata).await; - - Ok(()) -} - -pub async fn strategist_006( - alldata: &AllData, -) -> Result<(), Box> { - // print rt_price for debugging - // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); - // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); - - // 1st filtering: making basic form - let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_2nd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); - for symbol in valid_symbol_vec_c { - let mut opclo_30m_vec: Vec = Vec::new(); - - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); - - if opclo_30m_option.is_some() { - opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); - - if opclo_30m_vec.len() >= 3 { - let mut filtered_2nd_symbols_lock = - filtered_2nd_symbols_arc_c.lock().await; - filtered_2nd_symbols_lock - .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); - } - } - })); - } - try_join_all(task_vec).await?; - - // 2nd filtering: lookup tables if the tradepair is already there - let inspect_table_name_1 = String::from("buy_ordered_coin_list"); - let inspect_table_name_2 = String::from("sell_ordered_coin_list"); - let inspect_table_name_3 = String::from("pre_suggested_coin_list"); - let inspect_table_name_4 = String::from("suggested_coin_list"); - - let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); - let mut filtered_3rd_symbols_arc: Arc>> = - Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) - let mut task_vec = Vec::new(); - - let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); - for element in filtered_2nd_iter { - let mut exists_condition_build = String::from("symbol=\'"); - exists_condition_build.push_str(element.0.as_str()); - exists_condition_build.push_str("\' AND registerer="); - exists_condition_build.push_str(6.to_string().as_str()); - // exists_condition_build.push_str("\' AND close_time="); - // exists_condition_build.push_str(element.1.to_string().as_str()); - let exists_condition = Some(exists_condition_build); - let exists_condition_c = exists_condition.clone(); - let inspect_table_name_1_c = inspect_table_name_1.clone(); - let inspect_table_name_2_c = inspect_table_name_2.clone(); - let inspect_table_name_3_c = inspect_table_name_3.clone(); - let inspect_table_name_4_c = inspect_table_name_4.clone(); - let element_c = element.clone(); - let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); - task_vec.push(tokio::spawn(async move { - let inspect_result_1 = - exists_record(&inspect_table_name_1_c, &exists_condition_c).await; - let inspect_result_2 = - exists_record(&inspect_table_name_2_c, &exists_condition_c).await; - let inspect_result_3 = - exists_record(&inspect_table_name_3_c, &exists_condition_c).await; - let inspect_result_4 = - exists_record(&inspect_table_name_4_c, &exists_condition_c).await; - - if inspect_result_1 == false - && inspect_result_2 == false - && inspect_result_3 == false - && inspect_result_4 == false - { - let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; - filtered_3rd_symbols_lock.push(element_c); - } - })); - } - try_join_all(task_vec).await?; - - // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth kn > kn-1 - let filtered_3rd_symbol_c = filtered_3rd_symbols_arc.lock().await.clone(); - let mut rsi10_1d_data: Vec<(String, Vec)> = rsi( - 10, - &alldata.rt_price_1d_vec, - &filtered_3rd_symbol_c, - ) - .await?; - let stoch_rsi_data = stoch_rsi(&rsi10_1d_data, 10, 3, 3).await?; - let mut stoch_rsi10_1d_vec: Vec = Vec::new(); - let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_3rd_symbol_c { - let stoch_rsi10_1d_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); - - if stoch_rsi10_1d_option.is_some() { - stoch_rsi10_1d_vec = stoch_rsi_data[stoch_rsi10_1d_option.unwrap()].1.clone(); - - if stoch_rsi10_1d_vec.len() >= 3 { - let stoch_rsi_search_result = stoch_rsi10_1d_vec.binary_search_by_key( - &element.1, - |&StochRsiData { - k, - d, - close_time, - }| close_time, - ); - if stoch_rsi_search_result.is_ok() { - if stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k > stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()-1].k && - stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k < 90.0 && - stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()-1].k > 10.0 { - filtered_4th_symbols.push(element); - } - } - } - } - } - - // 6th filtering condition: MACD - let mut opclo_30m_vec: Vec = Vec::new(); - let mut ema3_1d_vec: &Vec = &Vec::new(); - let mut ema10_1d_vec: &Vec = &Vec::new(); - - let ema3_1d_data: Vec<(String, Vec)> = ema( - 3, - &alldata.rt_price_1d_vec, - &filtered_4th_symbols, - ) - .await?; - let ema10_1d_data: Vec<(String, Vec)> = ema( - 10, - &alldata.rt_price_1d_vec, - &filtered_4th_symbols, - ) - .await?; - - let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - for element in filtered_4th_symbols { - let ema3_1d_option = ema3_1d_data.iter().position(|x| *x.0 == *element.0); - let ema10_1d_option = ema10_1d_data.iter().position(|x| *x.0 == *element.0); - - if ema3_1d_option.is_some() && ema10_1d_option.is_some() { - ema3_1d_vec = &ema3_1d_data[ema3_1d_option.unwrap()].1; - ema10_1d_vec = &ema10_1d_data[ema10_1d_option.unwrap()].1; - - if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { - let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; - // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); - - // if macd_search_result.is_ok() { - if macd_vec.last().unwrap().macd_value > macd_vec[macd_vec.len() -1].macd_value { - filtered_5th_symbols.push(element); - } - // } - } - } - } - - // final job: adding price information to filtered results - let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) - let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); - let mut task_vec = Vec::new(); - for element in filtered_5th_symbols { - let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); - let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); - - let elememt_c = element.clone(); - task_vec.push(tokio::spawn(async move { - let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); - if opclo_30m_option.is_some() { - if rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .is_some() - { - let mut filtered_symbols_lock: tokio::sync::MutexGuard< - '_, - Vec<(String, i64, f64)>, - > = filtered_symbols_arc_c.lock().await; - filtered_symbols_lock.push(( - elememt_c.0, - elememt_c.1, - rt_price_30m_vec_c[opclo_30m_option.unwrap()] - .1 - .last() - .unwrap() - .close_price, - )); - } - } - })); - } - - try_join_all(task_vec).await?; - - let a = filtered_symbols_arc.lock().await.clone(); - insert_pre_suggested_coins(6, true, &a, alldata).await; - - Ok(()) -} - -// pub async fn execute_strategist_for_test1( -// alldata: &AllData, -// ) -> Result<(), Box> { -// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); -// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); -// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); -// let inspect_table_name_4 = String::from("suggested_coin_list"); - -// let market_cap_index = select_marketcap().await; - -// let mut filtered_symbols: Vec = Vec::new(); -// // filtered_symbols.push(String::from("BNBUSDT")); -// filtered_symbols.push(String::from("BTCUSDT")); -// // filtered_symbols.push(String::from("ETHUSDT")); -// // filtered_symbols.push(String::from("LTCUSDT")); -// // filtered_symbols.push(String::from("XRPUSDT")); -// // filtered_symbols.push(String::from("TRXUSDT")); -// // let current_price = get_current_price(&filtered_symbols.first().unwrap(), &alldata.price_vec).await.unwrap(); - -// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// let mut ema3_1m_vec: &Vec = &Vec::new(); -// let mut ema3_30m_vec: &Vec = &Vec::new(); -// let mut ema10_1m_vec: &Vec = &Vec::new(); -// let mut ema30_1m_vec: &Vec = &Vec::new(); -// let mut sma10_1m_vec: &Vec = &Vec::new(); -// let mut sma3_30m_vec: &Vec = &Vec::new(); -// let mut sma30_1m_vec: &Vec = &Vec::new(); -// let mut rsi3_1m_vec: &Vec = &Vec::new(); -// let mut rsi30_1m_vec: &Vec = &Vec::new(); -// let mut stoch_rsi3_1m_k_vec: &Vec = &Vec::new(); -// let mut stoch_rsi3_1m_d_vec: &Vec = &Vec::new(); -// let mut stoch_rsi30_1m_k_vec: &Vec = &Vec::new(); -// let mut stoch_rsi30_1m_d_vec: &Vec = &Vec::new(); -// let mut rt_price_1m_vec: &Vec = &Vec::new(); -// let mut is_filtering_passed: bool = false; - -// let mut cnt = 0; -// let exists_condition = Some(String::from("used_usdt >= 10.0 AND registerer = 1")); -// let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; -// let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; -// let mut is_buy_period_30m = false; - -// if inspect_result_1 == false && inspect_result_2 == false { -// for symbol in filtered_symbols { -// is_filtering_passed = false; -// let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); -// let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); -// let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); -// let ema30_1m_option = alldata.ema30_1m_data.iter().position(|x| *x.0 == *symbol); -// let sma10_1m_option = alldata.sma10_1m_data.iter().position(|x| *x.0 == *symbol); -// let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); -// let sma30_1m_option = alldata.sma30_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); -// let stoch_rsi3_1m_k_option = alldata -// .stoch_rsi3_1m_3_k_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let stoch_rsi3_1m_d_option = alldata -// .stoch_rsi3_1m_3_d_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let stoch_rsi30_1m_k_option = alldata -// .stoch_rsi30_1m_30_k_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let stoch_rsi30_1m_d_option = alldata -// .stoch_rsi30_1m_30_d_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let rt_price_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); - -// let supertrend_option_30m = -// supertrend(&symbol, &alldata.rt_price_30m_vec, 3, 0.5, true).await; - -// if supertrend_option_30m.is_some() { -// let supertrend_vec = supertrend_option_30m.unwrap(); -// if supertrend_vec.last().unwrap().area.contains("UP") { -// is_buy_period_30m = true; -// } -// } - -// if is_buy_period_30m == true -// && ema3_1m_option.is_some() -// && ema3_30m_option.is_some() -// && ema10_1m_option.is_some() -// && ema30_1m_option.is_some() -// && sma10_1m_option.is_some() -// && sma3_30m_option.is_some() -// && sma30_1m_option.is_some() -// && rsi3_1m_option.is_some() -// && rsi30_1m_option.is_some() -// && stoch_rsi3_1m_k_option.is_some() -// && stoch_rsi3_1m_d_option.is_some() -// && stoch_rsi30_1m_k_option.is_some() -// && stoch_rsi30_1m_d_option.is_some() -// && rt_price_1m_option.is_some() -// { -// ema3_1m_vec = &alldata.ema3_1m_data[ema3_1m_option.unwrap()].1; -// ema3_30m_vec = &alldata.ema3_30m_data[ema3_30m_option.unwrap()].1; -// ema10_1m_vec = &alldata.ema10_1m_data[ema10_1m_option.unwrap()].1; -// ema30_1m_vec = &alldata.ema30_1m_data[ema30_1m_option.unwrap()].1; -// sma10_1m_vec = &alldata.sma10_1m_data[sma10_1m_option.unwrap()].1; -// sma3_30m_vec = &alldata.sma3_30m_data[sma3_30m_option.unwrap()].1; -// sma30_1m_vec = &alldata.sma30_1m_data[sma30_1m_option.unwrap()].1; -// rsi3_1m_vec = &alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1; -// rsi30_1m_vec = &alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1; -// stoch_rsi3_1m_k_vec = -// &alldata.stoch_rsi3_1m_3_k_data[stoch_rsi3_1m_k_option.unwrap()].1; -// stoch_rsi3_1m_d_vec = -// &alldata.stoch_rsi3_1m_3_d_data[stoch_rsi3_1m_d_option.unwrap()].1; -// stoch_rsi30_1m_k_vec = -// &alldata.stoch_rsi30_1m_30_k_data[stoch_rsi30_1m_k_option.unwrap()].1; -// stoch_rsi30_1m_d_vec = -// &alldata.stoch_rsi30_1m_30_d_data[stoch_rsi30_1m_d_option.unwrap()].1; -// rt_price_1m_vec = &alldata.rt_price_1m_vec[rt_price_1m_option.unwrap()].1; - -// // filtering condition: data are ready -// if ema3_1m_vec.len() >= 3 -// && ema3_30m_vec.len() >= 3 -// && ema10_1m_vec.len() >= 3 -// && ema30_1m_vec.len() >= 3 -// && sma10_1m_vec.len() >= 3 -// && sma3_30m_vec.len() >= 3 -// && sma30_1m_vec.len() >= 3 -// && rsi3_1m_vec.len() >= 3 -// && rsi30_1m_vec.len() >= 3 -// && stoch_rsi3_1m_k_vec.len() >= 5 -// && stoch_rsi3_1m_d_vec.len() >= 5 -// && stoch_rsi30_1m_k_vec.len() >= 5 -// && stoch_rsi30_1m_d_vec.len() >= 5 -// && rt_price_1m_vec.len() >= 50 -// { -// is_filtering_passed = true; -// } - -// // // filtering condition: SuperTrend & EMA & SMA -// // if is_filtering_passed == true { -// // let supertrend_option = supertrend(&symbol, &alldata.rt_price_1m_vec, 10, 1.0, false).await; -// // if supertrend_option.is_some() { -// // let supertrend_vec = supertrend_option.unwrap(); -// // let supertrend_result = supertrend_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |SupertrendData{band_value, signal, area, close_time}| *close_time); -// // let ema3_result = ema3_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// // let sma10_result = sma10_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); - -// // if supertrend_vec.last().unwrap().signal.is_some() && ema3_result.is_ok() && sma10_result.is_ok() { -// // if (((supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) && rt_price_1m_vec.last().unwrap().close_price <= supertrend_vec[supertrend_vec.len()-2].band_value * 1.0005) -// // || (supertrend_vec.last().unwrap().area.contains("UP") && ema3_1m_vec[ema3_result.unwrap()-1].ema_value < sma10_1m_vec[sma10_result.unwrap()-1].sma_value && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value)) -// // && sma10_1m_vec[sma10_result.unwrap()-2].sma_value < sma10_1m_vec[sma10_result.unwrap()].sma_value { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } else { is_filtering_passed = false; } -// // } else { is_filtering_passed = false; } -// // } - -// // filtering condition: SuperTrend -// if is_filtering_passed == true { -// let supertrend_option = -// supertrend(&symbol, &alldata.rt_price_1m_vec, 30, 1.5, false).await; -// if supertrend_option.is_some() { -// let supertrend_vec = supertrend_option.unwrap(); -// let supertrend_result = supertrend_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |SupertrendData { -// band_value, -// signal, -// area, -// close_time, -// }| *close_time, -// ); - -// if supertrend_result.is_ok() { -// if supertrend_vec[supertrend_result.unwrap()] -// .signal -// .as_ref() -// .is_some() -// { -// if supertrend_vec[supertrend_result.unwrap()] -// .signal -// .as_ref() -// .unwrap() -// .contains("BUY") -// && supertrend_vec[supertrend_result.unwrap() - 1].band_value -// + ((rt_price_1m_vec[rt_price_1m_vec.len() - 2].high_price -// - rt_price_1m_vec[rt_price_1m_vec.len() - 2].low_price) -// * 0.1) -// > rt_price_1m_vec.last().unwrap().close_price -// { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: SMA & EMA -// if is_filtering_passed == true { -// let sma10_1m_result = sma10_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// let sma30_1m_result = sma30_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// let ema3_1m_result = ema3_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// let ema3_30m_result = ema3_30m_vec.binary_search_by_key( -// &sma3_30m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// let ema10_1m_result = ema10_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// let ema30_1m_result = ema30_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// if sma10_1m_result.is_ok() -// && sma30_1m_result.is_ok() -// && ema3_1m_result.is_ok() -// && ema10_1m_result.is_ok() -// && ema30_1m_result.is_ok() -// && ema3_30m_result.is_ok() -// { -// if ema3_1m_vec[ema3_1m_result.unwrap()].ema_value -// >= ema10_1m_vec[ema10_1m_result.unwrap()].ema_value -// { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: current price limitation -// // if is_filtering_passed == true { -// // if rt_price_1m_vec[rt_price_1m_vec.len()-2].close_price + ((rt_price_1m_vec[rt_price_1m_vec.len()-2].high_price - rt_price_1m_vec[rt_price_1m_vec.len()-2].low_price) * 0.1) > rt_price_1m_vec.last().unwrap().close_price { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } - -// // filtering condition: Heatmap Volume -// // if is_filtering_passed == true { -// // let heatmap_volume_option = heatmap_volume(&symbol, &alldata.rt_price_1m_vec, 30, 30, 4.0, 2.5, 1.0, -0.5).await; -// // if heatmap_volume_option.is_some() { -// // let heatmap_volume_vec = heatmap_volume_option.unwrap(); -// // let heatmap_search_result = heatmap_volume_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |HeatmapVolumeData{heatmap_value, heatmap_level, close_time}|*close_time); -// // if heatmap_search_result.is_ok() { -// // let heatmap_volume_trunc_vec_option = heatmap_volume_vec.get(heatmap_search_result.unwrap()-11..heatmap_search_result.unwrap()-1); -// // if heatmap_volume_trunc_vec_option.is_some() { -// // let heatmap_volume_trunc_vec = heatmap_volume_trunc_vec_option.unwrap(); -// // let mut heat_value_summation = 0.0; -// // for element in heatmap_volume_trunc_vec { -// // if element.heatmap_level == HeatMapLevel::ExtraHigh { -// // heat_value_summation += 2.0; -// // } else if element.heatmap_level == HeatMapLevel::High { -// // heat_value_summation += 1.5; -// // } else if element.heatmap_level == HeatMapLevel::Medium { -// // heat_value_summation += 1.0; -// // } else if element.heatmap_level == HeatMapLevel::Normal { -// // heat_value_summation += 0.5; -// // } else { -// // heat_value_summation += 0.0; -// // } -// // } -// // if heat_value_summation >= 2.0 { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } -// // } -// // } else { is_filtering_passed = false; } -// // } - -// // filtering condition: Stoch RSI -// if is_filtering_passed == true { -// // let sample_length: usize = 5; -// // stoch_rsi10_1m_k_vec.reverse(); -// // stoch_rsi10_1m_k_vec.truncate(5); -// // stoch_rsi10_1m_k_vec.reverse(); -// // stoch_rsi10_1m_d_vec.reverse(); -// // stoch_rsi10_1m_d_vec.truncate(5); -// // stoch_rsi10_1m_d_vec.reverse(); -// let rsi3_k_result = stoch_rsi3_1m_k_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&StochRsiKData { -// stoch_rsi_k_value, -// close_time, -// }| close_time, -// ); -// let rsi3_d_result = stoch_rsi3_1m_d_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&StochRsiDData { -// stoch_rsi_d_value, -// close_time, -// }| close_time, -// ); -// let rsi30_k_result = stoch_rsi30_1m_k_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&StochRsiKData { -// stoch_rsi_k_value, -// close_time, -// }| close_time, -// ); -// let rsi30_d_result = stoch_rsi30_1m_d_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&StochRsiDData { -// stoch_rsi_d_value, -// close_time, -// }| close_time, -// ); -// if rsi30_k_result.is_ok() -// && rsi30_d_result.is_ok() -// && rsi3_k_result.is_ok() -// && rsi3_d_result.is_ok() -// { -// if stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value -// >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value -// && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap() - 1].stoch_rsi_k_value -// >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap() - 1] -// .stoch_rsi_d_value -// && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value -// <= 50.0 -// // (stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value -// // && stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value > stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) -// // || -// // && (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= 60.0 -// // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-2].stoch_rsi_k_value >= stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value -// // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi3_1m_d_vec[rsi3_d_result.unwrap()-1].stoch_rsi_d_value -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value) -// // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) -// // || (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 -// // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) -// { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: MACD -// if is_filtering_passed == true { -// let macd_vec = ema_macd(&ema3_1m_vec, &ema10_1m_vec, 10).await?; -// let macd_search_result = macd_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaMacd { -// macd_value, -// close_time, -// }| close_time, -// ); - -// if macd_search_result.is_ok() { -// if macd_vec[macd_search_result.unwrap()].macd_value -// > macd_vec[macd_search_result.unwrap() - 1].macd_value -// { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: Ratio between amplitude and body of candles -// if is_filtering_passed == true { -// let sample_length: usize = 5; // 5 candle samsples -// let rt_price_1m_partial_vec_option = rt_price_1m_vec -// .get(rt_price_1m_vec.len() - sample_length - 1..rt_price_1m_vec.len() - 1); -// if rt_price_1m_partial_vec_option.is_some() { -// let rt_price_1m_partial_vec = rt_price_1m_partial_vec_option.unwrap(); - -// let mut sum_ratio_amp_body = 0.0; -// for element in rt_price_1m_partial_vec { -// sum_ratio_amp_body += (element.close_price - element.open_price).abs() -// / (element.high_price - element.low_price); -// } -// let average_ratio_amp_body = sum_ratio_amp_body / sample_length as f64; -// if average_ratio_amp_body > 0.3 { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // check all filterings are passed -// if is_filtering_passed == true { -// filtered_2nd_symbols.push((symbol, rt_price_1m_vec.last().unwrap().close_time)); -// } - -// // if ema3_1m_vec.len() >= 3 && ema10_1m_vec.len() >= 3 && ema30_1m_vec.len() >= 3 && sma10_1m_vec.len() >= 3 && rsi3_1m_vec.len() >= 3 && stoch_rsi10_1m_k_vec.len() >= 5 && stoch_rsi10_1m_d_vec.len() >= 5 && stoch_rsi30_1m_k_vec.len() >= 5 && stoch_rsi30_1m_d_vec.len() >= 5 && rt_price_1m_vec.len() >= 10 { -// // stoch_rsi10_1m_k_vec.reverse(); -// // stoch_rsi10_1m_k_vec.truncate(5); -// // stoch_rsi10_1m_k_vec.reverse(); -// // stoch_rsi10_1m_d_vec.reverse(); -// // stoch_rsi10_1m_d_vec.truncate(5); -// // stoch_rsi10_1m_d_vec.reverse(); -// // stoch_rsi30_1m_k_vec.reverse(); -// // stoch_rsi30_1m_k_vec.truncate(5); -// // stoch_rsi30_1m_k_vec.reverse(); -// // stoch_rsi30_1m_d_vec.reverse(); -// // stoch_rsi30_1m_d_vec.truncate(5); -// // stoch_rsi30_1m_d_vec.reverse(); -// // let supertrend_option = supertrend(&symbol, &alldata.rt_price_1m_vec, 10, 1.0, false).await; -// // let heatmap_volume_option = heatmap_volume(&symbol, &alldata.rt_price_1m_vec, 30, 30, 4.0, 2.5, 1.0, -0.5).await; -// // let macd_vec = ema_macd(&ema10_1m_vec, &ema30_1m_vec, 30).await?; - -// // if supertrend_option.is_some() && heatmap_volume_option.is_some() { -// // let supertrend_vec = supertrend_option.unwrap(); -// // let heatmap_volume_vec = heatmap_volume_option.unwrap(); -// // let heatmap_search_result = heatmap_volume_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |HeatmapVolumeData{heatmap_value, heatmap_level, close_time}|*close_time); -// // let macd_search_result = macd_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaMacd{macd_value, close_time}|close_time); -// // let ema3_result = ema3_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// // let ema10_result = ema10_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// // let ema30_result = ema30_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// // let sma10_result = sma10_1m_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); - -// // if supertrend_vec.last().unwrap().signal.is_some() && heatmap_search_result.is_ok() && macd_search_result.is_ok() && ema3_result.is_ok() && ema10_result.is_ok() && ema30_result.is_ok() && sma10_result.is_ok() { -// // // if supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") -// // // && macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value { -// // // { -// // if ((supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) && current_price <= supertrend_vec[supertrend_vec.len()-2].band_value * 1.0005) -// // || (supertrend_vec.last().unwrap().area.contains("UP") && ema3_1m_vec[ema3_result.unwrap()-1].ema_value < sma10_1m_vec[sma10_result.unwrap()-1].sma_value && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) -// // // && current_price >= ema30_1m_vec[ema30_result.unwrap()].ema_value -// // // && ema10_1m_vec[ema10_result.unwrap()-1].ema_value < ema10_1m_vec[ema10_result.unwrap()].ema_value - -// // // && ema10_1m_vec[ema10_result.unwrap()].ema_value >= ema30_1m_vec[ema30_result.unwrap()].ema_value -// // { -// // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&supertrend_vec.last().unwrap().close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // if k_result.is_ok() && d_result.is_ok() { -// // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value { -// // let heatmap_volume_trunc_vec_option = heatmap_volume_vec.get(heatmap_search_result.unwrap()-11..heatmap_search_result.unwrap()-1); -// // if heatmap_volume_trunc_vec_option.is_some() { -// // let heatmap_volume_trunc_vec = heatmap_volume_trunc_vec_option.unwrap(); -// // let mut heat_value_summation = 0.0; -// // for element in heatmap_volume_trunc_vec { -// // if element.heatmap_level == HeatMapLevel::ExtraHigh { -// // heat_value_summation += 2.0; -// // } else if element.heatmap_level == HeatMapLevel::High { -// // heat_value_summation += 1.5; -// // } else if element.heatmap_level == HeatMapLevel::Medium { -// // heat_value_summation += 1.0; -// // } else if element.heatmap_level == HeatMapLevel::Normal { -// // heat_value_summation += 0.5; -// // } else { -// // heat_value_summation += 0.0; -// // } -// // } -// // if heat_value_summation >= 3.0 { -// // filtered_2nd_symbols.push((symbol, supertrend_vec.last().unwrap().close_time)); -// // } -// // } -// // } -// // } -// // } -// // // } -// // } -// // } -// // // if macd_search_result.is_ok() { -// // // if macd_vec[macd_search_result.unwrap()].macd_value > 0.0 { -// // // //check duplicate records -// // // let mut exists_condition_build = String::from("symbol=\'"); -// // // exists_condition_build.push_str(symbol.as_str()); -// // // exists_condition_build.push_str("\' AND close_time="); -// // // exists_condition_build.push_str(opclo_1m_vec.last().unwrap().close_time.to_string().as_str()); -// // // let exists_condition = Some(exists_condition_build); - -// // // let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; -// // // let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; -// // // let inspect_result_3 = exists_record(&inspect_table_name_3, &exists_condition).await; -// // // let inspect_result_4 = exists_record(&inspect_table_name_4, &exists_condition).await; - -// // // if inspect_result_1 == false && inspect_result_2 == false && inspect_result_3 == false && inspect_result_4 == false { -// // // let mut sum_stoch_rsi30_1m_k = 0.0; -// // // for element in &stoch_rsi30_1m_k_vec { -// // // sum_stoch_rsi30_1m_k += element.stoch_rsi_k_value; -// // // } -// // // let average_stoch_rsi30_1m_k = sum_stoch_rsi30_1m_k / 5.0; - -// // // let ema3_3_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaData{ema_value, close_time}|close_time); -// // // let ema3_2_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); -// // // let ema3_1_result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&EmaData{ema_value, close_time}|close_time); -// // // let ema10_result = ema10_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&EmaData{ema_value, close_time}|close_time); -// // // let sma10_result = sma10_1m_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&SmaData{sma_value, close_time}|close_time); -// // // if ema3_3_result.is_ok() && ema3_2_result.is_ok() && ema3_1_result.is_ok() && ema10_result.is_ok() && sma10_result.is_ok() { -// // // if sma10_1m_vec[sma10_result.unwrap()].sma_value < ema3_1m_vec[ema3_3_result.unwrap()].ema_value { -// // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // // if k_result.is_ok() && k_prev_result.is_ok() { -// // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value -// // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value > 5.0 -// // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value < 80.0 -// // // && stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 96.0 -// // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0 { -// // // if current_price <= opclo_1m_vec[1].opclo_price * ((((opclo_1m_vec[1].high_price / opclo_1m_vec[1].low_price) - 1.0) / 2.0) + 1.0) { -// // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // } -// // // } -// // // } -// // // } - -// // // // if ema10_1m_vec[ema10_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value { -// // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema10_1m_vec[ema10_result.unwrap()].ema_value { -// // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema3_1m_vec[ema3_2_result.unwrap()].ema_value -// // // // && ema3_1m_vec[ema3_2_result.unwrap()].ema_value > ema3_1m_vec[ema3_1_result.unwrap()].ema_value -// // // // { -// // // // if average_stoch_rsi30_1m_k < 80.0 { -// // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let k_prev2_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // // // if k_result.is_ok() && d_result.is_ok() && k_prev_result.is_ok() && k_prev2_result.is_ok() { -// // // // if -// // // // (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) -// // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) > 3.0 -// // // // && stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 96.0 -// // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev2_result.unwrap()].stoch_rsi_k_value) -// // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) < 25.0 -// // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) > 3.0 -// // // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0) -// // // // // (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value > 5.0) && -// // // // // ((stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value <= 80.0) -// // // // // || (((opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0) && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value))) -// // // // { -// // // // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0 { -// // // // // if (opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 -// // // // // { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // // } else { -// // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // if opclo_1m_vec[1].candle_type == "DOWN" && opclo_1m_vec[1].opclo_price >= opclo_1m_vec[2].close_price { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } else if opclo_1m_vec[1].candle_type == "UP" { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // } -// // // // // else { -// // // // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); -// // // // // if result.is_ok() { -// // // // // if rsi3_1m_vec[result.unwrap()].rsi_value < 20.0 && cnt >= 2 && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // // } -// // // // // } - -// // // // // } else { -// // // // // if cnt >= 2 { - -// // // // // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); -// // // // // match result { -// // // // // Ok(T) => { -// // // // // if ema3_1m_vec[T].ema_value > opclo_1m_vec[1].opclo_price { -// // // // // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); -// // // // // match result { -// // // // // Ok(T) => { -// // // // // if rsi3_1m_vec[T].rsi_value < 15.0 { -// // // // // let k_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // // let d_result = stoch_rsi10_1m_d_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); - -// // // // // if k_result.is_ok() && d_result.is_ok() { -// // // // // if stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value <= stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value { -// // // // // if current_price < opclo_1m_vec[1].opclo_price { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // // } -// // // // // } -// // // // // } -// // // // // }, -// // // // // Err(E) => {} -// // // // // } -// // // // // } -// // // // // }, -// // // // // Err(E) => {} -// // // // // } -// // // // // } -// // // // // } -// // // // } -// // // // } else { -// // // // let k_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let k_prev_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let k_prev2_result = stoch_rsi10_1m_k_vec.binary_search_by_key(&opclo_1m_vec[0].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let d_result = stoch_rsi10_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // // // if k_result.is_ok() && d_result.is_ok() && k_prev_result.is_ok() && k_prev2_result.is_ok() { -// // // // if (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) -// // // // && (stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) > 3.0 -// // // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev2_result.unwrap()].stoch_rsi_k_value -// // // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi10_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value -// // // // && stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi10_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value < 30.0 -// // // // && stoch_rsi10_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value < 95.0 -// // // // { -// // // // // if stoch_rsi10_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > 80.0 { -// // // // // if (opclo_1m_vec[1].open_price - opclo_1m_vec[1].close_price).abs() / (opclo_1m_vec[1].high_price - opclo_1m_vec[1].low_price) > 60.0 -// // // // // { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // // } else { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } -// // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // } -// // // // } -// // // // } -// // // // } -// // // // } -// // // // // else { -// // // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // // // // if k_result.is_ok() && k_prev_result.is_ok() { -// // // // // if (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) -// // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value) > 5.0 -// // // // // { -// // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // } - -// // // // // // if ema3_1m_vec[ema3_3_result.unwrap()].ema_value < ema3_1m_vec[ema3_2_result.unwrap()].ema_value { -// // // // // // if opclo_1m_vec[1].candle_type == "DOWN" && opclo_1m_vec[1].open_price > ema3_1m_vec[ema3_2_result.unwrap()].ema_value -// // // // // // && opclo_1m_vec[2].open_price < ema3_1m_vec[ema3_3_result.unwrap()].ema_value -// // // // // // && opclo_1m_vec[2].high_price < ema3_1m_vec[ema3_3_result.unwrap()].ema_value -// // // // // // && opclo_1m_vec[2].candle_type == "UP" { -// // // // // // if (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value < stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) -// // // // // // { -// // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // // } -// // // // // // } -// // // // // // } else if ema3_1m_vec[ema3_3_result.unwrap()].ema_value > ema3_1m_vec[ema3_2_result.unwrap()].ema_value -// // // // // // { -// // // // // // if opclo_1m_vec[1].candle_type == "UP" -// // // // // // && (stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value) { -// // // // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // // // } -// // // // // // } -// // // // // } -// // // // // } -// // // // } -// // // } -// // // } -// // // } -// // // // else if macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value && macd_vec[macd_search_result.unwrap()].macd_value > -3.0{ -// // // // let k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let k_prev_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // // // let d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&opclo_1m_vec[2].close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // // // if k_result.is_ok() && k_prev_result.is_ok() && d_result.is_ok() { -// // // // if stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[k_prev_result.unwrap()].stoch_rsi_k_value -// // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value > stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value -// // // // && stoch_rsi30_1m_k_vec[k_result.unwrap()].stoch_rsi_k_value - stoch_rsi30_1m_d_vec[d_result.unwrap()].stoch_rsi_d_value > 5.0{ -// // // // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // // // } -// // // // } -// // // // } -// // // } - -// // } -// } -// } -// } - -// // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// // if market_cap_index.first().unwrap().negative_buy_signal == 1 || (market_cap_index.first().unwrap().liquidation_signal == 0 && market_cap_index.first().unwrap().market_cap_index <= 20.0 && market_cap_index.first().unwrap().market_cap_index >= 0.0) { -// // let mut rsi3_1m_vec: Vec = Vec::new(); -// // let mut opclo_1m_vec: Vec = Vec::new(); -// // let mut ema3_1m_vec: Vec = Vec::new(); -// // let mut cnt = 0; -// // for symbol in filtered_symbols { -// // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// // let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); - -// // if rsi3_1m_option.is_some() && opclo_1m_option.is_some() && ema3_1m_option.is_some() { -// // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// // opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); - -// // if rsi3_1m_vec.len() >= 3 && opclo_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 3 { -// // opclo_1m_vec.reverse(); -// // opclo_1m_vec.truncate(3); -// // opclo_1m_vec.reverse(); - -// // if opclo_1m_vec.last().unwrap().candle_type == "UP" { -// // cnt = 0; -// // for element in &opclo_1m_vec { -// // if element.candle_type == "DOWN" { -// // cnt += 1; -// // } -// // } - -// // if cnt >= 2 { -// // let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&EmaData{ema_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if ema3_1m_vec[T].ema_value > opclo_1m_vec[1].opclo_price { -// // let result = rsi3_1m_vec.binary_search_by_key(&opclo_1m_vec[1].close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi3_1m_vec[T].rsi_value < 30.0 { -// // if current_price < opclo_1m_vec[1].opclo_price { -// // filtered_2nd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } - -// // } - -// // } -// // } -// // } -// // } else if market_cap_index.first().unwrap().liquidation_signal == 1 && market_cap_index.first().unwrap().market_cap_index < - 10.0 { -// // let mut rsi3_1m_vec: Vec = Vec::new(); -// // let mut rsi10_1m_vec: Vec = Vec::new(); -// // let mut rsi30_1m_vec: Vec = Vec::new(); -// // let mut op_low_1m_vec: Vec = Vec::new(); -// // let mut ema3_1m_vec: Vec = Vec::new(); -// // let mut bb30_1m_vec: Vec = Vec::new(); -// // let mut cnt = 0; -// // for symbol in filtered_symbols { -// // let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// // let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); -// // let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); -// // let op_low_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// // let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); -// // let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); - -// // if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && rsi30_1m_option.is_some() && op_low_1m_option.is_some() && ema3_1m_option.is_some() && bb30_1m_option.is_some() { -// // rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// // rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); -// // rsi30_1m_vec = alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1.clone(); -// // op_low_1m_vec = alldata.rt_price_1m_vec[op_low_1m_option.unwrap()].1.clone(); -// // ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); -// // bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); - -// // if rsi3_1m_vec.len() >= 3 && rsi10_1m_vec.len() >= 3 && rsi30_1m_vec.len() >= 3 && op_low_1m_vec.len() >= 3 && ema3_1m_vec.len() >= 3 && bb30_1m_vec.len() >= 3 { -// // op_low_1m_vec.reverse(); -// // op_low_1m_vec.truncate(5); -// // op_low_1m_vec.reverse(); - -// // if op_low_1m_vec.last().unwrap().candle_type == "DOWN" { -// // cnt = 0; -// // for element in &op_low_1m_vec { -// // if element.candle_type == "DOWN" { -// // cnt += 1; -// // } -// // } - -// // if cnt >= 4 { -// // let result = ema3_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if ema3_1m_vec[T].ema_value > (op_low_1m_vec.last().unwrap().open_price + op_low_1m_vec.last().unwrap().low_price) / 2.0 { -// // let result = rsi3_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi3_1m_vec[T].rsi_value < 10.0 { -// // let result = rsi10_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi10_1m_vec[T].rsi_value < 15.0 { -// // let result = rsi30_1m_vec.binary_search_by_key(&op_low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi30_1m_vec[T].rsi_value < 35.0 { -// // let result = bb30_1m_vec.binary_search_by_key(&op_low_1m_vec.first().unwrap().close_time, |&BollingerBandData{sma, upperband, lowerband, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if bb30_1m_vec[T].lowerband > (op_low_1m_vec.last().unwrap().open_price + op_low_1m_vec.last().unwrap().low_price) / 2.0 { -// // filtered_2nd_symbols.push((symbol, op_low_1m_vec.last().unwrap().close_time)); -// // } -// // }, -// // Err(E) => {}, -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } - -// // } - -// // } -// // } -// // } -// // } - -// insert_pre_suggested_coins(1, &filtered_2nd_symbols, alldata).await; - -// Ok(()) -// } - -// Supertrend UP area에서 이득보기 -// pub async fn execute_strategist_for_test2( -// alldata: &AllData, -// ) -> Result<(), Box> { -// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); -// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); -// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); -// let inspect_table_name_4 = String::from("suggested_coin_list"); - -// let market_cap_index = select_marketcap().await; - -// let mut filtered_symbols: Vec = Vec::new(); - -// filtered_symbols.push(String::from("BTCUSDT")); - -// let current_price = get_current_price(&filtered_symbols.first().unwrap(), &alldata.price_vec) -// .await -// .unwrap(); - -// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// let mut ema3_1m_vec: &Vec = &Vec::new(); -// let mut ema3_30m_vec: &Vec = &Vec::new(); -// let mut ema10_1m_vec: &Vec = &Vec::new(); -// let mut ema30_1m_vec: &Vec = &Vec::new(); -// let mut sma3_1m_vec: &Vec = &Vec::new(); -// let mut sma10_1m_vec: &Vec = &Vec::new(); -// let mut sma3_30m_vec: &Vec = &Vec::new(); -// let mut sma30_1m_vec: &Vec = &Vec::new(); -// let mut rsi3_1m_vec: &Vec = &Vec::new(); -// let mut rsi30_1m_vec: &Vec = &Vec::new(); -// let mut stoch_rsi3_1m_k_vec: &Vec = &Vec::new(); -// let mut stoch_rsi3_1m_d_vec: &Vec = &Vec::new(); -// let mut stoch_rsi30_1m_k_vec: &Vec = &Vec::new(); -// let mut stoch_rsi30_1m_d_vec: &Vec = &Vec::new(); -// let mut rt_price_1m_vec: &Vec = &Vec::new(); -// let mut is_filtering_passed: bool = false; - -// let mut cnt = 0; -// let exists_condition = Some(String::from("used_usdt >= 10.0 AND registerer = 2")); -// let inspect_result_1 = exists_record(&inspect_table_name_1, &exists_condition).await; -// let inspect_result_2 = exists_record(&inspect_table_name_2, &exists_condition).await; -// let inspect_result_4 = exists_record(&inspect_table_name_4, &None).await; -// let mut is_buy_period_30m = false; - -// if inspect_result_1 == false && inspect_result_2 == false && inspect_result_4 == false { -// for symbol in filtered_symbols { -// is_filtering_passed = false; -// let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); -// let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); -// let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); -// let ema30_1m_option = alldata.ema30_1m_data.iter().position(|x| *x.0 == *symbol); -// let sma3_1m_option = alldata.sma3_1m_data.iter().position(|x| *x.0 == *symbol); -// let sma10_1m_option = alldata.sma10_1m_data.iter().position(|x| *x.0 == *symbol); -// let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); -// let sma30_1m_option = alldata.sma30_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi30_1m_option = alldata.rsi30_1m_data.iter().position(|x| *x.0 == *symbol); -// let stoch_rsi3_1m_k_option = alldata -// .stoch_rsi3_1m_3_k_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let stoch_rsi3_1m_d_option = alldata -// .stoch_rsi3_1m_3_d_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let stoch_rsi30_1m_k_option = alldata -// .stoch_rsi30_1m_30_k_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let stoch_rsi30_1m_d_option = alldata -// .stoch_rsi30_1m_30_d_data -// .iter() -// .position(|x| *x.0 == *symbol); -// let rt_price_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); - -// if ema3_1m_option.is_some() -// && ema3_30m_option.is_some() -// && ema10_1m_option.is_some() -// && ema30_1m_option.is_some() -// && sma3_1m_option.is_some() -// && sma10_1m_option.is_some() -// && sma3_30m_option.is_some() -// && sma30_1m_option.is_some() -// && rsi3_1m_option.is_some() -// && rsi30_1m_option.is_some() -// && stoch_rsi3_1m_k_option.is_some() -// && stoch_rsi3_1m_d_option.is_some() -// && stoch_rsi30_1m_k_option.is_some() -// && stoch_rsi30_1m_d_option.is_some() -// && rt_price_1m_option.is_some() -// { -// ema3_1m_vec = &alldata.ema3_1m_data[ema3_1m_option.unwrap()].1; -// ema3_30m_vec = &alldata.ema3_30m_data[ema3_30m_option.unwrap()].1; -// ema10_1m_vec = &alldata.ema10_1m_data[ema10_1m_option.unwrap()].1; -// ema30_1m_vec = &alldata.ema30_1m_data[ema30_1m_option.unwrap()].1; -// sma3_1m_vec = &alldata.sma3_1m_data[sma3_1m_option.unwrap()].1; -// sma10_1m_vec = &alldata.sma10_1m_data[sma10_1m_option.unwrap()].1; -// sma3_30m_vec = &alldata.sma3_30m_data[sma3_30m_option.unwrap()].1; -// sma30_1m_vec = &alldata.sma30_1m_data[sma30_1m_option.unwrap()].1; -// rsi3_1m_vec = &alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1; -// rsi30_1m_vec = &alldata.rsi30_1m_data[rsi30_1m_option.unwrap()].1; -// stoch_rsi3_1m_k_vec = -// &alldata.stoch_rsi3_1m_3_k_data[stoch_rsi3_1m_k_option.unwrap()].1; -// stoch_rsi3_1m_d_vec = -// &alldata.stoch_rsi3_1m_3_d_data[stoch_rsi3_1m_d_option.unwrap()].1; -// stoch_rsi30_1m_k_vec = -// &alldata.stoch_rsi30_1m_30_k_data[stoch_rsi30_1m_k_option.unwrap()].1; -// stoch_rsi30_1m_d_vec = -// &alldata.stoch_rsi30_1m_30_d_data[stoch_rsi30_1m_d_option.unwrap()].1; -// rt_price_1m_vec = &alldata.rt_price_1m_vec[rt_price_1m_option.unwrap()].1; - -// // filtering condition: data are ready -// if ema3_1m_vec.len() >= 3 -// && ema3_30m_vec.len() >= 3 -// && ema10_1m_vec.len() >= 3 -// && ema30_1m_vec.len() >= 3 -// && sma3_1m_vec.len() >= 3 -// && sma10_1m_vec.len() >= 3 -// && sma3_30m_vec.len() >= 3 -// && sma30_1m_vec.len() >= 3 -// && rsi3_1m_vec.len() >= 3 -// && rsi30_1m_vec.len() >= 3 -// && stoch_rsi3_1m_k_vec.len() >= 5 -// && stoch_rsi3_1m_d_vec.len() >= 5 -// && stoch_rsi30_1m_k_vec.len() >= 5 -// && stoch_rsi30_1m_d_vec.len() >= 5 -// && rt_price_1m_vec.len() >= 50 -// { -// is_filtering_passed = true; -// } - -// // // filtering condition: SuperTrend & EMA & SMA -// // if is_filtering_passed == true { -// // let supertrend_option = supertrend(&symbol, &alldata.rt_price_1m_vec, 10, 1.0, false).await; -// // if supertrend_option.is_some() { -// // let supertrend_vec = supertrend_option.unwrap(); -// // let supertrend_result = supertrend_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |SupertrendData{band_value, signal, area, close_time}| *close_time); -// // let ema3_result = ema3_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// // let sma10_result = sma10_1m_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); - -// // if supertrend_vec.last().unwrap().signal.is_some() && ema3_result.is_ok() && sma10_result.is_ok() { -// // if (((supertrend_vec.last().unwrap().signal.as_ref().unwrap().contains("BUY") && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value) && rt_price_1m_vec.last().unwrap().close_price <= supertrend_vec[supertrend_vec.len()-2].band_value * 1.0005) -// // || (supertrend_vec.last().unwrap().area.contains("UP") && ema3_1m_vec[ema3_result.unwrap()-1].ema_value < sma10_1m_vec[sma10_result.unwrap()-1].sma_value && ema3_1m_vec[ema3_result.unwrap()].ema_value > sma10_1m_vec[sma10_result.unwrap()].sma_value)) -// // && sma10_1m_vec[sma10_result.unwrap()-2].sma_value < sma10_1m_vec[sma10_result.unwrap()].sma_value { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } else { is_filtering_passed = false; } -// // } else { is_filtering_passed = false; } -// // } - -// // filtering condition: SuperTrend -// if is_filtering_passed == true { -// let supertrend_option = -// supertrend(&symbol, &alldata.rt_price_1m_vec, 3, 1.0, false).await; -// if supertrend_option.is_some() { -// let supertrend_vec = supertrend_option.unwrap(); -// let supertrend_result = supertrend_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |SupertrendData { -// band_value, -// signal, -// area, -// close_time, -// }| *close_time, -// ); - -// if supertrend_result.is_ok() { -// if supertrend_vec[supertrend_result.unwrap()] -// .signal -// .as_ref() -// .is_some() -// { -// if supertrend_vec[supertrend_result.unwrap()] -// .signal -// .as_ref() -// .unwrap() -// .contains("BUY") -// { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: SMA & EMA -// if is_filtering_passed == true { -// let sma3_1m_result = sma3_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// let sma10_1m_result = sma10_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// let sma30_1m_result = sma30_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// let ema3_1m_result = ema3_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// let ema3_30m_result = ema3_30m_vec.binary_search_by_key( -// &sma3_30m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// let ema10_1m_result = ema10_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// let ema30_1m_result = ema30_1m_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// if sma10_1m_result.is_ok() -// && sma30_1m_result.is_ok() -// && ema3_1m_result.is_ok() -// && ema10_1m_result.is_ok() -// && ema30_1m_result.is_ok() -// && ema3_30m_result.is_ok() -// { -// if sma3_1m_vec[sma3_1m_result.unwrap()].sma_value -// > sma3_1m_vec[sma3_1m_result.unwrap() - 1].sma_value -// && sma3_1m_vec[sma3_1m_result.unwrap()].sma_value -// > sma3_1m_vec[sma3_1m_result.unwrap() - 2].sma_value -// && sma3_1m_vec[sma3_1m_result.unwrap() - 1].sma_value -// > sma3_1m_vec[sma3_1m_result.unwrap() - 2].sma_value -// && sma30_1m_vec[sma30_1m_result.unwrap()].sma_value -// > rt_price_1m_vec.last().unwrap().close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 1].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 2].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 2].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 3].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 3].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 4].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 4].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 5].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 5].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 6].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 6].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 7].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 7].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 8].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 8].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 9].close_price -// && sma30_1m_vec[sma30_1m_result.unwrap() - 9].sma_value -// > rt_price_1m_vec[rt_price_1m_vec.len() - 10].close_price -// // ema10_1m_vec[ema10_1m_result.unwrap()].ema_value > sma10_1m_vec[sma10_1m_result.unwrap()].sma_value -// // ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value <= sma10_1m_vec[sma10_1m_result.unwrap()-1].sma_value -// // (sma10_1m_vec[sma10_1m_result.unwrap()].sma_value - ema10_1m_vec[ema10_1m_result.unwrap()].ema_value).abs() >= (sma10_1m_vec[sma10_1m_result.unwrap()-1].sma_value - ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value).abs() - -// // && ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value < ema10_1m_vec[ema10_1m_result.unwrap()].ema_value -// // && ema10_1m_vec[ema10_1m_result.unwrap()-2].ema_value < ema10_1m_vec[ema10_1m_result.unwrap()-1].ema_value - -// // && sma10_1m_vec[sma10_1m_result.unwrap()].sma_value > ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-1].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-2].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-3].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-4].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-5].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-2].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-1].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-3].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-2].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-4].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-3].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-5].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()-4].ema_value -// // && ema30_1m_vec[ema30_1m_result.unwrap()-5].ema_value < ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// // && rt_price_1m_vec.last().unwrap().close_price > ema30_1m_vec[ema30_1m_result.unwrap()].ema_value -// { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: current price limitation -// // if is_filtering_passed == true { -// // if rt_price_1m_vec[rt_price_1m_vec.len()-2].close_price + ((rt_price_1m_vec[rt_price_1m_vec.len()-2].high_price - rt_price_1m_vec[rt_price_1m_vec.len()-2].low_price) * 0.5) > rt_price_1m_vec.last().unwrap().close_price { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } - -// // filtering condition: Heatmap Volume -// if is_filtering_passed == true { -// let heatmap_volume_option = heatmap_volume( -// &symbol, -// &alldata.rt_price_1m_vec, -// 30, -// 30, -// 4.0, -// 2.5, -// 1.0, -// -0.5, -// ) -// .await; -// if heatmap_volume_option.is_some() { -// let heatmap_volume_vec = heatmap_volume_option.unwrap(); -// let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( -// &rt_price_1m_vec.last().unwrap().close_time, -// |HeatmapVolumeData { -// heatmap_value, -// heatmap_level, -// close_time, -// }| *close_time, -// ); -// if heatmap_search_result.is_ok() { -// let heatmap_volume_trunc_vec_option = heatmap_volume_vec.get( -// heatmap_search_result.unwrap() - 11 -// ..heatmap_search_result.unwrap() - 1, -// ); -// if heatmap_volume_trunc_vec_option.is_some() { -// let heatmap_volume_trunc_vec = -// heatmap_volume_trunc_vec_option.unwrap(); -// let mut heat_value_summation = 0.0; -// for element in heatmap_volume_trunc_vec { -// if element.heatmap_level == HeatMapLevel::ExtraHigh { -// heat_value_summation += 2.0; -// } else if element.heatmap_level == HeatMapLevel::High { -// heat_value_summation += 1.5; -// } else if element.heatmap_level == HeatMapLevel::Medium { -// heat_value_summation += 1.0; -// } else if element.heatmap_level == HeatMapLevel::Normal { -// heat_value_summation += 0.5; -// } else { -// heat_value_summation += 0.0; -// } -// } -// if heat_value_summation >= 1.5 { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // filtering condition: Stoch RSI -// // if is_filtering_passed == true { -// // // let sample_length: usize = 5; -// // // stoch_rsi10_1m_k_vec.reverse(); -// // // stoch_rsi10_1m_k_vec.truncate(5); -// // // stoch_rsi10_1m_k_vec.reverse(); -// // // stoch_rsi10_1m_d_vec.reverse(); -// // // stoch_rsi10_1m_d_vec.truncate(5); -// // // stoch_rsi10_1m_d_vec.reverse(); -// // let rsi3_k_result = stoch_rsi3_1m_k_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // let rsi3_d_result = stoch_rsi3_1m_d_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // let rsi30_k_result = stoch_rsi30_1m_k_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiKData{stoch_rsi_k_value, close_time}|close_time); -// // let rsi30_d_result = stoch_rsi30_1m_d_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&StochRsiDData{stoch_rsi_d_value, close_time}|close_time); -// // if rsi30_k_result.is_ok() && rsi30_d_result.is_ok() && rsi3_k_result.is_ok() && rsi3_d_result.is_ok() { -// // if -// // // stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value <= 80.0 || stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value <= 80.0 -// // // (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi3_1m_d_vec[rsi3_d_result.unwrap()].stoch_rsi_d_value) -// // (stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()-1].stoch_rsi_k_value -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) - -// // // (stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value -// // // && stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value > stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value -// // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) -// // // || -// // || (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= 60.0 -// // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-2].stoch_rsi_k_value >= stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value -// // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi3_1m_d_vec[rsi3_d_result.unwrap()-1].stoch_rsi_d_value -// // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()-1].stoch_rsi_k_value <= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()-1].stoch_rsi_d_value) -// // // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) -// // // || (stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 -// // // && stoch_rsi3_1m_k_vec[rsi3_k_result.unwrap()].stoch_rsi_k_value == 100.0 -// // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value >= stoch_rsi30_1m_d_vec[rsi30_d_result.unwrap()].stoch_rsi_d_value -// // // && stoch_rsi30_1m_k_vec[rsi30_k_result.unwrap()].stoch_rsi_k_value < 80.0) -// // { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } else { is_filtering_passed = false; } -// // } - -// // // filtering condition: MACD -// // if is_filtering_passed == true { -// // let macd_vec = ema_macd(&ema3_1m_vec, &ema10_1m_vec, 10).await?; -// // let macd_search_result = macd_vec.binary_search_by_key(&rt_price_1m_vec.last().unwrap().close_time, |&EmaMacd{macd_value, close_time}|close_time); - -// // if macd_search_result.is_ok() { -// // if macd_vec[macd_search_result.unwrap()].macd_value > macd_vec[macd_search_result.unwrap()-1].macd_value { -// // is_filtering_passed = true; -// // } else { is_filtering_passed = false; } -// // } else { is_filtering_passed = false; } -// // } - -// // filtering condition: Ratio between amplitude and body of candles -// if is_filtering_passed == true { -// let sample_length: usize = 5; // 5 candle samsples -// let rt_price_1m_partial_vec_option = rt_price_1m_vec -// .get(rt_price_1m_vec.len() - sample_length - 1..rt_price_1m_vec.len() - 1); -// if rt_price_1m_partial_vec_option.is_some() { -// let rt_price_1m_partial_vec = rt_price_1m_partial_vec_option.unwrap(); - -// let mut sum_ratio_amp_body = 0.0; -// for element in rt_price_1m_partial_vec { -// sum_ratio_amp_body += (element.close_price - element.open_price).abs() -// / (element.high_price - element.low_price); -// } -// let average_ratio_amp_body = sum_ratio_amp_body / sample_length as f64; -// if average_ratio_amp_body > 0.3 { -// is_filtering_passed = true; -// } else { -// is_filtering_passed = false; -// } -// } else { -// is_filtering_passed = false; -// } -// } - -// // check all filterings are passed -// if is_filtering_passed == true { -// filtered_2nd_symbols.push((symbol, rt_price_1m_vec.last().unwrap().close_time)); -// } -// } -// } -// } - -// insert_pre_suggested_coins(2, &filtered_2nd_symbols, alldata).await; -// Ok(()) -// } - -// pub async fn strategist_001 (alldata: &AllData) -> Result<(), Box> { -// // [strategist_001 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) -// // 3. 2nd filtering symbols (opclo_30m price at the previous candle < bb_sma30_30m lowerband) -// // 4. insert or update record into [strategist_001_table] -// // 5. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] - -// // 1. retrieve all usdttrade symbols -// let signal_decision = select_signal_decision().await; - -// // 3. 1st filtering symbols: 5 samples of candle 30m has 4 DOWN candles at least && the latest candle 30m < SMA3 -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut sma3_30m_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// let mut cnt = 0; -// for symbol in &alldata.valid_symbol_vec { - -// let opclo_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == *symbol); -// let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); - -// // read 1d csv file & bollingerband sma30 csv file -// if opclo_30m_option.is_some() & sma3_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()].1.clone(); -// sma3_30m_vec = alldata.sma3_30m_data[sma3_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 && sma3_30m_vec.len() >= 1 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); -// opclo_30m_vec.reverse(); - -// cnt = 0; -// for element in &opclo_30m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 4 { -// let result = sma3_30m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&SmaData{sma_value, close_time}|close_time); -// match result { -// Ok(T) => { -// if sma3_30m_vec[T].sma_value > opclo_30m_vec.last().unwrap().opclo_price { -// filtered_1st_symbols.push(symbol.clone()); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } -// } - -// // 4. 2nd filtering symbols: 30m RSI 3 < 15, 30m RSI 10 < 25 -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for symbol in filtered_1st_symbols { - -// let rsi3_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == *symbol); - -// if rsi3_option.is_some() && rsi10_option.is_some() && opclo_30m_option.is_some() { -// rsi3_vec = alldata.rsi3_30m_data[rsi3_option.unwrap()].1.clone(); -// rsi10_vec = alldata.rsi10_30m_data[rsi10_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()].1.clone(); - -// if rsi3_vec.len() >= 1 && rsi10_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// let result = rsi3_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// match result { -// Ok(T) => { -// if rsi3_vec[T].rsi_value < 15.0 { -// let result = rsi10_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// match result { -// Ok(T) => { -// if rsi10_vec[T].rsi_value < 25.0 { -// filtered_2nd_symbols.push(symbol); -// } -// }, -// Err(E) => {} -// } -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// // 3. 3rd filtering symbols: 5 samples of candle 1m has 4 DOWN candles at least && the latest candle 1m < EMA3 -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut ema3_1m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// let mut cnt = 0; -// for symbol in filtered_2nd_symbols { - -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); - -// // read 1d csv file & bollingerband sma30 csv file -// if opclo_1m_option.is_some() & ema3_1m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); - -// if opclo_1m_vec.len() >= 5 && ema3_1m_vec.len() >= 1 { -// opclo_1m_vec.reverse(); -// opclo_1m_vec.truncate(5); -// opclo_1m_vec.reverse(); - -// cnt = 0; -// for element in &opclo_1m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 4 { -// let result = ema3_1m_vec.binary_search_by_key(&opclo_1m_vec.last().unwrap().close_time, |&EmaData{ema_value, close_time}|close_time); -// match result { -// Ok(T) => { -// if ema3_1m_vec[T].ema_value > opclo_1m_vec.last().unwrap().opclo_price { -// filtered_3rd_symbols.push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } -// } - -// // // 2. 2nd filtering symbols: candle 1m price avg < candle 30m price avg -// // let mut opclo_1m_vec: Vec = Vec::new(); -// // let mut opclo_1m_price_avg = 0.0; -// // let mut opclo_30m_vec: Vec = Vec::new(); -// // let mut opclo_30m_price_avg = 0.0; -// // let mut filtered_2nd_symbols: Vec = Vec::new(); -// // for element in filtered_1st_symbols { -// // // initialize avgs -// // opclo_1m_price_avg = 0.0; -// // opclo_30m_price_avg = 0.0; - -// // let opclo_1m_result = read_price_into_vector("1m", &element).await; -// // let opclo_30m_result = read_price_into_vector("30m", &element).await; - -// // // read 1d csv file -// // if opclo_1m_result.is_ok() && opclo_30m_result.is_ok() { -// // let opclo_1m_option = opclo_1m_result?; -// // let opclo_30m_option = opclo_30m_result?; - -// // if opclo_1m_option.is_some() && opclo_30m_option.is_some() { -// // opclo_1m_vec = opclo_1m_option.unwrap(); -// // opclo_30m_vec = opclo_30m_option.unwrap(); - -// // if opclo_1m_vec.len() >= 10 && opclo_30m_vec.len() >= 4 { -// // opclo_1m_vec.reverse(); -// // opclo_1m_vec.split_off(10); -// // opclo_30m_vec.reverse(); -// // opclo_30m_vec.split_off(4); - -// // // calculate opclo 1m price average -// // for element in &opclo_1m_vec { -// // opclo_1m_price_avg += element.opclo_price; -// // } -// // opclo_1m_price_avg /= opclo_1m_vec.len() as f64; - -// // // calculate opclo 30m price average -// // for element in &opclo_30m_vec { -// // opclo_30m_price_avg += element.opclo_price; -// // } -// // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // // campare both prices -// // if opclo_1m_price_avg < opclo_30m_price_avg * 0.98 { -// // filtered_2nd_symbols.push(element); -// // } -// // } -// // } -// // } -// // } - -// // // 3. 2nd filtering symbols: 85% of BB SMA10 MA price > candle 1d price yesterday avg -// // let mut opclo_1d_vec: Vec = Vec::new(); -// // let mut read_bb_vec: Vec = Vec::new(); -// // let mut filtered_2nd_symbols: Vec = Vec::new(); -// // for element in filtered_1st_symbols { - -// // let opclo_1d_result = read_price_into_vector("1d", &element).await; -// // let read_bb_result = read_bb_into_vector("sma10", "1d", &element).await; - -// // // read 1d csv file & bollingerband sma30 csv file -// // if opclo_1d_result.is_ok() & read_bb_result.is_ok() { -// // let opclo_1d_option = opclo_1d_result?; -// // let read_bb_option = read_bb_result?; -// // if opclo_1d_option.is_some() && read_bb_option.is_some() { -// // opclo_1d_vec = opclo_1d_option.unwrap(); -// // read_bb_vec = read_bb_option.unwrap(); - -// // if opclo_1d_vec.len() > 1 && read_bb_vec.len() > 1 { -// // opclo_1d_vec.pop(); -// // read_bb_vec.pop(); -// // let result = read_bb_vec.binary_search_by_key(&opclo_1d_vec.last().unwrap().close_time, |&BBData{ma_price, upperband, lowerband, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if read_bb_vec[T].ma_price > opclo_1d_vec.last().unwrap().opclo_price { -// // filtered_2nd_symbols.push(element); -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // } -// // } -// // } - -// // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price -// // let mut read_bb_vec: Vec = Vec::new(); -// // let mut opclo_30m_vec: Vec = Vec::new(); -// // let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) -// // for element in filtered_2nd_symbols { - -// // // read 30m csv file & bollingerband sma30 csv file -// // let opclo_30m_result = read_price_into_vector("30m", &element).await; -// // let bb_result = read_bb_into_vector("sma30", "30m", &element).await; - -// // if opclo_30m_result.is_ok() && bb_result.is_ok() { -// // let opclo_30m_option = opclo_30m_result?; -// // let read_bb_option = bb_result?; -// // if opclo_30m_option.is_some() && read_bb_option.is_some() { -// // opclo_30m_vec = opclo_30m_option.unwrap(); -// // read_bb_vec = read_bb_option.unwrap(); - -// // // 2nd filtering symbols -// // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&BBData{ma_price, upperband, lowerband, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().opclo_price { -// // filtered_3rd_symbols.push((element, read_bb_vec[T].close_time)); -// // } -// // }, -// // Err(E) => {} -// // } -// // } - -// // } -// // } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(1, &filtered_3rd_symbols, alldata).await; -// // println!("strategist_001 완료"); -// Ok(()) -// } - -// pub async fn strategist_002( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_002 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) -// // 3. 2nd filtering symbols (sma30 price > opclo_30m price, check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample) -// // 4. if the two conditions are right, upload the filtered symbols into [strategist_002_table] -// // 5. monitor price of symbols in [strategist_002_table], and upload them into [suggested_coin_list] when price seems to become high -// let signal_decision = select_signal_decision().await; - -// if signal_decision[0].decision.contains("UP") { -// // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut opclo_1m_price_avg = 0.0; -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_price_avg = 0.0; -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for symbol in &alldata.valid_symbol_vec { -// // initialize avgs -// opclo_1m_price_avg = 0.0; -// opclo_30m_price_avg = 0.0; - -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// // read 1d csv file -// if opclo_1m_option.is_some() && opclo_30m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if opclo_1m_vec.len() >= 10 && opclo_30m_vec.len() >= 4 { -// opclo_1m_vec.reverse(); -// opclo_1m_vec.split_off(10); -// opclo_30m_vec.reverse(); -// opclo_30m_vec.split_off(4); - -// // calculate opclo 1m price average -// for element in &opclo_1m_vec { -// opclo_1m_price_avg += element.opclo_price; -// } -// opclo_1m_price_avg /= opclo_1m_vec.len() as f64; - -// // calculate opclo 30m price average -// for element in &opclo_30m_vec { -// opclo_30m_price_avg += element.opclo_price; -// } -// opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // campare both prices -// if opclo_1m_price_avg < opclo_30m_price_avg * 0.97 { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// } -// } - -// // 3. 2nd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.2 of the middle sample -// let mut sma10_30m_vec: Vec = Vec::new(); -// let mut rsi30_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_1st_symbols { -// // read 30m opclo, SMA30, rsi30 csv file -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let sma10_30m_option = alldata.sma10_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi30_30m_option = alldata.rsi30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() -// && sma10_30m_option.is_some() -// && rsi30_30m_option.is_some() -// { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// sma10_30m_vec = alldata.sma10_30m_data[sma10_30m_option.unwrap()].1.clone(); -// rsi30_30m_vec = alldata.rsi30_30m_data[rsi30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 && sma10_30m_vec.len() >= 5 && rsi30_30m_vec.len() >= 5 -// { -// opclo_30m_vec.pop(); -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); - -// // 2nd filtering symbols -// let result = sma10_30m_vec.binary_search_by_key( -// &opclo_30m_vec.first().unwrap().close_time, -// |SmaData { -// sma_value, -// close_time, -// }| *close_time, -// ); -// match result { -// Ok(T) => { -// if sma10_30m_vec[T].sma_value > opclo_30m_vec[0].opclo_price { -// let index_of_min: Option = opclo_30m_vec -// .iter() -// .enumerate() -// .min_by(|(_, a), (_, b)| { -// a.opclo_price -// .partial_cmp(&b.opclo_price) -// .expect("Nan was forbidden.") -// }) -// .map(|(index, _)| index); - -// // index 1 means the middle index of 5 element in a vec, assuming the latest price is included but removed in the vec. -// if index_of_min == Some(0) { -// let result = rsi30_30m_vec.binary_search_by_key( -// &opclo_30m_vec[0].close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi30_30m_vec[T].rsi_value < 20.0 { -// filtered_2nd_symbols.push(( -// symbol, -// opclo_30m_vec.last().unwrap().close_time, -// )); -// } -// } -// Err(e) => {} -// } -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(2, &filtered_2nd_symbols, alldata).await; -// } -// // println!("strategist_002 완료"); -// Ok(()) -// } - -// pub async fn strategist_003( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_003 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) -// // 3. 2nd filtering symbols (opclo_30m price at the previous candle < bb_sma30_30m lowerband) -// // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI30 is lower than 0.25 of the middle sample) -// // 5. if the two conditions are right, upload the filtered symbols into [suggested_coin_list] -// let signal_decision = select_signal_decision().await; - -// if signal_decision[0].decision.contains("UP") { -// // 1. retrieve all usdttrade symbols - -// // 2. 1st filtering symbols: yesterday and today's candle 1d opclo price < EMA10 -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut ema10_1d_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for symbol in &alldata.valid_symbol_vec { -// // read 1d csv file -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1d_option = alldata.rsi10_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && ema10_1d_option.is_some() && rsi10_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// ema10_1d_vec = alldata.ema10_1d_data[ema10_1d_option.unwrap()].1.clone(); -// rsi10_vec = alldata.rsi10_1d_data[rsi10_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && ema10_1d_vec.len() >= 2 && rsi10_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.split_off(2); -// ema10_1d_vec.reverse(); -// ema10_1d_vec.split_off(2); -// rsi10_vec.reverse(); -// rsi10_vec.split_off(2); - -// let result = ema10_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |EmaData { -// ema_value, -// close_time, -// }| *close_time, -// ); -// match result { -// Ok(T) => { -// if ema10_1d_vec[T].ema_value > opclo_1d_vec[1].opclo_price { -// let result = rsi10_vec.binary_search_by_key( -// &opclo_1d_vec[1].close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_vec[T].rsi_value < 20.0 { -// let result = ema10_1d_vec.binary_search_by_key(&opclo_1d_vec.first().unwrap().close_time, |EmaData{ema_value, close_time}| *close_time); -// match result { -// Ok(T) => { -// if ema10_1d_vec[T].ema_value -// > opclo_1d_vec[0].opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(e) => {} -// } -// } -// } -// Err(e) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); // (symbol, closetime) -// for symbol in filtered_1st_symbols { -// // read 30m csv file -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && bb30_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// read_bb_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 1 && read_bb_vec.len() >= 1 { -// let result = read_bb_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().opclo_price -// { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 4. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample -// let mut low_1m_vec: Vec = Vec::new(); -// let mut bb30_1m_vec: Vec = Vec::new(); -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_2nd_symbols { -// let low_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); - -// if low_1m_option.is_some() -// && bb30_1m_option.is_some() -// && rsi3_1m_option.is_some() -// && rsi10_1m_option.is_some() -// { -// low_1m_vec = alldata.rt_price_1m_vec[low_1m_option.unwrap()].1.clone(); -// bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); -// rsi3_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); - -// if low_1m_vec.len() >= 1 -// && bb30_1m_vec.len() >= 1 -// && rsi3_vec.len() >= 1 -// && rsi10_vec.len() >= 1 -// { -// let result = bb30_1m_vec.binary_search_by_key( -// &low_1m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1m_vec[T].lowerband > low_1m_vec.last().unwrap().low_price { -// let result = rsi3_vec.binary_search_by_key( -// &low_1m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_vec[T].rsi_value < 15.0 { -// let result = rsi10_vec.binary_search_by_key(&low_1m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// match result { -// Ok(T) => { -// if rsi10_vec[T].rsi_value < 20.0 { -// filtered_3rd_symbols.push(( -// symbol, -// low_1m_vec.last().unwrap().close_time, -// )); -// } -// } -// Err(e) => {} -// } -// } -// } -// Err(e) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(3, &filtered_3rd_symbols, alldata).await; -// } - -// // println!("strategist_003 완료"); -// Ok(()) -// } - -// pub async fn strategist_004( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_004 procedure] -// // 1st filtering: opclo_30m price < bb30_30m lowerband -// // 2nd filtering: opclo_1m price < bb30_1m lowerband -// // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 - -// let signal_decision = select_signal_decision().await; -// if signal_decision[0].decision.contains("UP") { -// // 1st filtering: (opclo_30m price < bb30 lowerband) -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut bb30_30m_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for symbol in &alldata.valid_symbol_vec { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && bb30_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 1 && bb30_30m_vec.len() >= 1 { -// let result = bb30_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_30m_vec[T].lowerband > opclo_30m_vec.last().unwrap().opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 2nd filtering: (opclo_1m price < bb30_1m lowerband) -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut bb30_1m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for symbol in filtered_1st_symbols { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1m_option.is_some() && bb30_1m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); - -// if opclo_1m_vec.len() >= 1 && bb30_1m_vec.len() >= 1 { -// let result = bb30_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1m_vec[T].lowerband > opclo_1m_vec.last().unwrap().opclo_price { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut rsi3_1m_vec: Vec = Vec::new(); -// let mut rsi10_1m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_2nd_symbols { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1m_option.is_some() && rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); -// } - -// if opclo_1m_vec.len() >= 1 && rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { -// let result = rsi3_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_1m_vec[T].rsi_value < 10.0 { -// let result = rsi10_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_1m_vec[T].rsi_value < 25.0 { -// filtered_3rd_symbols.push(( -// symbol, -// opclo_1m_vec.last().unwrap().close_time, -// )); -// } -// } -// Err(e) => {} -// } -// } -// } -// Err(e) => {} -// } -// } -// } -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(4, &filtered_3rd_symbols, alldata).await; -// } -// // println!("strategist_004 완료"); -// Ok(()) -// } - -// // for ultra-short -// pub async fn strategist_005( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_005 procedure] -// // 1st filtering: sampling the least 1m 5 tickers, check DOWN ticker at least 2, check the quote vol of the last ticker > 2X the counterpart of the previous 2 tickers. -// // 2nd filtering: opclo_1m price < sma3_1m -// // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 -// // 4th filtering: check the latest and previous 30m candles are UPs - -// let signal_decision = select_signal_decision().await; -// if signal_decision[0].decision.contains("UP") { -// // 1st filtering: sampling the least 1m 5 tickers, check DOWN ticker at least 2, check the quote vol of the last ticker > 2X the counterpart of the previous 2 tickers. -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); - -// if opclo_1m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// if opclo_1m_vec.len() >= 5 { -// opclo_1m_vec.reverse(); -// opclo_1m_vec.truncate(5); -// opclo_1m_vec.reverse(); - -// let mut cnt = 0; -// for element in &opclo_1m_vec { -// if element.candle_type == "DOWN" -// && element.opclo_price > opclo_1m_vec.last().unwrap().opclo_price -// { -// cnt += 1; -// } -// } - -// if cnt >= 2 && opclo_1m_vec.last().unwrap().candle_type == "DOWN" { -// let mut vec_cmp = opclo_1m_vec.to_vec(); -// vec_cmp.pop(); -// vec_cmp.reverse(); -// let mut vec_iter = vec_cmp.iter(); - -// for _ in 0..2 { -// let temp = vec_iter.next(); -// if temp.is_some() { -// if (temp.unwrap().quote_asset_volume != 0.0) -// && (temp.unwrap().quote_asset_volume * 2.0 -// < opclo_1m_vec.last().unwrap().quote_asset_volume) -// { -// filtered_1st_symbols.push(symbol.clone()); -// break; -// } -// } -// } -// } -// } -// } -// } - -// // 2nd filtering: opclo_1m price < sma3_1m -// let mut sma3_1m_vec: Vec = Vec::new(); -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for symbol in filtered_1st_symbols { -// let sma3_1m_option = alldata.sma3_1m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); - -// if sma3_1m_option.is_some() && opclo_1m_option.is_some() { -// sma3_1m_vec = alldata.sma3_1m_data[sma3_1m_option.unwrap()].1.clone(); -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); - -// if sma3_1m_vec.len() >= 1 && opclo_1m_vec.len() >= 1 { -// let result = sma3_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma3_1m_vec[T].sma_value > opclo_1m_vec.last().unwrap().opclo_price { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 3rd filtering: RSI3_1m < 10, RSI10_1m < 25 -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut rsi3_1m_vec: Vec = Vec::new(); -// let mut rsi10_1m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for symbol in filtered_2nd_symbols { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1m_option.is_some() && rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); - -// if opclo_1m_vec.len() >= 1 && rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { -// let result = rsi3_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_1m_vec[T].rsi_value < 10.0 { -// let result = rsi10_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_1m_vec[T].rsi_value < 25.0 { -// filtered_3rd_symbols.push(symbol); -// } -// } -// Err(e) => {} -// } -// } -// } -// Err(e) => {} -// } -// } -// } -// } - -// // 4th filtering: check the latest and previous 30m candles are UPs -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_3rd_symbols { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && opclo_1m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 2 && opclo_1m_vec.len() >= 1 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(2); -// opclo_30m_vec.reverse(); - -// if opclo_30m_vec.first().unwrap().candle_type == "UP" -// && opclo_30m_vec.last().unwrap().candle_type == "UP" -// { -// filtered_4th_symbols -// .push((symbol, opclo_1m_vec.last().unwrap().close_time)); -// } -// } -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(5, &filtered_4th_symbols, alldata).await; -// } -// // println!("strategist_005 완료"); -// Ok(()) -// } - -// pub async fn strategist_006( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_006 procedure] -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 3, the latest opclo_30m < SMA3_30m -// // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 -// // 4th filtering: the latest 30m quote vol > 2X the previous quote vol - -// // 1st filtering symbols: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut bb30_1d_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// let mut current_price: Option; -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && bb30_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.truncate(2); -// opclo_1d_vec.reverse(); -// bb30_1d_vec.reverse(); -// bb30_1d_vec.truncate(2); -// bb30_1d_vec.reverse(); - -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.first().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// current_price = get_current_price(&symbol, &alldata.price_vec).await; - -// if current_price.is_some() { -// if current_price.unwrap().is_normal() { -// if (bb30_1d_vec[T].upperband -// > opclo_1d_vec.first().unwrap().opclo_price) -// && (opclo_1d_vec.first().unwrap().opclo_price -// > current_price.unwrap()) -// { -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1d_vec[T].upperband -// > opclo_1d_vec.last().unwrap().opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 3, the latest opclo_30m < SMA3_30m -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut sma3_30m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// let mut cnt = 0; -// for symbol in filtered_1st_symbols { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let sma3_30m_option = alldata.sma3_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && sma3_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// sma3_30m_vec = alldata.sma3_30m_data[sma3_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 && sma3_30m_vec.len() >= 1 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); -// opclo_30m_vec.reverse(); - -// cnt = 0; -// for element in &opclo_30m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 3 { -// let result = sma3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma3_30m_vec[T].sma_value > opclo_30m_vec.last().unwrap().opclo_price -// { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } - -// // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 -// let mut rsi3_30m_vec: Vec = Vec::new(); -// let mut rsi10_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for symbol in filtered_2nd_symbols { -// let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); -// rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// let result = rsi3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_30m_vec[T].rsi_value < 15.0 { -// let result = rsi10_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_30m_vec[T].rsi_value < 35.0 { -// filtered_3rd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 4th filtering: the latest 30m quote vol > 2X the previous quote vol -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_3rd_symbols { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if opclo_30m_vec.len() >= 2 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(2); -// opclo_30m_vec.reverse(); - -// if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume -// < opclo_30m_vec.last().unwrap().quote_asset_volume -// && opclo_30m_vec.last().unwrap().candle_type == "DOWN" -// { -// filtered_4th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); -// } -// } -// } -// } - -// // 7. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(6, &filtered_4th_symbols, alldata).await; -// Ok(()) -// } - -// pub async fn strategist_006 () -> Result<(), Box> { -// // [strategist_006 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (low_price_1m price avg < low_price_30m price avg) -// // 3. 2nd filtering symbols (low_price_30m price at the previous candle < bb_sma30_30m lowerband) -// // 4. insert [pre_suggested_coin_list] - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut low_price_1m_vec: Vec = Vec::new(); -// let mut low_price_1m_avg = 0.0; -// let mut low_price_30m_vec: Vec = Vec::new(); -// let mut low_price_30m_avg = 0.0; - -// // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// low_price_1m_avg = 0.0; -// low_price_30m_avg = 0.0; - -// // read 1m csv file -// low_price_1m_vec = read_low_price_into_vector("1m", &element.symbol).await?; - -// // calculate opclo 1m price average -// for element in &low_price_1m_vec { -// low_price_1m_avg += element.price; -// } -// low_price_1m_avg /= low_price_1m_vec.len() as f64; - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element.symbol).await?; - -// // calculate opclo 30m price average -// for element in &low_price_30m_vec { -// low_price_30m_avg += element.price; -// } -// low_price_30m_avg /= low_price_30m_vec.len() as f64; - -// // campare both prices -// if low_price_1m_avg < low_price_30m_avg { -// filtered_1st_symbols.push(element.symbol); -// } -// } - -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price -// for element in filtered_1st_symbols { - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element).await?; - -// // read bollingerband sma30 csv file -// read_bb_vec = read_bb_into_vector("sma30", "30m", &element).await?; - -// // 2nd filtering symbols -// low_price_30m_vec.pop(); -// let result = read_bb_vec.binary_search_by_key(&low_price_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband > low_price_30m_vec.last().unwrap().price { -// filtered_2nd_symbols.push((element, read_bb_vec[T].server_epoch)); -// } -// }, -// Err(E) => {} -// } - -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(6, &filtered_2nd_symbols).await; - -// println!("strategist_006 완료"); -// Ok(()) -// } - -// pub async fn strategist_007 () -> Result<(), Box> { -// // [strategist_007 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (low_price_1m avg < low_price_30m price avg) -// // 3. 2nd filtering symbols (sma30 price > low_price_30m, check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample) -// // 4. insert [pre_suggested_coin_list] - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut low_price_1m_vec: Vec = Vec::new(); -// let mut low_price_1m_avg = 0.0; -// let mut low_price_30m_vec: Vec = Vec::new(); -// let mut low_price_30m_avg = 0.0; - -// // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// low_price_1m_avg = 0.0; -// low_price_30m_avg = 0.0; - -// // read 1m csv file -// low_price_1m_vec = read_low_price_into_vector("1m", &element.symbol).await?; - -// // calculate opclo 1m price average -// for element in &low_price_1m_vec { -// low_price_1m_avg += element.price; -// } -// low_price_1m_avg /= low_price_1m_vec.len() as f64; - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element.symbol).await?; - -// // calculate opclo 30m price average -// for element in &low_price_30m_vec { -// low_price_30m_avg += element.price; -// } -// low_price_30m_avg /= low_price_30m_vec.len() as f64; - -// // campare both prices -// if low_price_1m_avg < low_price_30m_avg { -// filtered_1st_symbols.push(element.symbol); -// } -// } - -// let mut sma30_30m_vec: Vec = Vec::new(); -// let mut rsi30_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 2nd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample -// for element in filtered_1st_symbols { - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element).await?; -// low_price_30m_vec.pop(); -// low_price_30m_vec.reverse(); -// low_price_30m_vec.truncate(5); - -// // read SMA30 csv file -// sma30_30m_vec = read_ma_into_vector(&MA::Sma, 30, "30m", &element).await?; - -// // read rsi30 csv file -// rsi30_vec = read_rsi_into_vector(30, "30m", &element).await?; - -// if low_price_30m_vec.len() == 5 { - -// // 2nd filtering symbols -// let result = sma30_30m_vec.binary_search_by_key(&low_price_30m_vec.first().unwrap().server_epoch, |MaData{price, server_epoch}| *server_epoch); -// match result { -// Ok(T) => { - -// if sma30_30m_vec[T].price > low_price_30m_vec[0].price { - -// let index_of_min: Option = low_price_30m_vec -// .iter() -// .enumerate() -// .min_by(|(_, a), (_, b)| a.price.partial_cmp(&b.price).expect("Nan was forbidden.")) -// .map(|(index, _)| index); - -// // index 1 means the middle index of 5 element in a vec, assuming the latest price is included but removed in the vec. -// if index_of_min == Some(1) { -// let result = rsi30_vec.binary_search_by_key(&low_price_30m_vec[1].server_epoch, |&RsiData{rsi_value, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if rsi30_vec[T].rsi_value < 0.3 { -// filtered_2nd_symbols.push((element, low_price_30m_vec.first().unwrap().server_epoch)); -// } -// }, -// Err(e) => {} -// } -// } -// } -// }, -// Err(E) => {} -// } -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(7, &filtered_2nd_symbols).await; - -// println!("strategist_007 완료"); -// Ok(()) -// } - -// pub async fn strategist_008 () -> Result<(), Box> { -// // [strategist_008 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (low_price_1m avg < low_price_30m avg) -// // 3. 2nd filtering symbols (low_price_30m at the previous candle < bb_sma30_30m lowerband) -// // 4. insert [pre_suggested_coin_list] - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut low_price_1m_vec: Vec = Vec::new(); -// let mut low_price_1m_avg = 0.0; -// let mut low_price_30m_vec: Vec = Vec::new(); -// let mut low_price_30m_avg = 0.0; - -// // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// low_price_1m_avg = 0.0; -// low_price_30m_avg = 0.0; - -// // read 1m csv file -// low_price_1m_vec = read_low_price_into_vector("1m", &element.symbol).await?; - -// // calculate opclo 1m price average -// for element in &low_price_1m_vec { -// low_price_1m_avg += element.price; -// } -// low_price_1m_avg /= low_price_1m_vec.len() as f64; - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element.symbol).await?; - -// // calculate opclo 30m price average -// for element in &low_price_30m_vec { -// low_price_30m_avg += element.price; -// } -// low_price_30m_avg /= low_price_30m_vec.len() as f64; - -// // campare both prices -// if low_price_1m_avg < low_price_30m_avg { -// filtered_1st_symbols.push(element.symbol); -// } -// } - -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m price -// for element in filtered_1st_symbols { - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element).await?; - -// // read bollingerband sma30 csv file -// read_bb_vec = read_bb_into_vector("sma30", "30m", &element).await?; - -// // 2nd filtering symbols -// low_price_30m_vec.pop(); -// let result = read_bb_vec.binary_search_by_key(&low_price_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband > low_price_30m_vec.last().unwrap().price { -// filtered_2nd_symbols.push((element, read_bb_vec[T].server_epoch)); -// } -// }, -// Err(E) => {} -// } - -// } - -// let mut sma30_30m_vec: Vec = Vec::new(); -// let mut rsi30_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 4. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price of SMA30 is the lowest price and then check if RSI30 is lower than 0.3 of the middle sample -// for element in filtered_2nd_symbols { - -// // read 30m csv file -// low_price_30m_vec = read_low_price_into_vector("30m", &element.0).await?; -// low_price_30m_vec.pop(); -// low_price_30m_vec.reverse(); -// low_price_30m_vec.truncate(5); - -// // read SMA30 csv file -// sma30_30m_vec = read_ma_into_vector(&MA::Sma, 30, "30m", &element.0).await?; - -// // read rsi30 csv file -// rsi30_vec = read_rsi_into_vector(30, "30m", &element.0).await?; - -// if low_price_30m_vec.len() == 5 { - -// // 2nd filtering symbols -// let result = sma30_30m_vec.binary_search_by_key(&low_price_30m_vec.first().unwrap().server_epoch, |MaData{price, server_epoch}| *server_epoch); -// match result { -// Ok(T) => { - -// if sma30_30m_vec[T].price > low_price_30m_vec[0].price { - -// let index_of_min: Option = low_price_30m_vec -// .iter() -// .enumerate() -// .min_by(|(_, a), (_, b)| a.price.partial_cmp(&b.price).expect("Nan was forbidden.")) -// .map(|(index, _)| index); - -// // index 1 means the middle index of 5 element in a vec, assuming the latest price is included but removed in the vec. -// if index_of_min == Some(1) { -// let result = rsi30_vec.binary_search_by_key(&low_price_30m_vec[1].server_epoch, |&RsiData{rsi_value, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if rsi30_vec[T].rsi_value < 0.25 { -// filtered_3rd_symbols.push((element.0, low_price_30m_vec.first().unwrap().server_epoch)); -// } -// }, -// Err(e) => {} -// } -// } -// } -// }, -// Err(E) => {} -// } -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(8, &filtered_3rd_symbols).await; - -// println!("strategist_008 완료"); -// Ok(()) -// } - -// pub async fn strategist_009 () -> Result<(), Box> { -// // [strategist_009 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) -// // 3. 2nd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) -// // 4. insert or update record into [strategist_001_table] -// // 5. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_price_avg = 0.0; -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut opclo_1d_price_avg = 0.0; - -// // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// opclo_30m_price_avg = 0.0; -// opclo_1d_price_avg = 0.0; - -// // read 1m csv file -// opclo_30m_vec = read_opclo_into_vector("30m", &element.symbol).await?; - -// // calculate opclo 1m price average -// for element in &opclo_30m_vec { -// opclo_30m_price_avg += element.price; -// } -// opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // read 30m csv file -// opclo_1d_vec = read_opclo_into_vector("1d", &element.symbol).await?; - -// // calculate opclo 30m price average -// for element in &opclo_1d_vec { -// opclo_1d_price_avg += element.price; -// } -// opclo_1d_price_avg /= opclo_1d_vec.len() as f64; - -// // campare both prices -// if opclo_30m_price_avg < opclo_1d_price_avg { -// filtered_1st_symbols.push(element.symbol); -// } -// } - -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 2nd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample -// for element in filtered_1st_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); -// // read rsi3 csv file -// rsi3_vec = read_rsi_into_vector(3, "30m", &element).await?; -// // read rsi10 csv file -// rsi10_vec = read_rsi_into_vector(10, "30m", &element).await?; - -// if rsi3_vec.len() >= 2 && rsi10_vec.len() >= 2 { -// if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.30 { -// filtered_2nd_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); -// } -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(9, &filtered_2nd_symbols).await; - -// println!("strategist_009 완료"); -// Ok(()) -// } - -// pub async fn strategist_010 () -> Result<(), Box> { -// // [strategist_010 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) -// // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) -// // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) -// // 5. insert or update record into [strategist_001_table] -// // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] - -// let instant = Instant::now(); - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_price_avg = 0.0; -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut opclo_1d_price_avg = 0.0; - -// // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// opclo_30m_price_avg = 0.0; -// opclo_1d_price_avg = 0.0; - -// // -// let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; -// let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; - -// // read opclo_30m and 1d csv file -// if opclo_30m_result.is_ok() && opclo_1d_result.is_ok() { -// opclo_30m_vec = opclo_30m_result.unwrap(); -// opclo_1d_vec = opclo_1d_result.unwrap(); - -// if opclo_30m_vec.len() > 4 && opclo_1d_vec.len() > 7 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.split_off(7); -// opclo_30m_vec.reverse(); -// opclo_1d_vec.split_off(4); - -// // calculate opclo 1m price average -// for element in &opclo_30m_vec { -// opclo_30m_price_avg += element.price; -// } -// opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // calculate opclo 30m price average -// for element in &opclo_1d_vec { -// opclo_1d_price_avg += element.price; -// } -// opclo_1d_price_avg /= opclo_1d_vec.len() as f64; - -// // campare both prices -// if opclo_30m_price_avg < opclo_1d_price_avg { -// filtered_1st_symbols.push(element.symbol); -// } -// } -// } -// } - -// // 4. 3rd filtering symbols: yesterday 1d RSI 3 < 10, 1d RSI 10 < 15 -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for element in filtered_1st_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "1d", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "1d", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() & rsi10_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// rsi3_vec.pop(); -// rsi10_vec.pop(); -// if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.15 { -// filtered_2nd_symbols.push(element); -// } -// } -// } -// } - -// // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for element in filtered_2nd_symbols { - -// let opclo_30m_result = read_low_price_into_vector("30m", &element).await; -// let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; - -// // read 30m csv file && bollingerband sma30 csv file -// if opclo_30m_result.is_ok() && read_bb_result.is_ok() { -// opclo_30m_vec = opclo_30m_result.unwrap(); -// read_bb_vec = read_bb_result.unwrap(); - -// if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { -// // 2nd filtering symbols -// opclo_30m_vec.pop(); -// let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().price { -// filtered_3rd_symbols.push(element); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample -// for element in filtered_3rd_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let opclo_30m_result = read_low_price_into_vector("30m", &element).await; -// let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() && rsi10_result.is_ok() && opclo_30m_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); -// opclo_30m_vec = opclo_30m_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.20 { -// filtered_4th_symbols.push((element, opclo_30m_vec.last().unwrap().server_epoch)); -// } -// } - -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(10, &filtered_4th_symbols).await; - -// if instant.elapsed().as_millis() < 50 { -// sleep(Duration::from_millis(50)).await; -// } -// // println!("strategist_010 완료"); -// Ok(()) -// } - -// pub async fn strategist_011 () -> Result<(), Box> { -// // [strategist_011 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_1m price avg < opclo_30m price avg) -// // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) -// // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) -// // 5. insert or update record into [strategist_001_table] -// // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] - -// let instant = Instant::now(); - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut opclo_1m_price_avg = 0.0; -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_price_avg = 0.0; - -// // 2. 1st filtering symbols: candle 1m price avg < candle 30m price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// opclo_1m_price_avg = 0.0; -// opclo_30m_price_avg = 0.0; - -// let opclo_1m_result = read_opclo_into_vector("1m", &element.symbol).await; -// let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; - -// if opclo_1m_result.is_ok() && opclo_30m_result.is_ok() { -// opclo_1m_vec = opclo_1m_result.unwrap(); -// opclo_30m_vec = opclo_30m_result.unwrap(); - -// if opclo_1m_vec.len() > 1 && opclo_30m_vec.len() > 1 { -// // calculate opclo 1m price average -// for element in &opclo_1m_vec { -// opclo_1m_price_avg += element.price; -// } -// opclo_1m_price_avg /= opclo_1m_vec.len() as f64; - -// // calculate opclo 30m price average -// for element in &opclo_30m_vec { -// opclo_30m_price_avg += element.price; -// } -// opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // campare both prices -// if opclo_1m_price_avg < opclo_30m_price_avg { -// filtered_1st_symbols.push(element.symbol); -// } -// } -// } -// } - -// // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for element in filtered_1st_symbols { - -// let opclo_30m_result = read_low_price_into_vector("30m", &element).await; -// let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; - -// // read 30m csv file & bollingerband sma30 csv file -// if opclo_30m_result.is_ok() && read_bb_result.is_ok() { -// opclo_30m_vec = opclo_30m_result.unwrap(); -// read_bb_vec = read_bb_result.unwrap(); - -// if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 -// { -// // 2nd filtering symbols -// opclo_30m_vec.pop(); -// let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().price { -// filtered_2nd_symbols.push(element); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample -// for element in filtered_2nd_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; - -// if rsi3_result.is_ok() && rsi10_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.20 { -// filtered_3rd_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); -// } -// } - -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(11, &filtered_3rd_symbols).await; - -// if instant.elapsed().as_millis() < 50 { -// sleep(Duration::from_millis(50)).await; -// } - -// // println!("strategist_011 완료"); -// Ok(()) -// } - -// pub async fn strategist_012 () -> Result<(), Box> { -// // [strategist_010 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) -// // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) -// // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) -// // 5. insert or update record into [strategist_001_table] -// // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] - -// let instant = Instant::now(); - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_price_avg = 0.0; -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut opclo_1d_price_avg = 0.0; - -// // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// opclo_30m_price_avg = 0.0; -// opclo_1d_price_avg = 0.0; - -// let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; -// let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; - -// // read 30m csv file & read 1d csv file -// if opclo_30m_result.is_ok() && opclo_1d_result.is_ok() { -// opclo_30m_vec = opclo_30m_result.unwrap(); -// opclo_1d_vec = opclo_1d_result.unwrap(); - -// if opclo_30m_vec.len() > 1 && opclo_1d_vec.len() > 1 { -// // calculate opclo 1m price average -// for element in &opclo_30m_vec { -// opclo_30m_price_avg += element.price; -// } -// opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // calculate opclo 30m price average -// for element in &opclo_1d_vec { -// opclo_1d_price_avg += element.price; -// } -// opclo_1d_price_avg /= opclo_1d_vec.len() as f64; - -// // campare both prices -// if opclo_30m_price_avg < (opclo_1d_price_avg/4.0) { -// filtered_1st_symbols.push(element.symbol); -// } -// } -// } -// } - -// let mut opclo_30m_vec: Vec = Vec::new(); -// // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for element in filtered_1st_symbols { - -// let opclo_30m_result = read_low_price_into_vector("30m", &element).await; -// let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; - -// // read 1m csv file & bollingerband sma30 csv file -// if opclo_30m_result.is_ok() & read_bb_result.is_ok() { -// opclo_30m_vec = opclo_30m_result.unwrap(); -// read_bb_vec = read_bb_result.unwrap(); - -// if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { -// // 2nd filtering symbols -// let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband > opclo_30m_vec.last().unwrap().price { -// filtered_2nd_symbols.push(element); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut opclo_1m_price_avg = 0.0; -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_price_avg = 0.0; -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for element in filtered_2nd_symbols { -// // initialize avgs -// opclo_1m_price_avg = 0.0; -// opclo_30m_price_avg = 0.0; - -// let opclo_1m_result = read_opclo_into_vector("1m", &element).await; -// let opclo_30m_result = read_opclo_into_vector("30m", &element).await; - -// if opclo_1m_result.is_ok() && opclo_30m_result.is_ok() { -// opclo_1m_vec = opclo_1m_result.unwrap(); -// opclo_30m_vec = opclo_30m_result.unwrap(); - -// if opclo_1m_vec.len() > 10 && opclo_30m_vec.len() > 4 { -// opclo_1m_vec.reverse(); -// opclo_1m_vec.split_off(10); -// opclo_30m_vec.reverse(); -// opclo_30m_vec.split_off(4); - -// // calculate opclo 1m price average -// for element in &opclo_1m_vec { -// opclo_1m_price_avg += element.price; -// } -// opclo_1m_price_avg /= opclo_1m_vec.len() as f64; - -// // calculate opclo 30m price average -// for element in &opclo_30m_vec { -// opclo_30m_price_avg += element.price; -// } -// opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // campare both prices -// if opclo_1m_price_avg < (opclo_30m_price_avg*0.99) { -// filtered_3rd_symbols.push(element); -// } -// } -// } -// } - -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample -// for element in filtered_3rd_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() & rsi10_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { -// filtered_4th_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); -// } -// } - -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(12, &filtered_4th_symbols).await; - -// if instant.elapsed().as_millis() < 50 { -// sleep(Duration::from_millis(50)).await; -// } - -// // println!("strategist_012 완료"); -// Ok(()) -// } - -// // original strategist 012 -// // pub async fn strategist_012 () -> Result<(), Box> { -// // // [strategist_010 procedure] -// // // 1. retrieve all usdttrade symbols -// // // 2. 1st filtering symbols (opclo_30m price avg < opclo_1d price avg) -// // // 3. 2nd filtering symbols (candle 30m low price at the previous candle < bb_sma30_30m lowerband) -// // // 4. 3rd filtering symbols (check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample) -// // // 5. insert or update record into [strategist_001_table] -// // // 6. if symbol's 30m price is over bb_sma30_30m lowerband, move the record from [strategist_001_table] to [suggested_coin_list] - -// // let instant = Instant::now(); - -// // // 1. retrieve all usdttrade symbols -// // #[derive(Debug, FromRow)] -// // struct UsdtTrades { -// // symbol: String, -// // } -// // let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// // let table_name = String::from("valid_usdt_trades"); -// // let column_name = String::from("symbol"); -// // let table_condition = None; -// // let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// // let mut opclo_30m_vec: Vec = Vec::new(); -// // let mut opclo_30m_price_avg = 0.0; -// // let mut opclo_1d_vec: Vec = Vec::new(); -// // let mut opclo_1d_price_avg = 0.0; - -// // // 2. 1st filtering symbols: candle 30m price avg < candle 1d price avg -// // let mut filtered_1st_symbols: Vec = Vec::new(); -// // for element in usdt_trade_symbols { -// // // initialize avgs -// // opclo_30m_price_avg = 0.0; -// // opclo_1d_price_avg = 0.0; - -// // let opclo_30m_result = read_opclo_into_vector("30m", &element.symbol).await; -// // let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; - -// // // read 30m csv file & read 1d csv file -// // if opclo_30m_result.is_ok() && opclo_1d_result.is_ok() { -// // opclo_30m_vec = opclo_30m_result.unwrap(); -// // opclo_1d_vec = opclo_1d_result.unwrap(); - -// // if opclo_30m_vec.len() > 1 && opclo_1d_vec.len() > 1 { -// // // calculate opclo 1m price average -// // for element in &opclo_30m_vec { -// // opclo_30m_price_avg += element.price; -// // } -// // opclo_30m_price_avg /= opclo_30m_vec.len() as f64; - -// // // calculate opclo 30m price average -// // for element in &opclo_1d_vec { -// // opclo_1d_price_avg += element.price; -// // } -// // opclo_1d_price_avg /= opclo_1d_vec.len() as f64; - -// // // campare both prices -// // if opclo_30m_price_avg < (opclo_1d_price_avg/3.0) { -// // filtered_1st_symbols.push(element.symbol); -// // } -// // } -// // } -// // } - -// // let mut opclo_1m_vec: Vec = Vec::new(); -// // // 3. 2nd filtering symbols: lower band in bollingerband of sma30 > candle 30m low price -// // let mut read_bb_vec: Vec = Vec::new(); -// // let mut filtered_2nd_symbols: Vec = Vec::new(); -// // for element in filtered_1st_symbols { - -// // let opclo_1m_result = read_low_price_into_vector("1m", &element).await; -// // let read_bb_result = read_bb_into_vector("sma30", "1m", &element).await; - -// // // read 1m csv file & bollingerband sma30 csv file -// // if opclo_1m_result.is_ok() & read_bb_result.is_ok() { -// // opclo_1m_vec = opclo_1m_result.unwrap(); -// // read_bb_vec = read_bb_result.unwrap(); - -// // if opclo_1m_vec.len() > 1 && read_bb_vec.len() > 1 { -// // // 2nd filtering symbols -// // let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// // match result { -// // Ok(T) => { -// // if read_bb_vec[T].lowerband > opclo_1m_vec.last().unwrap().price { -// // filtered_2nd_symbols.push(element); -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // } -// // } - -// // let mut rsi3_vec: Vec = Vec::new(); -// // let mut rsi10_vec: Vec = Vec::new(); -// // let mut filtered_3rd_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) - -// // // 3. 3rd filtering symbols: check if the middle sample among 5 sample from the latest price is the lowest price and then check if RSI3 and RSI10 are lower than 0.15 and 0.3 respectively of the middle sample -// // for element in filtered_2nd_symbols { - -// // rsi3_vec.clear(); -// // rsi10_vec.clear(); - -// // let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; -// // let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; - -// // // read rsi3 csv file & rsi10 csv file -// // if rsi3_result.is_ok() & rsi10_result.is_ok() { -// // rsi3_vec = rsi3_result.unwrap(); -// // rsi10_vec = rsi10_result.unwrap(); - -// // if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// // if rsi3_vec.last().unwrap().rsi_value < 0.15 && rsi10_vec.last().unwrap().rsi_value < 0.20 { -// // filtered_3rd_symbols.push((element, opclo_30m_vec.first().unwrap().server_epoch)); -// // } -// // } - -// // } -// // } - -// // // 4. insert record into [pre_suggested_coin_list] -// // insert_pre_suggested_coins(12, &filtered_3rd_symbols).await; - -// // if instant.elapsed().as_millis() < 50 { -// // sleep(Duration::from_millis(50)).await; -// // } - -// // // println!("strategist_012 완료"); -// // Ok(()) -// // } - -// pub async fn strategist_013 () -> Result<(), Box> { -// // [strategist_013 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols (the latest opclo_1d price avg < 20% of opclo_1d price avg two days before, the latest opclo_1d price avg < opclo_1d price avg a day before) -// // 3. 2nd filtering symbols (1d RSI3 and RSI10 are lower than 0.10) -// // 4. 3rd filtering symbols (candle 1d low price < 90% of bb_sma30_1d lowerband) -// // 5. 4th filtering symbols (30m RSI3 and RSI10 are lower than 0.10 abd 0.10 respectively) -// // 6. 5th filtering symbols (candle 30m low price < 99.5% of bb_sma30_30m lowerband) - -// let instant = Instant::now(); - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// // 2. 1st filtering symbols (the latest opclo_1d price avg < 90% of opclo_1d price avg two days before) -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut opclo_1d_latest_price = 0.0; -// let mut opclo_1d_1before_price = 0.0; -// let mut opclo_1d_2before_price = 0.0; -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// opclo_1d_latest_price = 0.0; -// opclo_1d_1before_price = 0.0; -// opclo_1d_2before_price = 0.0; - -// let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; - -// // read 30m csv file & read 1d csv file -// if opclo_1d_result.is_ok() { -// opclo_1d_vec = opclo_1d_result.unwrap(); - -// if opclo_1d_vec.len() > 3 { -// // compare the lastest price and 20% of 2 days before price -// opclo_1d_vec.reverse(); -// let mut iter = opclo_1d_vec.iter(); -// opclo_1d_latest_price = iter.next().unwrap().price; -// opclo_1d_1before_price = iter.next().unwrap().price; -// opclo_1d_2before_price = iter.next().unwrap().price; - -// // campare both prices -// if (opclo_1d_latest_price < opclo_1d_2before_price * 0.9) && (opclo_1d_latest_price < opclo_1d_1before_price * 0.95) { -// filtered_1st_symbols.push(element.symbol); -// } -// } -// } -// } - -// // 3. 2nd filtering symbols (1d RSI3 and RSI10 are lower than 0.10) -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for element in filtered_1st_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "1d", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "1d", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() & rsi10_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { -// filtered_2nd_symbols.push(element); -// } -// } - -// } -// } - -// // 4. 3rd filtering symbols (candle 1d low price < 90% of bb_sma30_1d lowerband) -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for element in filtered_2nd_symbols { - -// let opclo_1d_result = read_low_price_into_vector("1d", &element).await; -// let read_bb_result = read_bb_into_vector("sma30", "1d", &element).await; - -// // read 1d csv file & bollingerband sma30 csv file -// if opclo_1d_result.is_ok() & read_bb_result.is_ok() { -// opclo_30m_vec = opclo_1d_result.unwrap(); -// read_bb_vec = read_bb_result.unwrap(); - -// if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { -// // 3rd filtering symbols -// let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband * 0.9 > opclo_30m_vec.last().unwrap().price { -// filtered_3rd_symbols.push(element); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// // 5. 4th filtering symbols (30m RSI3 and RSI10 are lower than 0.10 abd 0.10 respectively) -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec = Vec::new(); -// for element in filtered_3rd_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() & rsi10_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { -// filtered_4th_symbols.push(element); -// } -// } - -// } -// } - -// // 6. 5th filtering symbols (candle 30m low price < 99.5% of bb_sma30_30m lowerband) -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_5th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) -// for element in filtered_4th_symbols { - -// let opclo_30m_result = read_low_price_into_vector("30m", &element).await; -// let read_bb_result = read_bb_into_vector("sma30", "30m", &element).await; - -// // read 1d csv file & bollingerband sma30 csv file -// if opclo_30m_result.is_ok() & read_bb_result.is_ok() { -// opclo_30m_vec = opclo_30m_result.unwrap(); -// read_bb_vec = read_bb_result.unwrap(); - -// if opclo_30m_vec.len() > 1 && read_bb_vec.len() > 1 { -// // 3rd filtering symbols -// let result = read_bb_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].lowerband * 0.995 > opclo_30m_vec.last().unwrap().price { -// filtered_5th_symbols.push((element, opclo_30m_vec.last().unwrap().server_epoch)); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// // 4. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(13, &filtered_5th_symbols).await; - -// if instant.elapsed().as_millis() < 50 { -// sleep(Duration::from_millis(50)).await; -// } - -// // println!("strategist_013 완료"); -// Ok(()) -// } - -// pub async fn strategist_014 () -> Result<(), Box> { -// // [strategist_014 procedure] -// // 1. retrieve all usdttrade symbols -// // 2. 1st filtering symbols: candle 1d price yesterday avg < 80% of candle 1d opclo price latest 7 days avg -// // 3. 2nd filtering symbols: 85% of BB SMA10 MA price > candle 1d price yesterday avg -// // 4. 3rd filtering symbols: yesterday 1d RSI 3 < 10, 1d RSI 10 < 15 -// // 5. 4th filtering symbols: avg between yesterday 1d opclo price and yesterday low price> latest 30m opclo price -// // 6. 5th filtering symbols: 30m RSI 3 < 10, 30m RSI 10 < 15 -// // 7. insert record into [pre_suggested_coin_list] - -// let instant = Instant::now(); - -// // 1. retrieve all usdttrade symbols -// #[derive(Debug, FromRow)] -// struct UsdtTrades { -// symbol: String, -// } -// let mut usdt_trades = UsdtTrades { symbol: String::new() }; - -// let table_name = String::from("valid_usdt_trades"); -// let column_name = String::from("symbol"); -// let table_condition = None; -// let mut usdt_trade_symbols = select_record(&table_name, &column_name, &table_condition, &usdt_trades).await.unwrap(); - -// // 2. 1st filtering symbols: candle 1d price yesterday avg < 80% of candle 1d opclo price latest 7 days avg -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut opclo_1d_price_7days_avg = 0.0; -// let mut filtered_1st_symbols: Vec = Vec::new(); -// for element in usdt_trade_symbols { -// // initialize avgs -// opclo_1d_price_7days_avg = 0.0; - -// let opclo_1d_result = read_opclo_into_vector("1d", &element.symbol).await; - -// // read 1d csv file -// if opclo_1d_result.is_ok() { - -// opclo_1d_vec = opclo_1d_result.unwrap(); - -// if opclo_1d_vec.len() >= 8 { -// opclo_1d_vec.pop(); -// opclo_1d_vec.reverse(); - -// opclo_1d_vec.split_off(7); - -// // calculate opclo 1d price average -// for element in &opclo_1d_vec { -// opclo_1d_price_7days_avg += element.price; -// } -// opclo_1d_price_7days_avg /= opclo_1d_vec.len() as f64; - -// // campare the yesterday opclo price with 30days avg -// if opclo_1d_vec[0].price < (opclo_1d_price_7days_avg * 0.8) { -// filtered_1st_symbols.push(element.symbol); -// } -// } -// } -// } - -// // 3. 2nd filtering symbols: 85% of BB SMA10 MA price > candle 1d price yesterday avg -// let mut read_bb_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// for element in filtered_1st_symbols { - -// let opclo_1d_result = read_opclo_into_vector("1d", &element).await; -// let read_bb_result = read_bb_into_vector("sma10", "1d", &element).await; - -// // read 1d csv file & bollingerband sma30 csv file -// if opclo_1d_result.is_ok() & read_bb_result.is_ok() { -// opclo_1d_vec = opclo_1d_result.unwrap(); -// read_bb_vec = read_bb_result.unwrap(); - -// if opclo_1d_vec.len() > 1 && read_bb_vec.len() > 1 { -// opclo_1d_vec.pop(); -// read_bb_vec.pop(); -// let result = read_bb_vec.binary_search_by_key(&opclo_1d_vec.last().unwrap().server_epoch, |&BBData{ma_price, upperband, lowerband, server_epoch}|server_epoch); -// match result { -// Ok(T) => { -// if read_bb_vec[T].ma_price * 0.85 > opclo_1d_vec.last().unwrap().price { -// filtered_2nd_symbols.push(element); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// // 4. 3rd filtering symbols: yesterday 1d RSI 3 < 10, 1d RSI 10 < 15 -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for element in filtered_2nd_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "1d", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "1d", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() & rsi10_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 { -// rsi3_vec.pop(); -// rsi10_vec.pop(); -// if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.15 { -// filtered_3rd_symbols.push(element); -// } -// } -// } -// } - -// // 5. 4th filtering symbols: avg between yesterday 1d opclo price and yesterday low price> latest 30m opclo price -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut low_1d_vec: Vec = Vec::new(); -// let mut avg = 0.0; -// let mut price_same_closetime = 0.0; -// let mut filtered_4th_symbols: Vec = Vec::new(); -// for element in filtered_3rd_symbols { -// // initialize avgs -// avg = 0.0; -// price_same_closetime = 0.0; - -// let opclo_1d_result = read_opclo_into_vector("1d", &element).await; -// let opclo_30m_result = read_opclo_into_vector("30m", &element).await; -// let low_1d_result = read_low_price_into_vector("1d", &element).await; - -// // read 1d csv file -// if opclo_1d_result.is_ok() && low_1d_result.is_ok() && opclo_30m_result.is_ok() { - -// opclo_1d_vec = opclo_1d_result.unwrap(); -// opclo_30m_vec = opclo_30m_result.unwrap(); -// low_1d_vec = low_1d_result.unwrap(); - -// if opclo_1d_vec.len() > 1 && low_1d_vec.len() > 1 && opclo_30m_vec.len() > 1 { -// opclo_1d_vec.pop(); - -// let result = low_1d_vec.binary_search_by_key(&opclo_1d_vec.last().unwrap().server_epoch, |OpcloData{price, server_epoch, usdt_volume, up_down}| *server_epoch); - -// match result { -// Ok(T) => { -// avg = (opclo_1d_vec.last().unwrap().price + low_1d_vec[T].price) / 2.0; - -// if opclo_30m_vec.last().unwrap().price < avg { -// filtered_4th_symbols.push(element); -// } -// }, -// Err(E) => {} -// } -// } -// } -// } - -// // 6. 5th filtering symbols: 30m RSI 3 < 10, 30m RSI 10 < 15 -// let mut rsi3_vec: Vec = Vec::new(); -// let mut rsi10_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_5th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) -// for element in filtered_4th_symbols { - -// rsi3_vec.clear(); -// rsi10_vec.clear(); - -// let rsi3_result = read_rsi_into_vector(3, "30m", &element).await; -// let rsi10_result = read_rsi_into_vector(10, "30m", &element).await; -// let opclo_30m_result = read_opclo_into_vector("30m", &element).await; - -// // read rsi3 csv file & rsi10 csv file -// if rsi3_result.is_ok() & rsi10_result.is_ok() && opclo_30m_result.is_ok() { -// rsi3_vec = rsi3_result.unwrap(); -// rsi10_vec = rsi10_result.unwrap(); -// opclo_30m_vec = opclo_30m_result.unwrap(); - -// if rsi3_vec.len() > 1 && rsi10_vec.len() > 1 && opclo_30m_vec.len() > 1 { -// if rsi3_vec.last().unwrap().rsi_value < 0.10 && rsi10_vec.last().unwrap().rsi_value < 0.10 { -// filtered_5th_symbols.push((element, opclo_30m_vec.last().unwrap().server_epoch)); -// } -// } -// } -// } - -// // 7. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(14, &filtered_5th_symbols).await; - -// if instant.elapsed().as_millis() < 50 { -// sleep(Duration::from_millis(50)).await; -// } -// Ok(()) -// } - -// pub async fn strategist_013( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_013 procedure] -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// // 3rd filtering: low price 30m < BB30_30m lowerband -// // 4th filtering: RSI3_30m < 15, RSI10_30m < 35 -// // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 -// // 6th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m - -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut bb30_1d_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// let mut current_price: Option; -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && bb30_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.truncate(2); -// opclo_1d_vec.reverse(); -// bb30_1d_vec.reverse(); -// bb30_1d_vec.truncate(2); -// bb30_1d_vec.reverse(); - -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.first().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// current_price = get_current_price(&symbol, &alldata.price_vec).await; - -// if current_price.is_some() { -// if current_price.unwrap().is_normal() { -// if (bb30_1d_vec[T].upperband -// > opclo_1d_vec.first().unwrap().opclo_price) -// && (opclo_1d_vec.first().unwrap().opclo_price -// > current_price.unwrap()) -// { -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1d_vec[T].upperband -// > opclo_1d_vec.last().unwrap().opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut ema3_30m_vec: Vec = Vec::new(); -// let mut sma30_30m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// let mut cnt = 0; -// for symbol in filtered_1st_symbols { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); -// let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && ema3_30m_option.is_some() && sma30_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); -// sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 && ema3_30m_vec.len() >= 1 && sma30_30m_vec.len() >= 1 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); -// opclo_30m_vec.reverse(); - -// cnt = 0; -// for element in &opclo_30m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 4 { -// let result = ema3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema3_30m_vec[T].ema_value > opclo_30m_vec.last().unwrap().opclo_price -// { -// let result = sma30_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma30_30m_vec[T].sma_value -// > opclo_30m_vec.last().unwrap().opclo_price -// { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } - -// // 3rd filtering: low price 30m < BB30_30m lowerband -// let mut low_30m_vec: Vec = Vec::new(); -// let mut bb30_30m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for symbol in filtered_2nd_symbols { -// let low_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if low_30m_option.is_some() && bb30_30m_option.is_some() { -// low_30m_vec = alldata.rt_price_30m_vec[low_30m_option.unwrap()].1.clone(); -// bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); - -// if low_30m_vec.len() >= 1 && bb30_30m_vec.len() >= 1 { -// let result = bb30_30m_vec.binary_search_by_key( -// &low_30m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_30m_vec[T].lowerband > low_30m_vec.last().unwrap().low_price { -// filtered_3rd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 4th filtering: 30m RSI 3 < 15, 30m RSI 10 < 35 -// let mut rsi3_30m_vec: Vec = Vec::new(); -// let mut rsi10_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec = Vec::new(); -// for symbol in filtered_3rd_symbols { -// let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); -// rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// let result = rsi3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_30m_vec[T].rsi_value < 15.0 { -// let result = rsi10_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_30m_vec[T].rsi_value < 35.0 { -// filtered_4th_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 -// let mut rsi3_1m_vec: Vec = Vec::new(); -// let mut rsi10_1m_vec: Vec = Vec::new(); -// let mut filtered_5th_symbols: Vec = Vec::new(); // (symbol, closetime) -// for symbol in filtered_4th_symbols { -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); - -// if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { -// rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); - -// if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { -// if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 -// && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 -// { -// filtered_5th_symbols.push(symbol); -// } -// } -// } -// } - -// // 6th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m, clo_1m < BB30_1m lowerband -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut ema3_1m_vec: Vec = Vec::new(); -// let mut ema10_1m_vec: Vec = Vec::new(); -// let mut bb30_1m_vec: Vec = Vec::new(); -// let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_5th_symbols { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); -// let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); -// let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1m_option.is_some() -// && opclo_30m_option.is_some() -// && ema3_1m_option.is_some() -// && ema10_1m_option.is_some() -// && bb30_1m_option.is_some() -// { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); -// ema10_1m_vec = alldata.ema10_1m_data[ema10_1m_option.unwrap()].1.clone(); -// bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); - -// if opclo_1m_vec.len() >= 1 -// && opclo_30m_vec.len() >= 1 -// && ema3_1m_vec.len() >= 1 -// && ema10_1m_vec.len() >= 1 -// && bb30_1m_vec.len() >= 1 -// { -// let result = ema3_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema3_1m_vec[T].ema_value > opclo_1m_vec.last().unwrap().opclo_price { -// let result = ema10_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema10_1m_vec[T].ema_value -// > opclo_1m_vec.last().unwrap().opclo_price -// { -// let result = bb30_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| { -// close_time -// }, -// ); -// match result { -// Ok(T) => { -// if bb30_1m_vec[T].lowerband -// > opclo_1d_vec.last().unwrap().close_price -// { -// filtered_6th_symbols.push(( -// symbol, -// opclo_30m_vec.last().unwrap().close_time, -// )); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// insert_pre_suggested_coins(13, &filtered_6th_symbols, alldata).await; - -// Ok(()) -// } - -// pub async fn strategist_014( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_014 procedure] -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d, -// // 2nd filtering: the latest 2 opclo_1d < SMA3_1d (apply this filtering if 5days angle of marketcap is negative and marketcap opinion is DOWN or KEEP) -// // 3rd filtering: RSI3_1d < 20, RSI10_1d < 35, RSI30_1d < 45 (if 5days angle of marketcap is negative and marketcap opinion is UP, this filtering will be passed) -// // 4th filtering: -// // 1) check the latest candle is DOWN (common) -// // 2) DOWN candles having 0.3% below change is not counted -// // 3) check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// // 4) OR, check 5 samples of candle 30m has DOWN candles at least 3, the latest clo_30m < BB30_30m lowerband -// // 5th filtering: RSI3_30m < 20, RSI10_30m < 35 -// // 6th filtering: RSI3_1m < 10, RSI10_1m < 25 -// // 7th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m, clo_1m < BB30_1m lowerband -// // 8th filtering: check the latest candle is DOWN and check 5 samples of candle 1m has DOWN candles at least 3 - -// let signal_opinions = select_signal_association_opinion().await; -// let market_cap_index = select_marketcap().await; - -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band and SMA3_1d, current price < previous opclo_1d, -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut bb30_1d_vec: Vec = Vec::new(); -// let mut sma3_1d_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// let mut current_price: Option; -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); -// let sma3_1d_option = alldata.sma3_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && bb30_1d_option.is_some() && sma3_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); -// sma3_1d_vec = alldata.sma3_1d_data[sma3_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 && sma3_1d_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.truncate(2); -// opclo_1d_vec.reverse(); -// bb30_1d_vec.reverse(); -// bb30_1d_vec.truncate(2); -// bb30_1d_vec.reverse(); -// sma3_1d_vec.reverse(); -// sma3_1d_vec.truncate(2); -// sma3_1d_vec.reverse(); - -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.first().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// current_price = get_current_price(&symbol, &alldata.price_vec).await; - -// if current_price.is_some() { -// if current_price.unwrap().is_normal() { -// if (bb30_1d_vec[T].upperband -// > opclo_1d_vec.first().unwrap().opclo_price) -// && (opclo_1d_vec.first().unwrap().opclo_price -// > current_price.unwrap()) -// { -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1d_vec[T].upperband -// > opclo_1d_vec.last().unwrap().opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 2nd filtering: the latest 2 opclo_1d < SMA3_1d (apply this filtering if 5days angle of marketcap is negative and marketcap opinion is DOWN or KEEP) -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut sma3_1d_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// if (signal_opinions[0].opinion.contains("DOWN") || signal_opinions[0].opinion.contains("KEEP")) -// && market_cap_index[1].market_cap_index.is_sign_negative() -// { -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let sma3_1d_option = alldata.sma3_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && sma3_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// sma3_1d_vec = alldata.sma3_1d_data[sma3_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && sma3_1d_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.truncate(2); -// opclo_1d_vec.reverse(); -// sma3_1d_vec.reverse(); -// sma3_1d_vec.truncate(2); -// sma3_1d_vec.reverse(); - -// let result = sma3_1d_vec.binary_search_by_key( -// &opclo_1d_vec.first().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma3_1d_vec[T].sma_value > opclo_1d_vec.first().unwrap().opclo_price -// { -// let result = sma3_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma3_1d_vec[T].sma_value -// > opclo_1d_vec.last().unwrap().opclo_price -// { -// filtered_2nd_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } else { -// filtered_2nd_symbols = filtered_1st_symbols; -// } - -// // 3rd filtering: RSI3_1d < 20, RSI10_1d < 35, RSI30_1d < 45 (if 5days angle of marketcap is negative and marketcap opinion is UP, this filtering will be passed) -// let mut rsi3_1d_vec: Vec = Vec::new(); -// let mut rsi10_1d_vec: Vec = Vec::new(); -// let mut rsi30_1d_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// if signal_opinions[0].opinion.contains("UP") -// && market_cap_index[1].market_cap_index.is_sign_negative() -// { -// filtered_3rd_symbols = filtered_2nd_symbols; -// } else { -// for symbol in filtered_2nd_symbols { -// let rsi3_1d_option = alldata.rsi3_1d_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1d_option = alldata.rsi10_1d_data.iter().position(|x| *x.0 == *symbol); -// let rsi30_1d_option = alldata.rsi30_1d_data.iter().position(|x| *x.0 == *symbol); - -// if rsi3_1d_option.is_some() && rsi10_1d_option.is_some() && rsi30_1d_option.is_some() { -// rsi3_1d_vec = alldata.rsi3_1d_data[rsi3_1d_option.unwrap()].1.clone(); -// rsi10_1d_vec = alldata.rsi10_1d_data[rsi10_1d_option.unwrap()].1.clone(); -// rsi30_1d_vec = alldata.rsi30_1d_data[rsi30_1d_option.unwrap()].1.clone(); - -// if rsi3_1d_vec.len() >= 1 && rsi10_1d_vec.len() >= 1 && rsi30_1d_vec.len() >= 1 { -// if rsi3_1d_vec.last().unwrap().rsi_value < 20.0 -// && rsi10_1d_vec.last().unwrap().rsi_value < 35.0 -// && rsi30_1d_vec.last().unwrap().rsi_value < 45.0 -// { -// filtered_3rd_symbols.push(symbol); -// } -// } -// } -// } -// } - -// // 4th filtering: -// // 1) check the latest candle is DOWN (common) -// // 2) DOWN candles having 0.3% below change is not counted -// // 3) check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// // 4) OR, check 5 samples of candle 30m has DOWN candles at least 3, the latest clo_30m < BB30_30m lowerband - -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut ema3_30m_vec: Vec = Vec::new(); -// let mut sma30_30m_vec: Vec = Vec::new(); -// let mut bb30_30m_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec = Vec::new(); -// let mut cnt = 0; -// for symbol in filtered_3rd_symbols { -// let mut is_filtering_passed: bool = false; -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); -// let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); -// let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() -// && ema3_30m_option.is_some() -// && sma30_30m_option.is_some() -// && bb30_30m_option.is_some() -// { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); -// sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); -// bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 -// && ema3_30m_vec.len() >= 1 -// && sma30_30m_vec.len() >= 1 -// && bb30_30m_vec.len() >= 1 -// { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); -// opclo_30m_vec.reverse(); - -// if opclo_30m_vec.last().unwrap().candle_type == "DOWN" { -// cnt = 0; -// for element in &opclo_30m_vec { -// if element.candle_type == "DOWN" { -// if (element.open_price / element.close_price) - 1.0 > 0.003 { -// cnt += 1; -// } -// } -// } - -// if cnt >= 4 { -// let result = ema3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema3_30m_vec[T].ema_value -// > opclo_30m_vec.last().unwrap().opclo_price -// { -// let result = sma30_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma30_30m_vec[T].sma_value -// > opclo_30m_vec.last().unwrap().opclo_price -// { -// is_filtering_passed = true; -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } else if cnt == 3 { -// let result = bb30_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_30m_vec[T].lowerband -// > opclo_30m_vec.last().unwrap().close_price -// { -// is_filtering_passed = true; -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } -// if is_filtering_passed == true { -// filtered_4th_symbols.push(symbol); -// } -// } - -// // 5th filtering: RSI3_30m < 20, RSI10_30m < 35 -// let mut rsi3_30m_vec: Vec = Vec::new(); -// let mut rsi10_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_5th_symbols: Vec = Vec::new(); -// for symbol in filtered_4th_symbols { -// let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); -// rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// let result = rsi3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_30m_vec[T].rsi_value < 20.0 { -// let result = rsi10_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_30m_vec[T].rsi_value < 35.0 { -// filtered_5th_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 6th filtering: RSI3_1m < 10, RSI10_1m < 25 -// let mut rsi3_1m_vec: Vec = Vec::new(); -// let mut rsi10_1m_vec: Vec = Vec::new(); -// let mut filtered_6th_symbols: Vec = Vec::new(); -// for symbol in filtered_5th_symbols { -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); - -// if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() { -// rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); - -// if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 { -// if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 -// && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 -// { -// filtered_6th_symbols.push(symbol); -// } -// } -// } -// } - -// // // 6. 5th filtering symbols: 30m current vol > 30m previous vol * 2 -// // let mut opclo_30m_vec: Vec = Vec::new(); -// // let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) -// // for element in filtered_3rd_symbols { -// // let opclo_30m_result = read_price_into_vector("30m", &element).await; - -// // if opclo_30m_result.is_ok() { -// // let opclo_30m_option = opclo_30m_result?; -// // if opclo_30m_option.is_some() { -// // opclo_30m_vec = opclo_30m_option.unwrap(); - -// // if opclo_30m_vec.len() >= 2 { -// // opclo_30m_vec.reverse(); -// // opclo_30m_vec.truncate(2); -// // opclo_30m_vec.reverse(); - -// // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume < opclo_30m_vec.last().unwrap().quote_asset_volume && opclo_30m_vec.last().unwrap().candle_type == "DOWN" { -// // filtered_4th_symbols.push((element, opclo_30m_vec.last().unwrap().close_time)); -// // } -// // } -// // } -// // } -// // } - -// // 7th filtering: opclo_1m < EMA3_1m, opclo_1m < EMA10_1m, clo_1m < BB30_1m lowerband -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut ema3_1m_vec: Vec = Vec::new(); -// let mut ema10_1m_vec: Vec = Vec::new(); -// let mut bb30_1m_vec: Vec = Vec::new(); -// let mut filtered_7th_symbols: Vec = Vec::new(); -// for symbol in filtered_6th_symbols { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let ema3_1m_option = alldata.ema3_1m_data.iter().position(|x| *x.0 == *symbol); -// let ema10_1m_option = alldata.ema10_1m_data.iter().position(|x| *x.0 == *symbol); -// let bb30_1m_option = alldata.bb30_1m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1m_option.is_some() -// && ema3_1m_option.is_some() -// && ema10_1m_option.is_some() -// && bb30_1m_option.is_some() -// { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// ema3_1m_vec = alldata.ema3_1m_data[ema3_1m_option.unwrap()].1.clone(); -// ema10_1m_vec = alldata.ema10_1m_data[ema10_1m_option.unwrap()].1.clone(); -// bb30_1m_vec = alldata.bb30_1m_data[bb30_1m_option.unwrap()].1.clone(); - -// if opclo_1m_vec.len() >= 1 -// && ema3_1m_vec.len() >= 1 -// && ema10_1m_vec.len() >= 1 -// && bb30_1m_vec.len() >= 1 -// { -// let result = ema3_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema3_1m_vec[T].ema_value > opclo_1m_vec.last().unwrap().opclo_price { -// let result = ema10_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema10_1m_vec[T].ema_value -// > opclo_1m_vec.last().unwrap().opclo_price -// { -// let result = bb30_1m_vec.binary_search_by_key( -// &opclo_1m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| { -// close_time -// }, -// ); -// match result { -// Ok(T) => { -// if bb30_1m_vec[T].lowerband -// > opclo_1d_vec.last().unwrap().close_price -// { -// filtered_7th_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 8th filtering: -// // check the latest candle is DOWN and check 5 samples of candle 30m has DOWN candles at least 3 -// let mut opclo_1m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_8th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) - -// let mut cnt = 0; -// for symbol in filtered_7th_symbols { -// let opclo_1m_option = alldata.rt_price_1m_vec.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && opclo_1m_option.is_some() { -// opclo_1m_vec = alldata.rt_price_1m_vec[opclo_1m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if opclo_1m_vec.len() >= 5 && opclo_30m_vec.len() >= 5 { -// opclo_1m_vec.reverse(); -// opclo_1m_vec.truncate(5); -// opclo_1m_vec.reverse(); - -// if opclo_1m_vec.last().unwrap().candle_type == "DOWN" { -// cnt = 0; -// for element in &opclo_1m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 3 { -// filtered_8th_symbols -// .push((symbol, opclo_30m_vec.last().unwrap().close_time)); -// } -// } -// } -// } -// } - -// insert_pre_suggested_coins(14, &filtered_8th_symbols, alldata).await; - -// Ok(()) -// } - -// pub async fn strategist_015( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_015 procedure] -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// // 3rd filtering: low price 30m < BB30_30m lowerband -// // 4th filtering: RSI3_30m < 15, RSI10_30m < 35 -// // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 - -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut bb30_1d_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// let mut current_price: Option; -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && bb30_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.truncate(2); -// opclo_1d_vec.reverse(); -// bb30_1d_vec.reverse(); -// bb30_1d_vec.truncate(2); -// bb30_1d_vec.reverse(); - -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.first().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// current_price = get_current_price(&symbol, &alldata.price_vec).await; - -// if current_price.is_some() { -// if current_price.unwrap().is_normal() { -// if (bb30_1d_vec[T].upperband -// > opclo_1d_vec.first().unwrap().opclo_price) -// && (opclo_1d_vec.first().unwrap().opclo_price -// > current_price.unwrap()) -// { -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1d_vec[T].upperband -// > opclo_1d_vec.last().unwrap().opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut ema3_30m_vec: Vec = Vec::new(); -// let mut sma30_30m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// let mut cnt = 0; -// for symbol in filtered_1st_symbols { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); -// let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && ema3_30m_option.is_some() && sma30_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); -// sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 && ema3_30m_vec.len() >= 1 && sma30_30m_vec.len() >= 1 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); -// opclo_30m_vec.reverse(); - -// cnt = 0; -// for element in &opclo_30m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 4 { -// let result = ema3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema3_30m_vec[T].ema_value > opclo_30m_vec.last().unwrap().opclo_price -// { -// let result = sma30_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma30_30m_vec[T].sma_value -// > opclo_30m_vec.last().unwrap().opclo_price -// { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } - -// // 3rd filtering: low price 30m < BB30_30m lowerband -// let mut low_30m_vec: Vec = Vec::new(); -// let mut bb30_30m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for symbol in filtered_2nd_symbols { -// let low_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let bb30_30m_option = alldata.bb30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if low_30m_option.is_some() && bb30_30m_option.is_some() { -// low_30m_vec = alldata.rt_price_30m_vec[low_30m_option.unwrap()].1.clone(); -// bb30_30m_vec = alldata.bb30_30m_data[bb30_30m_option.unwrap()].1.clone(); - -// if low_30m_vec.len() >= 1 && bb30_30m_vec.len() >= 1 { -// let result = bb30_30m_vec.binary_search_by_key( -// &low_30m_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_30m_vec[T].lowerband > low_30m_vec.last().unwrap().low_price { -// filtered_3rd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 4th filtering: 30m RSI 3 < 15, 30m RSI 10 < 35 -// let mut rsi3_30m_vec: Vec = Vec::new(); -// let mut rsi10_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec = Vec::new(); -// for symbol in filtered_3rd_symbols { -// let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); -// rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// let result = rsi3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_30m_vec[T].rsi_value < 15.0 { -// let result = rsi10_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_30m_vec[T].rsi_value < 35.0 { -// filtered_4th_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 5th filtering: RSI3_1m < 10, RSI10_1m < 25 -// let mut rsi3_1m_vec: Vec = Vec::new(); -// let mut rsi10_1m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_4th_symbols { -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 -// && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 -// { -// filtered_5th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); -// } -// } - -// // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// // let result = rsi3_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi3_1m_vec[T].rsi_value < 10.0 { -// // let result = rsi10_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi10_1m_vec[T].rsi_value < 25.0 { -// // filtered_5th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// } -// } -// // // 6. 5th filtering symbols: 30m current vol > 30m previous vol * 2 -// // let mut opclo_30m_vec: Vec = Vec::new(); -// // let mut filtered_5th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) -// // for element in filtered_4th_symbols { -// // let opclo_30m_result = read_price_into_vector("30m", &element).await; - -// // if opclo_30m_result.is_ok() { -// // let opclo_30m_option = opclo_30m_result?; -// // if opclo_30m_option.is_some() { -// // opclo_30m_vec = opclo_30m_option.unwrap(); - -// // if opclo_30m_vec.len() >= 2 { -// // opclo_30m_vec.reverse(); -// // opclo_30m_vec.truncate(2); -// // opclo_30m_vec.reverse(); - -// // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume < opclo_30m_vec.last().unwrap().quote_asset_volume && opclo_30m_vec.last().unwrap().candle_type == "DOWN" { -// // filtered_5th_symbols.push((element, opclo_30m_vec.last().unwrap().close_time)); -// // } -// // } -// // } -// // } -// // } -// // println!("5: {:?}", filtered_5th_symbols); -// // 7. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(15, &filtered_5th_symbols, alldata).await; - -// Ok(()) -// } - -// pub async fn strategist_016( -// alldata: &AllData, -// ) -> Result<(), Box> { -// // [strategist_016 procedure] -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 -// // 4th filtering: RSI3_1m < 10, RSI10_1m < 25 - -// // 1st filtering: the latest 2 opclo_1d < BB30_1d upper band, current price < previous opclo_1d -// let mut opclo_1d_vec: Vec = Vec::new(); -// let mut bb30_1d_vec: Vec = Vec::new(); -// let mut filtered_1st_symbols: Vec = Vec::new(); -// let mut current_price: Option; -// for symbol in &alldata.valid_symbol_vec { -// let opclo_1d_option = alldata.rt_price_1d_vec.iter().position(|x| *x.0 == *symbol); -// let bb30_1d_option = alldata.bb30_1d_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_1d_option.is_some() && bb30_1d_option.is_some() { -// opclo_1d_vec = alldata.rt_price_1d_vec[opclo_1d_option.unwrap()].1.clone(); -// bb30_1d_vec = alldata.bb30_1d_data[bb30_1d_option.unwrap()].1.clone(); - -// if opclo_1d_vec.len() >= 2 && bb30_1d_vec.len() >= 2 { -// opclo_1d_vec.reverse(); -// opclo_1d_vec.truncate(2); -// opclo_1d_vec.reverse(); -// bb30_1d_vec.reverse(); -// bb30_1d_vec.truncate(2); -// bb30_1d_vec.reverse(); - -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.first().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// current_price = get_current_price(&symbol, &alldata.price_vec).await; - -// if current_price.is_some() { -// if current_price.unwrap().is_normal() { -// if (bb30_1d_vec[T].upperband -// > opclo_1d_vec.first().unwrap().opclo_price) -// && (opclo_1d_vec.first().unwrap().opclo_price -// > current_price.unwrap()) -// { -// let result = bb30_1d_vec.binary_search_by_key( -// &opclo_1d_vec.last().unwrap().close_time, -// |&BollingerBandData { -// sma, -// upperband, -// lowerband, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if bb30_1d_vec[T].upperband -// > opclo_1d_vec.last().unwrap().opclo_price -// { -// filtered_1st_symbols.push(symbol.clone()); -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 2nd filtering: check 5 samples of candle 30m has DOWN candles at least 4, the latest opclo_30m < EMA3_30m, the latest opclo_30m < SMA30_30m -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut ema3_30m_vec: Vec = Vec::new(); -// let mut sma30_30m_vec: Vec = Vec::new(); -// let mut filtered_2nd_symbols: Vec = Vec::new(); -// let mut cnt = 0; -// for symbol in filtered_1st_symbols { -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); -// let ema3_30m_option = alldata.ema3_30m_data.iter().position(|x| *x.0 == *symbol); -// let sma30_30m_option = alldata.sma30_30m_data.iter().position(|x| *x.0 == *symbol); - -// if opclo_30m_option.is_some() && ema3_30m_option.is_some() && sma30_30m_option.is_some() { -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); -// ema3_30m_vec = alldata.ema3_30m_data[ema3_30m_option.unwrap()].1.clone(); -// sma30_30m_vec = alldata.sma30_30m_data[sma30_30m_option.unwrap()].1.clone(); - -// if opclo_30m_vec.len() >= 5 && ema3_30m_vec.len() >= 1 && sma30_30m_vec.len() >= 1 { -// opclo_30m_vec.reverse(); -// opclo_30m_vec.truncate(5); -// opclo_30m_vec.reverse(); - -// cnt = 0; -// for element in &opclo_30m_vec { -// if element.candle_type == "DOWN" { -// cnt += 1; -// } -// } - -// if cnt >= 4 { -// let result = ema3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&EmaData { -// ema_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if ema3_30m_vec[T].ema_value > opclo_30m_vec.last().unwrap().opclo_price -// { -// let result = sma30_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&SmaData { -// sma_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if sma30_30m_vec[T].sma_value -// > opclo_30m_vec.last().unwrap().opclo_price -// { -// filtered_2nd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } -// } - -// // 3rd filtering: RSI3_30m < 15, RSI10_30m < 35 -// let mut rsi3_30m_vec: Vec = Vec::new(); -// let mut rsi10_30m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_3rd_symbols: Vec = Vec::new(); -// for symbol in filtered_2nd_symbols { -// let rsi3_30m_option = alldata.rsi3_30m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_30m_option = alldata.rsi10_30m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_30m_option.is_some() && rsi10_30m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_30m_vec = alldata.rsi3_30m_data[rsi3_30m_option.unwrap()].1.clone(); -// rsi10_30m_vec = alldata.rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_30m_vec.len() >= 1 && rsi10_30m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// let result = rsi3_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi3_30m_vec[T].rsi_value < 15.0 { -// let result = rsi10_30m_vec.binary_search_by_key( -// &opclo_30m_vec.last().unwrap().close_time, -// |&RsiData { -// rsi_value, -// close_time, -// }| close_time, -// ); -// match result { -// Ok(T) => { -// if rsi10_30m_vec[T].rsi_value < 35.0 { -// filtered_3rd_symbols.push(symbol); -// } -// } -// Err(E) => {} -// } -// } -// } -// Err(E) => {} -// } -// } -// } -// } - -// // 4th filtering: RSI3_1m < 10, RSI10_1m < 25 -// let mut rsi3_1m_vec: Vec = Vec::new(); -// let mut rsi10_1m_vec: Vec = Vec::new(); -// let mut opclo_30m_vec: Vec = Vec::new(); -// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) -// for symbol in filtered_3rd_symbols { -// let rsi3_1m_option = alldata.rsi3_1m_data.iter().position(|x| *x.0 == *symbol); -// let rsi10_1m_option = alldata.rsi10_1m_data.iter().position(|x| *x.0 == *symbol); -// let opclo_30m_option = alldata -// .rt_price_30m_vec -// .iter() -// .position(|x| *x.0 == *symbol); - -// if rsi3_1m_option.is_some() && rsi10_1m_option.is_some() && opclo_30m_option.is_some() { -// rsi3_1m_vec = alldata.rsi3_1m_data[rsi3_1m_option.unwrap()].1.clone(); -// rsi10_1m_vec = alldata.rsi10_1m_data[rsi10_1m_option.unwrap()].1.clone(); -// opclo_30m_vec = alldata.rt_price_30m_vec[opclo_30m_option.unwrap()] -// .1 -// .clone(); - -// if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// if rsi3_1m_vec.last().unwrap().rsi_value < 10.0 -// && rsi10_1m_vec.last().unwrap().rsi_value < 25.0 -// { -// filtered_4th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); -// } -// } - -// // if rsi3_1m_vec.len() >= 1 && rsi10_1m_vec.len() >= 1 && opclo_30m_vec.len() >= 1 { -// // let result = rsi3_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi3_1m_vec[T].rsi_value < 10.0 { -// // let result = rsi10_1m_vec.binary_search_by_key(&opclo_30m_vec.last().unwrap().close_time, |&RsiData{rsi_value, close_time}|close_time); -// // match result { -// // Ok(T) => { -// // if rsi10_1m_vec[T].rsi_value < 25.0 { -// // filtered_5th_symbols.push((symbol, opclo_30m_vec.last().unwrap().close_time)); -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// // }, -// // Err(E) => {} -// // } -// // } -// } -// } - -// // // 6. 5th filtering symbols: 30m current vol > 30m previous vol * 2 -// // let mut opclo_30m_vec: Vec = Vec::new(); -// // let mut filtered_4th_symbols: Vec<(String, u64)> = Vec::new(); // (symbol, closetime) -// // for element in filtered_3rd_symbols { -// // let opclo_30m_result = read_price_into_vector("30m", &element).await; - -// // if opclo_30m_result.is_ok() { -// // let opclo_30m_option = opclo_30m_result?; -// // if opclo_30m_option.is_some() { -// // opclo_30m_vec = opclo_30m_option.unwrap(); - -// // if opclo_30m_vec.len() >= 2 { -// // opclo_30m_vec.reverse(); -// // opclo_30m_vec.truncate(2); -// // opclo_30m_vec.reverse(); - -// // if 2.0 * opclo_30m_vec.first().unwrap().quote_asset_volume < opclo_30m_vec.last().unwrap().quote_asset_volume && opclo_30m_vec.last().unwrap().candle_type == "DOWN" { -// // filtered_4th_symbols.push((element, opclo_30m_vec.last().unwrap().close_time)); -// // } -// // } -// // } -// // } -// // } -// // println!("4: {:?}", filtered_4th_symbols); -// // 7. insert record into [pre_suggested_coin_list] -// insert_pre_suggested_coins(16, &filtered_4th_symbols, alldata).await; - -// Ok(()) -// } - -// useful functions for strategists -pub async fn get_current_price( - symbol: &String, - rt_price_vec: &Vec<(String, Vec)>, -) -> Option { - let index_result = rt_price_vec.iter().position(|x| *x.0 == *symbol); - match index_result { - Some(T) => { - if rt_price_vec[T].1.last().is_some() { - Some(rt_price_vec[T].1.last().unwrap().close_price) - } else { - None - } - } - None => None, - } -} - -async fn insert_pre_suggested_coins( - registerer: i32, - is_long: bool, - filtered_symbols: &Vec<(String, i64, f64)>, - alldata: &AllData, -) -> Result<(), Box> { - // Check the existance of record that is registered by this strategist - let mut dest_table_name = String::from("suggested_coin_list"); - let mut dest2_table_name = String::from("buy_ordered_coin_list"); - let mut dest3_table_name = String::from("pre_suggested_coin_list"); - let mut insert_table_name = String::from("pre_suggested_coin_list"); - let mut exists_condition_build = String::from("registerer="); - exists_condition_build.push_str(registerer.to_string().as_str()); - let mut exists_condition = Some(exists_condition_build); - let exists_result1 = exists_record(&dest_table_name, &exists_condition).await; - let exists_result2 = exists_record(&dest2_table_name, &exists_condition).await; - let exists_result3 = exists_record(&dest3_table_name, &exists_condition).await; - let insert_columns = vec![ - "symbol", - "close_time", - "suggested_price", - "current_price", - "registered_server_epoch", - "profit_percent", - "minimum_profit_percent", - "maximum_profit_percent", - "registerer", - "is_long", - ]; - - if exists_result1 == true && exists_result2 == true && exists_result3 == true { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - #[derive(FromRow)] - struct SelectData2 { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let mut select_columns2 = String::from("symbol, close_time"); - let select_data_structure2 = SelectData2 { - symbol: String::new(), - close_time: 0, - }; - let suggested_coin_list = try_select_record( - &dest_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - let ordered_coin_list = try_select_record( - &dest2_table_name, - &select_columns2, - &select_condition, - &select_data_structure2, - ) - .await?; - let pre_suggested_coin_list = try_select_record( - &dest3_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - - // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - for list_element in &ordered_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - for list_element in &pre_suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else if exists_result1 == true && exists_result2 == true && exists_result3 == false { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - #[derive(FromRow)] - struct SelectData2 { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let mut select_columns2 = String::from("symbol, close_time"); - let select_data_structure2 = SelectData2 { - symbol: String::new(), - close_time: 0, - }; - let suggested_coin_list = try_select_record( - &dest_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - let ordered_coin_list = try_select_record( - &dest2_table_name, - &select_columns2, - &select_condition, - &select_data_structure2, - ) - .await?; - - // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - for list_element in &ordered_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else if exists_result1 == true && exists_result2 == false && exists_result3 == true { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let suggested_coin_list = try_select_record( - &dest_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - let pre_suggested_coin_list = try_select_record( - &dest3_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - - // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - for list_element in &pre_suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else if exists_result1 == true && exists_result2 == false && exists_result3 == false { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let suggested_coin_list = try_select_record( - &dest_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - - // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else if exists_result1 == false && exists_result2 == true && exists_result3 == true { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - #[derive(FromRow)] - struct SelectData2 { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let mut select_columns2 = String::from("symbol, close_time"); - let select_data_structure2 = SelectData2 { - symbol: String::new(), - close_time: 0, - }; - let ordered_coin_list = try_select_record( - &dest2_table_name, - &select_columns2, - &select_condition, - &select_data_structure2, - ) - .await?; - let pre_suggested_coin_list = try_select_record( - &dest3_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - - // insert record without duplicate(registerer, close_time, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &ordered_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - for list_element in &pre_suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else if exists_result1 == false && exists_result2 == true && exists_result3 == false { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - #[derive(FromRow)] - struct SelectData2 { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let mut select_columns2 = String::from("symbol, close_time"); - let select_data_structure2 = SelectData2 { - symbol: String::new(), - close_time: 0, - }; - let ordered_coin_list = try_select_record( - &dest2_table_name, - &select_columns2, - &select_condition, - &select_data_structure2, - ) - .await?; - - // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &ordered_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else if exists_result1 == false && exists_result2 == false && exists_result3 == true { - // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] - #[derive(FromRow)] - struct SelectData { - symbol: String, - close_time: i64, - } - let mut select_columns = String::from("symbol, close_time"); - let mut condition_build = String::from("WHERE registerer="); - condition_build.push_str(registerer.to_string().as_str()); - let select_condition = Some(condition_build); - let select_data_structure = SelectData { - symbol: String::new(), - close_time: 0, - }; - let pre_suggested_coin_list = try_select_record( - &dest3_table_name, - &select_columns, - &select_condition, - &select_data_structure, - ) - .await?; - - // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] - for filtered_element in filtered_symbols { - let mut is_dupe = false; // initialize - - for list_element in &pre_suggested_coin_list { - if (filtered_element.0 == list_element.symbol) - && (filtered_element.1 == list_element.close_time) - { - is_dupe = true; - break; - } - } - - if is_dupe == false { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - } else { - for filtered_element in filtered_symbols { - let mut insert_values = vec![ - filtered_element.0.clone(), // symbol - filtered_element.1.to_string(), // close_time - filtered_element.2.to_string(), // suggested_price - filtered_element.2.to_string(), // current_price - server_epoch().await.to_string(), // registered_server_epoch - 0.0.to_string(), // profit_percent - 0.0.to_string(), // minimum_profit_percent - 0.0.to_string(), // maximum_profit_percent - registerer.to_string(), // registerer - ]; - - if is_long == true { - insert_values.push(1.to_string()); // is_long - } else { - insert_values.push(0.to_string()); // is_long - } - - insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; - } - } - - Ok(()) -} diff --git a/src/coin_health_check_team.rs b/src/coin_health_check_team/mod.rs similarity index 100% rename from src/coin_health_check_team.rs rename to src/coin_health_check_team/mod.rs diff --git a/src/database_control.rs b/src/database_control.rs index 13daa97..87c076b 100644 --- a/src/database_control.rs +++ b/src/database_control.rs @@ -748,7 +748,7 @@ where let mut conn_result = sqlx::mysql::MySqlConnection::connect(DB_URL).await; //retry connection until it will be done. while conn_result.is_err() { - sleep(Duration::from_millis(200)).await; + sleep(Duration::from_millis(50)).await; conn_result = sqlx::mysql::MySqlConnection::connect(DB_URL).await; } let mut conn = conn_result.unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 058276e..ba95b49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,13 +22,15 @@ pub enum RunningMode { TEST, REAL, } -pub const RUNNING_MODE: RunningMode = RunningMode::REAL; +pub const RUNNING_MODE: RunningMode = RunningMode::SIMUL; -mod coex; -mod coin_health_check_team; -mod database_control; -mod decimal_funcs; -mod server_health_check_team; -mod signal_association; -mod time_checking_team; -mod value_estimation_team; +pub mod coex; +pub mod coin_health_check_team; +pub mod database_control; +pub mod decimal_funcs; +pub mod server_health_check_team; +pub mod signal_association; +pub mod time_checking_team; +pub mod value_estimation_team; +pub mod strategy_team; +pub mod initialization; diff --git a/src/main.rs b/src/main.rs index 8e9e696..a98df64 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,7 @@ #![allow(unused)] #![allow(warnings)] -mod coex; -mod coin_health_check_team; -mod database_control; -mod decimal_funcs; -mod initialization; -mod server_health_check_team; -mod signal_association; -mod time_checking_team; -mod value_estimation_team; - -use crate::coex::order_team::*; -use crate::coex::strategy_team::AllData; +use crate::strategy_team::AllData; use crate::coin_health_check_team::*; use crate::request_candles::CandleData; use crate::request_others::{CoinPriceData, ExchangeInfo, TradeFee}; @@ -84,6 +73,7 @@ async fn main() -> Result<(), Box> { let tx_task24 = tx_task1.clone(); // for Task#24 let tx_task25 = tx_task1.clone(); // for Task#25 let tx_task26 = tx_task1.clone(); // for Task#26 + let tx_task27 = tx_task1.clone(); // for Task#27 let (tx1, mut rx1_1) = watch::channel(0); // local_epoch let mut rx1_2 = rx1_1.clone(); @@ -198,6 +188,7 @@ async fn main() -> Result<(), Box> { let mut rx2_exchange_info_data = rx_exchange_info_data.clone(); let mut rx3_exchange_info_data = rx_exchange_info_data.clone(); let mut rx4_exchange_info_data = rx_exchange_info_data.clone(); + let mut rx5_exchange_info_data = rx_exchange_info_data.clone(); { if RUNNING_MODE == RunningMode::REAL { @@ -268,99 +259,103 @@ async fn main() -> Result<(), Box> { match result { Some(1) => { - print!("\r1[■] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[■] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(2) => { - print!("\r1[ ] 2[■] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[■] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(3) => { - print!("\r1[ ] 2[ ] 3[■] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[■] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(4) => { - print!("\r1[ ] 2[ ] 3[ ] 4[■] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[■] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(5) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[■] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[■] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(6) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[■] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[■] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(7) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[■] 8[] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[■] 8[] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(8) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[■ 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[■ 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(9) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[■] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[■] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(12) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[■] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[■] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(13) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[■] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[■] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(14) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[■] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[■] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(15) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[■] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[■] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(16) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[■] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[■] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(17) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[■] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[■] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(18) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[■] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[■] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(19) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[■] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[■] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(20) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[■] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[■] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(21) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[■] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[■] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(22) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[■] 23[ ] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[■] 23[ ] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(23) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[■] 24[ ] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[■] 24[ ] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(24) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[■] 25[ ] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[■] 25[ ] 26[ ] 27[ ]"); io::stdout().flush(); } Some(25) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[■] 26[ ]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[■] 26[ ] 27[ ]"); io::stdout().flush(); } Some(26) => { - print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[■]"); + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[■] 27[ ]"); + io::stdout().flush(); + } + Some(27) => { + print!("\r1[ ] 2[ ] 3[ ] 4[ ] 5[ ] 6[ ] 7[ ] 8[ ] 9[ ] 12[ ] 13[ ] 14[ ] 15[ ] 16[ ] 17[ ] 18[ ] 19[ ] 20[ ] 21[ ] 22[ ] 23[ ] 24[ ] 25[ ] 26[ ] 27[■]"); io::stdout().flush(); } Some(_) => {} @@ -529,8 +524,51 @@ async fn main() -> Result<(), Box> { } }); - // Task#3: request 24h price changes, pick valid USDT Trades, monitor total_24h_change_profit_index, usdt_24h_change_profit_index, total_price_down_dist_index + // Task#13: request lot stepsize and ticksize tokio::task::spawn(async move { + let client = ClientBuilder::new() + .timeout(tokio::time::Duration::from_millis(3000)) + .build() + .unwrap(); + loop { + let mut exchange_info_data_temp: Vec = Vec::new(); + let mut result; + loop { + result = coin_health_check_team::request_others::request_exchange_infomation( + &client, + &mut exchange_info_data_temp, + ) + .await; + + // retry + if exchange_info_data_temp.len() == 0 { + sleep(Duration::from_secs(3)).await; + } else { + break; + } + } + + match result { + Ok(T) => { + tx_exchange_info_data.send_modify(|vec| *vec = exchange_info_data_temp); + tx_task13 + .send(13) + .expect("The mpsc channel has been closed."); + } + Err(E) => {} + } + sleep(Duration::from_secs(300)).await; // sleep for 5 mins + } + }); + + // Task#3: request 24h price changes, + // pick valid USDT Trades, + // filtering stop USDT Trades, + // monitor total_24h_change_profit_index, + // usdt_24h_change_profit_index, + // total_price_down_dist_index + tokio::task::spawn(async move { + sleep(Duration::from_secs(10)).await; let client = ClientBuilder::new() .timeout(tokio::time::Duration::from_millis(3000)) .build() @@ -541,9 +579,10 @@ async fn main() -> Result<(), Box> { let result = request_others::request_24hr_ticker_price_change_statistics(&client).await; match result { Ok(T) => { + let exchange_info_vec = rx5_exchange_info_data.borrow().clone(); let mut valid_usdt_trade_vec_temp: Vec = Vec::new(); let result = - monitors::collect_valid_usde_trade(&mut valid_usdt_trade_vec_temp).await; + monitors::collect_valid_usde_trade(&mut valid_usdt_trade_vec_temp, &exchange_info_vec).await; match result { Ok(T) => { @@ -881,43 +920,6 @@ async fn main() -> Result<(), Box> { }); } - // Task#13: request lot stepsize and ticksize - tokio::task::spawn(async move { - let client = ClientBuilder::new() - .timeout(tokio::time::Duration::from_millis(3000)) - .build() - .unwrap(); - loop { - let mut exchange_info_data_temp: Vec = Vec::new(); - let mut result; - loop { - result = coin_health_check_team::request_others::request_exchange_infomation( - &client, - &mut exchange_info_data_temp, - ) - .await; - - // retry - if exchange_info_data_temp.len() == 0 { - sleep(Duration::from_secs(3)).await; - } else { - break; - } - } - - match result { - Ok(T) => { - tx_exchange_info_data.send_modify(|vec| *vec = exchange_info_data_temp); - tx_task13 - .send(13) - .expect("The mpsc channel has been closed."); - } - Err(E) => {} - } - sleep(Duration::from_secs(1200)).await; // sleep for 20mins - } - }); - // Task#14: monitoring foreign exchange rate if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL { tokio::task::spawn(async move { @@ -1008,7 +1010,7 @@ async fn main() -> Result<(), Box> { // all_data.rt_price_1w_vec = rx3_rt_price_1w_vec.borrow().clone(); // all_data.rt_price_1mon_vec = rx3_rt_price_1mon_vec.borrow().clone(); - let result = coex::strategy_team::execute_strategists(&all_data).await; + let result = strategy_team::strategy_manager::execute_list_up_for_buy(&all_data).await; match result { Ok(T) => { @@ -1017,7 +1019,7 @@ async fn main() -> Result<(), Box> { .expect("The mpsc channel has been closed."); } Err(E) => { - eprintln!("Couldn't execute strategists."); + // eprintln!("Couldn't execute strategists."); } } @@ -1382,6 +1384,34 @@ async fn main() -> Result<(), Box> { } }); + // Task#27: update kelly_criterion + tokio::task::spawn(async move { + let mut elapsed_time = 0; + loop { + let instant = Instant::now(); + let result = + coex::assets_managing_team::update_kelly_criterion().await; + + // send Task#0 a message to notify running on + match result { + Ok(T) => { + tx_task27 + .send(27) + .expect("The mpsc channel has been closed."); + } + Err(E) => { + println!("{}", E); + } + } + + // sleep as much as the loop recurs per 1 minutes + elapsed_time = instant.elapsed().as_secs(); + if 60 > elapsed_time { + sleep(Duration::from_secs((60 - elapsed_time) as u64)).await; + } + } + }); + loop { // println!("test limit order 실행"); // let client = ClientBuilder::new().timeout(Duration::from_millis(1000)).build().unwrap(); diff --git a/src/signal_association.rs b/src/signal_association/mod.rs similarity index 100% rename from src/signal_association.rs rename to src/signal_association/mod.rs diff --git a/src/strategy_team/mod.rs b/src/strategy_team/mod.rs new file mode 100644 index 0000000..7467a9f --- /dev/null +++ b/src/strategy_team/mod.rs @@ -0,0 +1,58 @@ +pub mod strategy_manager; +pub mod strategy_001; +pub mod strategy_002; +pub mod strategy_003; +pub mod strategy_004; +pub mod strategy_005; +pub mod strategy_006; + +use std::{sync::Arc}; +use crate::database_control::*; +use crate::value_estimation_team::datapoints::price_data::RealtimePriceData; +use crate::value_estimation_team::indicators::macd::{ema_macd, EmaMacd}; +use crate::value_estimation_team::indicators::rsi::{rsi, RsiData}; +use crate::value_estimation_team::indicators::sma::{sma, SmaData}; +use crate::value_estimation_team::indicators::ema::{ema, EmaData}; +use crate::value_estimation_team::indicators::bollingerband::{bollingerband, BollingerBandData}; +use crate::value_estimation_team::indicators::stoch_rsi::{stoch_rsi, StochRsiData}; +use crate::value_estimation_team::indicators::supertrend::{supertrend, SupertrendData}; +use crate::value_estimation_team::indicators::heatmap_volume::{ + heatmap_volume, HeatMapLevel, HeatmapVolumeData, +}; +use futures::future::try_join_all; +use sqlx::FromRow; +use tokio::sync::Mutex; + +#[derive(Debug)] +pub struct AllData { + pub valid_symbol_vec: Vec, + pub rt_price_1m_vec: Vec<(String, Vec)>, + pub rt_price_30m_vec: Vec<(String, Vec)>, + pub rt_price_1d_vec: Vec<(String, Vec)>, + pub rt_price_1w_vec: Vec<(String, Vec)>, + pub rt_price_1mon_vec: Vec<(String, Vec)>, +} +impl AllData { + pub fn new() -> AllData { + let a = AllData { + valid_symbol_vec: Vec::new(), + rt_price_1m_vec: Vec::new(), + rt_price_30m_vec: Vec::new(), + rt_price_1d_vec: Vec::new(), + rt_price_1w_vec: Vec::new(), + rt_price_1mon_vec: Vec::new(), + }; + a + } +} + +#[derive(Debug, FromRow)] +pub struct TimeData { + pub server_epoch: u64, + pub local_epoch: u64, + pub epoch_difference: i64, + pub server_ymdhs: String, + pub local_ymdhs: String, + pub last_server_epoch: u64, + pub last_server_ymdhs: String, +} diff --git a/src/strategy_team/strategy_001.rs b/src/strategy_team/strategy_001.rs new file mode 100644 index 0000000..46e0412 --- /dev/null +++ b/src/strategy_team/strategy_001.rs @@ -0,0 +1,424 @@ +// pub async fn strategist_001( +// alldata: &AllData, +// ) -> Result<(), Box> { +// // print rt_price for debugging +// // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); +// // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); + +// // // 1st filtering: supertrend(ATR period 10, multiplier: 1.3, 30m close price), the area should be in SELL area. +// // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); +// // let mut filtered_2nd_symbols_arc: Arc>> = +// // Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) +// // let mut task_vec = Vec::new(); +// // let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); +// // for symbol in valid_symbol_vec_c { +// // let mut opclo_30m_vec: Vec = Vec::new(); +// // let mut supertrend_vec: Vec = Vec::new(); +// // let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// // let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); +// // task_vec.push(tokio::spawn(async move { +// // let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); +// // let supertrend_option_30m = +// // supertrend(&symbol, &rt_price_30m_vec_c, 10, 1.3, true).await; + +// // if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { +// // opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); +// // supertrend_vec = supertrend_option_30m.unwrap(); + +// // if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { +// // let supertrend_search_result = supertrend_vec.binary_search_by_key( +// // &opclo_30m_vec.last().unwrap().close_time, +// // |SupertrendData { +// // band_value, +// // signal, +// // area, +// // close_time, +// // }| *close_time, +// // ); +// // if supertrend_search_result.is_ok() { +// // if supertrend_vec[supertrend_search_result.unwrap()] +// // .area +// // .contains("DOWN") +// // { +// // let mut filtered_2nd_symbols_lock = +// // filtered_2nd_symbols_arc_c.lock().await; +// // filtered_2nd_symbols_lock +// // .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); +// // } +// // } +// // } +// // } +// // })); +// // } +// // try_join_all(task_vec).await?; + +// // 1st filtering: making basic form +// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_2nd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); +// let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); +// for symbol in valid_symbol_vec_c { +// let mut opclo_30m_vec: Vec = Vec::new(); + +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); + +// if opclo_30m_option.is_some() { +// opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let mut filtered_2nd_symbols_lock = +// filtered_2nd_symbols_arc_c.lock().await; +// filtered_2nd_symbols_lock +// .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); +// } +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 2nd filtering: lookup tables if the tradepair is already there +// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); +// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); +// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); +// let inspect_table_name_4 = String::from("suggested_coin_list"); + +// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_3rd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); + +// let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); +// for element in filtered_2nd_iter { +// let mut exists_condition_build = String::from("symbol=\'"); +// exists_condition_build.push_str(element.0.as_str()); +// exists_condition_build.push_str("\' AND registerer="); +// exists_condition_build.push_str(1.to_string().as_str()); +// // exists_condition_build.push_str("\' AND close_time="); +// // exists_condition_build.push_str(element.1.to_string().as_str()); +// let exists_condition = Some(exists_condition_build); +// let exists_condition_c = exists_condition.clone(); +// let inspect_table_name_1_c = inspect_table_name_1.clone(); +// let inspect_table_name_2_c = inspect_table_name_2.clone(); +// let inspect_table_name_3_c = inspect_table_name_3.clone(); +// let inspect_table_name_4_c = inspect_table_name_4.clone(); +// let element_c = element.clone(); +// let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let inspect_result_1 = +// exists_record(&inspect_table_name_1_c, &exists_condition_c).await; +// let inspect_result_2 = +// exists_record(&inspect_table_name_2_c, &exists_condition_c).await; +// let inspect_result_3 = +// exists_record(&inspect_table_name_3_c, &exists_condition_c).await; +// let inspect_result_4 = +// exists_record(&inspect_table_name_4_c, &exists_condition_c).await; + +// if inspect_result_1 == false +// && inspect_result_2 == false +// && inspect_result_3 == false +// && inspect_result_4 == false +// { +// let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; +// filtered_3rd_symbols_lock.push(element_c); +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 3rd filtering: BollingerBand (length 10, stddev: 2.5, 30m close price) the current price should be under the lowerband of BB. +// let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); +// let sma10_30m_data: Vec<(String, Vec)> = sma( +// 10, +// &alldata.rt_price_30m_vec, +// &filtered_3rd_symbols_c, +// ) +// .await?; + +// let bb10_30m_data: Vec<(String, Vec)> = +// bollingerband( +// 10, +// 3.0, +// &sma10_30m_data, +// &alldata.rt_price_30m_vec, +// &filtered_3rd_symbols_c, +// ) +// .await?; + +// let mut task_vec = Vec::new(); +// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_4th_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) +// for element in filtered_3rd_symbols_c { +// let mut bb10_30m_vec: Vec = Vec::new(); +// let bb10_30m_option = bb10_30m_data.iter().position(|x| *x.0 == element.0); +// let bb10_30m_option_c = bb10_30m_option.clone(); +// let element_c = element.clone(); +// let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); + +// if bb10_30m_option_c.is_some() { +// bb10_30m_vec = bb10_30m_data[bb10_30m_option_c.unwrap()].1.clone(); + +// if bb10_30m_vec.len() >= 3 { +// let bb10_30m_vec_c = bb10_30m_vec.clone(); +// let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec) +// .await +// .unwrap(); +// task_vec.push(tokio::spawn(async move { +// let bb_search_result = bb10_30m_vec_c.binary_search_by_key( +// &element_c.1, +// |&BollingerBandData { +// sma, +// upperband, +// lowerband, +// close_time, +// }| close_time, +// ); +// if bb_search_result.is_ok() { +// if bb10_30m_vec_c[bb_search_result.unwrap()].lowerband > current_price { +// let mut filtered_4th_symbols_lock = +// filtered_4th_symbols_arc_c.lock().await; +// filtered_4th_symbols_lock.push(element_c); +// } +// } +// })); +// } +// } +// } +// try_join_all(task_vec).await?; + +// // 4th filtering: the current price should be lower than lowest price from the latest 20 candles. +// let mut task_vec = Vec::new(); +// let filtered_4th_symbols_c = filtered_4th_symbols_arc.lock().await.clone(); +// let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_5th_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_5th_symbols)); // (symbol, closetime) +// for element in filtered_4th_symbols_c { +// let rt_price_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == element.0); +// let element_c = element.clone(); +// let filtered_5th_symbols_arc_c = Arc::clone(&filtered_5th_symbols_arc); + +// if rt_price_30m_option.is_some() { +// let mut rt_price_30m_vec_c = alldata.rt_price_30m_vec[rt_price_30m_option.unwrap()].1.clone(); +// let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec) +// .await +// .unwrap(); + +// task_vec.push(tokio::spawn(async move { +// if rt_price_30m_vec_c.len() >= 21 { +// rt_price_30m_vec_c.pop(); +// rt_price_30m_vec_c.reverse(); +// rt_price_30m_vec_c.truncate(20); + +// let lowest_price_option = rt_price_30m_vec_c.iter() +// .enumerate() +// .min_by(|(_, a), (_, b)| { +// a.low_price +// .partial_cmp(&b.low_price) +// .expect("Nan was forbidden.") +// }) +// .map(|(index, _)| index); + +// if lowest_price_option.is_some() { +// let lowest_price = rt_price_30m_vec_c[lowest_price_option.unwrap()].low_price; +// if lowest_price > current_price { +// let mut filtered_5th_symbols_lock = +// filtered_5th_symbols_arc_c.lock().await; +// filtered_5th_symbols_lock.push(element_c); +// } +// } +// } +// })); +// } +// } +// try_join_all(task_vec).await?; + +// // 5th filtering: RSI (length: 10, 30m close price) the current index should be lower than 30. +// let filtered_5th_symbol_c = filtered_5th_symbols_arc.lock().await.clone(); +// let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( +// 10, +// &alldata.rt_price_30m_vec, +// &filtered_5th_symbol_c, +// ) +// .await?; +// let mut task_vec = Vec::new(); +// let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// let mut filtered_6th_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_6th_symbols)); // (symbol, closetime) + +// for element in filtered_5th_symbol_c { +// let rsi10_30m_option = rsi10_30m_data.iter().position(|x| *x.0 == element.0); +// let filtered_6th_symbols_arc_c = Arc::clone(&filtered_6th_symbols_arc); + +// if rsi10_30m_option.is_some() { +// let mut rsi10_30m_vec = rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone(); + +// if rsi10_30m_vec.len() >= 3 { +// let element_c = element.clone(); +// task_vec.push(tokio::spawn(async move { +// let rsi_search_result = rsi10_30m_vec.binary_search_by_key( +// &element.1, +// |&RsiData { +// rsi_value, +// close_time, +// }| close_time, +// ); +// if rsi_search_result.is_ok() { +// if rsi10_30m_vec[rsi_search_result.unwrap()].rsi_value <= 20.0 { +// let mut filtered_6th_symbols_lock = +// filtered_6th_symbols_arc_c.lock().await; +// filtered_6th_symbols_lock.push(element_c); + +// } +// } +// })); +// } +// } +// } +// try_join_all(task_vec).await?; + +// // 6th filtering: StochRSI (RSI length: 14, Stoch length: 14, smooth k: 3, smooth d: 3) smooth kn <= 10, kn-1 <= 25.0 +// let filtered_6th_symbol_c = filtered_6th_symbols_arc.lock().await.clone(); +// let mut rsi14_30m_data: Vec<(String, Vec)> = rsi( +// 14, +// &alldata.rt_price_30m_vec, +// &filtered_6th_symbol_c, +// ) +// .await?; +// let stoch_rsi_data = stoch_rsi(&rsi14_30m_data, 14, 3, 3).await?; +// let mut stoch_rsi14_30m_vec: Vec = Vec::new(); +// let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_6th_symbol_c { +// let stoch_rsi14_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); + +// if stoch_rsi14_30m_option.is_some() { +// stoch_rsi14_30m_vec = stoch_rsi_data[stoch_rsi14_30m_option.unwrap()].1.clone(); + +// if stoch_rsi14_30m_vec.len() >= 3 { +// let stoch_rsi_search_result = stoch_rsi14_30m_vec.binary_search_by_key( +// &element.1, +// |&StochRsiData { +// k, +// d, +// close_time, +// }| close_time, +// ); +// if stoch_rsi_search_result.is_ok() { +// if stoch_rsi14_30m_vec[stoch_rsi_search_result.unwrap()].k <= 10.0 && stoch_rsi14_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= 25.0 { +// filtered_7th_symbols.push(element); +// } +// } +// } +// } +// } + +// // 7th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least. +// let mut filtered_8th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_7th_symbols { +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let heatmap_volume_option = +// heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) +// .await; +// if heatmap_volume_option.is_some() { +// let heatmap_volume_vec = heatmap_volume_option.unwrap(); +// let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( +// &element.1, +// |HeatmapVolumeData { +// heatmap_value, +// heatmap_level, +// close_time, +// }| *close_time, +// ); +// if heatmap_search_result.is_ok() { +// if heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::Medium +// || +// heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::High +// || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::ExtraHigh +// { +// filtered_8th_symbols.push(element); +// } +// } +// } +// } +// } +// } + +// // final job: adding price information to filtered results +// let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) +// let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); +// let mut task_vec = Vec::new(); +// for element in filtered_8th_symbols { +// let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + +// let elememt_c = element.clone(); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// if rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .is_some() +// { +// let mut filtered_symbols_lock: tokio::sync::MutexGuard< +// '_, +// Vec<(String, i64, f64)>, +// > = filtered_symbols_arc_c.lock().await; +// filtered_symbols_lock.push(( +// elememt_c.0, +// elememt_c.1, +// rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .unwrap() +// .close_price, +// )); +// } +// } +// })); +// } + +// try_join_all(task_vec).await?; + +// // 6th filtering condition: MACD +// // let mut opclo_30m_vec: Vec = Vec::new(); +// // let mut ema3_1d_vec: &Vec = &Vec::new(); +// // let mut ema10_1d_vec: &Vec = &Vec::new(); + +// // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// // for element in filtered_6th_symbols { +// // let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0); +// // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0); + +// // if ema3_1d_option.is_some() && ema10_1d_option.is_some() { +// // ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1; +// // ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1; + +// // if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { +// // let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; +// // // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); + +// // // if macd_search_result.is_ok() { +// // if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 { +// // filtered_7th_symbols.push(element); +// // } +// // // } +// // } +// // } +// // } +// let a = filtered_symbols_arc.lock().await.clone(); +// insert_pre_suggested_coins(1, false, &a, alldata).await; + +// Ok(()) +// } \ No newline at end of file diff --git a/src/strategy_team/strategy_002.rs b/src/strategy_team/strategy_002.rs new file mode 100644 index 0000000..1d0c2d4 --- /dev/null +++ b/src/strategy_team/strategy_002.rs @@ -0,0 +1,277 @@ +// pub async fn strategist_002( +// alldata: &AllData, +// ) -> Result<(), Box> { +// // print rt_price for debugging +// // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); +// // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); + +// // 1st filtering: making basic form +// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_2nd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); +// let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); +// for symbol in valid_symbol_vec_c { +// let mut opclo_30m_vec: Vec = Vec::new(); + +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); + +// if opclo_30m_option.is_some() { +// opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let mut filtered_2nd_symbols_lock = +// filtered_2nd_symbols_arc_c.lock().await; +// filtered_2nd_symbols_lock +// .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); +// } +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 2nd filtering: lookup tables if the tradepair is already there +// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); +// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); +// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); +// let inspect_table_name_4 = String::from("suggested_coin_list"); + +// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_3rd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); + +// let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); +// for element in filtered_2nd_iter { +// let mut exists_condition_build = String::from("symbol=\'"); +// exists_condition_build.push_str(element.0.as_str()); +// exists_condition_build.push_str("\' AND registerer="); +// exists_condition_build.push_str(2.to_string().as_str()); +// // exists_condition_build.push_str("\' AND close_time="); +// // exists_condition_build.push_str(element.1.to_string().as_str()); + +// let exists_condition = Some(exists_condition_build); +// let exists_condition_c = exists_condition.clone(); +// let inspect_table_name_1_c = inspect_table_name_1.clone(); +// let inspect_table_name_2_c = inspect_table_name_2.clone(); +// let inspect_table_name_3_c = inspect_table_name_3.clone(); +// let inspect_table_name_4_c = inspect_table_name_4.clone(); +// let element_c = element.clone(); +// let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let inspect_result_1 = +// exists_record(&inspect_table_name_1_c, &exists_condition_c).await; +// let inspect_result_2 = +// exists_record(&inspect_table_name_2_c, &exists_condition_c).await; +// let inspect_result_3 = +// exists_record(&inspect_table_name_3_c, &exists_condition_c).await; +// let inspect_result_4 = +// exists_record(&inspect_table_name_4_c, &exists_condition_c).await; + +// if inspect_result_1 == false +// && inspect_result_2 == false +// && inspect_result_3 == false +// && inspect_result_4 == false +// { +// let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; +// filtered_3rd_symbols_lock.push(element_c); +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 3rd filtering: EMA30 > EMA 150 +// let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); +// let ema30_30m_data: Vec<(String, Vec)> = ema( +// 30, +// &alldata.rt_price_30m_vec, +// &filtered_3rd_symbols_c, +// ) +// .await?; +// let ema150_30m_data: Vec<(String, Vec)> = ema( +// 150, +// &alldata.rt_price_30m_vec, +// &filtered_3rd_symbols_c, +// ) +// .await?; + +// let mut task_vec = Vec::new(); +// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_4th_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) +// for element in filtered_3rd_symbols_c { +// let mut ema30_30m_vec: Vec = Vec::new(); +// let mut ema150_30m_vec: Vec = Vec::new(); +// let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0); +// let ema30_30m_option_c = ema30_30m_option.clone(); +// let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0); +// let ema150_30m_option_c = ema150_30m_option.clone(); +// let element_c = element.clone(); +// let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); + +// if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() { +// ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone(); +// ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone(); + +// if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 { +// let ema30_30m_vec_c = ema30_30m_vec.clone(); +// let ema150_30m_vec_c = ema150_30m_vec.clone(); + +// task_vec.push(tokio::spawn(async move { +// let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( +// &element_c.1, +// |&EmaData { +// ema_value, +// close_time, +// }| close_time, +// ); +// let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( +// &element_c.1, +// |&EmaData { +// ema_value, +// close_time, +// }| close_time, +// ); + +// if ema30_search_result.is_ok() && ema150_search_result.is_ok() { +// if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value +// { +// let mut filtered_4th_symbols_lock = +// filtered_4th_symbols_arc_c.lock().await; +// filtered_4th_symbols_lock.push(element_c); +// } +// } +// })); +// } +// } +// } +// try_join_all(task_vec).await?; + +// // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth dn == 0, kn == 0, kn-1 < 5 +// let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone(); +// let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( +// 10, +// &alldata.rt_price_30m_vec, +// &filtered_4th_symbol_c, +// ) +// .await?; +// let stoch_rsi_data = stoch_rsi(&rsi10_30m_data, 10, 3, 3).await?; +// let mut stoch_rsi10_30m_vec: Vec = Vec::new(); +// let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_4th_symbol_c { +// let stoch_rsi10_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); + +// if stoch_rsi10_30m_option.is_some() { +// stoch_rsi10_30m_vec = stoch_rsi_data[stoch_rsi10_30m_option.unwrap()].1.clone(); + +// if stoch_rsi10_30m_vec.len() >= 3 { +// let stoch_rsi_search_result = stoch_rsi10_30m_vec.binary_search_by_key( +// &element.1, +// |&StochRsiData { +// k, +// d, +// close_time, +// }| close_time, +// ); +// if stoch_rsi_search_result.is_ok() { +// if stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k <= 5.0 && +// stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].d <= 5.0 && +// stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= 5.0 { +// filtered_5th_symbols.push(element); +// } +// } +// } +// } +// } + +// // 7th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least. +// let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_5th_symbols { +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let heatmap_volume_option = +// heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) +// .await; +// if heatmap_volume_option.is_some() { +// let heatmap_volume_vec = heatmap_volume_option.unwrap(); +// let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( +// &element.1, +// |HeatmapVolumeData { +// heatmap_value, +// heatmap_level, +// close_time, +// }| *close_time, +// ); +// if heatmap_search_result.is_ok() { +// if +// // heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// // == HeatMapLevel::Medium +// // || +// heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::High +// || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::ExtraHigh +// { +// filtered_6th_symbols.push(element); +// } +// } +// } +// } +// } +// } + +// // final job: adding price information to filtered results +// let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) +// let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); +// let mut task_vec = Vec::new(); +// for element in filtered_6th_symbols { +// let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + +// let elememt_c = element.clone(); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// if rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .is_some() +// { +// let mut filtered_symbols_lock: tokio::sync::MutexGuard< +// '_, +// Vec<(String, i64, f64)>, +// > = filtered_symbols_arc_c.lock().await; +// filtered_symbols_lock.push(( +// elememt_c.0, +// elememt_c.1, +// rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .unwrap() +// .close_price, +// )); +// } +// } +// })); +// } + +// try_join_all(task_vec).await?; + +// let a = filtered_symbols_arc.lock().await.clone(); +// insert_pre_suggested_coins(2, false, &a, alldata).await; + +// Ok(()) +// } diff --git a/src/strategy_team/strategy_003.rs b/src/strategy_team/strategy_003.rs new file mode 100644 index 0000000..9ae9897 --- /dev/null +++ b/src/strategy_team/strategy_003.rs @@ -0,0 +1,286 @@ +use super::{AllData, RealtimePriceData, Mutex, Arc, try_join_all, exists_record, StochRsiData, EmaData, SupertrendData, RsiData, stoch_rsi, ema, rsi, supertrend}; + +pub async fn list_up_for_buy( + alldata: &AllData, +) -> Result<(), Box> { + // print rt_price for debugging + // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); + // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); + + // 1st filtering: supertrend(ATR period 100, multiplier: 6.0, 30m close price), the area should be in UP area. + let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); + let mut filtered_2nd_symbols_arc: Arc>> = + Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) + let mut task_vec = Vec::new(); + let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); + for symbol in valid_symbol_vec_c { + let mut opclo_30m_vec: Vec = Vec::new(); + let mut supertrend_vec: Vec = Vec::new(); + let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); + task_vec.push(tokio::spawn(async move { + let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); + let supertrend_option_30m = + supertrend(&symbol, &rt_price_30m_vec_c, 100, 6.0, true).await; + + if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { + opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + supertrend_vec = supertrend_option_30m.unwrap(); + + if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { + let supertrend_search_result = supertrend_vec.binary_search_by_key( + &opclo_30m_vec.last().unwrap().close_time, + |SupertrendData { + band_value, + signal, + area, + close_time, + }| *close_time, + ); + if supertrend_search_result.is_ok() { + if supertrend_vec[supertrend_search_result.unwrap()] + .area + .contains("UP") + { + let mut filtered_2nd_symbols_lock = + filtered_2nd_symbols_arc_c.lock().await; + filtered_2nd_symbols_lock + .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); + } + } + } + } + })); + } + try_join_all(task_vec).await?; + + // 2nd filtering: lookup tables if the tradepair is already there + let inspect_table_name_1 = String::from("buy_ordered_coin_list"); + let inspect_table_name_2 = String::from("sell_ordered_coin_list"); + let inspect_table_name_3 = String::from("pre_suggested_coin_list"); + let inspect_table_name_4 = String::from("suggested_coin_list"); + + let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); + let mut filtered_3rd_symbols_arc: Arc>> = + Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) + let mut task_vec = Vec::new(); + + let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); + for element in filtered_2nd_iter { + let mut exists_condition_build = String::from("symbol=\'"); + exists_condition_build.push_str(element.0.as_str()); + exists_condition_build.push_str("\' AND registerer="); + exists_condition_build.push_str(3.to_string().as_str()); + // exists_condition_build.push_str("\' AND close_time="); + // exists_condition_build.push_str(element.1.to_string().as_str()); + let exists_condition = Some(exists_condition_build); + let exists_condition_c = exists_condition.clone(); + let inspect_table_name_1_c = inspect_table_name_1.clone(); + let inspect_table_name_2_c = inspect_table_name_2.clone(); + let inspect_table_name_3_c = inspect_table_name_3.clone(); + let inspect_table_name_4_c = inspect_table_name_4.clone(); + let element_c = element.clone(); + let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); + task_vec.push(tokio::spawn(async move { + let inspect_result_1 = + exists_record(&inspect_table_name_1_c, &exists_condition_c).await; + let inspect_result_2 = + exists_record(&inspect_table_name_2_c, &exists_condition_c).await; + let inspect_result_3 = + exists_record(&inspect_table_name_3_c, &exists_condition_c).await; + let inspect_result_4 = + exists_record(&inspect_table_name_4_c, &exists_condition_c).await; + + if inspect_result_1 == false + && inspect_result_2 == false + && inspect_result_3 == false + && inspect_result_4 == false + { + let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; + filtered_3rd_symbols_lock.push(element_c); + } + })); + } + try_join_all(task_vec).await?; + + // 3rd filtering: EMA30 > EMA 150 + let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); + let ema30_30m_data: Vec<(String, Vec)> = ema( + 30, + &alldata.rt_price_30m_vec, + &filtered_3rd_symbols_c, + ) + .await?; + let ema150_30m_data: Vec<(String, Vec)> = ema( + 150, + &alldata.rt_price_30m_vec, + &filtered_3rd_symbols_c, + ) + .await?; + + let mut task_vec = Vec::new(); + let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); + let mut filtered_4th_symbols_arc: Arc>> = + Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) + for element in filtered_3rd_symbols_c { + let mut ema30_30m_vec: Vec = Vec::new(); + let mut ema150_30m_vec: Vec = Vec::new(); + let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0); + let ema30_30m_option_c = ema30_30m_option.clone(); + let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0); + let ema150_30m_option_c = ema150_30m_option.clone(); + let element_c = element.clone(); + let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); + + if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() { + ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone(); + ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone(); + + if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 { + let ema30_30m_vec_c = ema30_30m_vec.clone(); + let ema150_30m_vec_c = ema150_30m_vec.clone(); + + task_vec.push(tokio::spawn(async move { + let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( + &element_c.1, + |&EmaData { + ema_value, + close_time, + }| close_time, + ); + let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( + &element_c.1, + |&EmaData { + ema_value, + close_time, + }| close_time, + ); + + if ema30_search_result.is_ok() && ema150_search_result.is_ok() { + if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && + ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && + ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && + ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && + ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && + ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && + ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value + { + let mut filtered_4th_symbols_lock = + filtered_4th_symbols_arc_c.lock().await; + filtered_4th_symbols_lock.push(element_c); + } + } + })); + } + } + } + try_join_all(task_vec).await?; + + // 4th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) 20 > k > kn-1 > kn-2 > kn-3, + let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone(); + let mut rsi10_30m_data: Vec<(String, Vec)> = rsi( + 10, + &alldata.rt_price_30m_vec, + &filtered_4th_symbol_c, + ) + .await?; + let stoch_rsi_data = stoch_rsi(&rsi10_30m_data, 10, 3, 3).await?; + let mut stoch_rsi10_30m_vec: Vec = Vec::new(); + let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) + for element in filtered_4th_symbol_c { + let stoch_rsi10_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); + + if stoch_rsi10_30m_option.is_some() { + stoch_rsi10_30m_vec = stoch_rsi_data[stoch_rsi10_30m_option.unwrap()].1.clone(); + + if stoch_rsi10_30m_vec.len() >= 3 { + let stoch_rsi_search_result = stoch_rsi10_30m_vec.binary_search_by_key( + &element.1, + |&StochRsiData { + k, + d, + close_time, + }| close_time, + ); + if stoch_rsi_search_result.is_ok() { + if 10.0 > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k && + stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k > stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k && + stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-2].k && + stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-2].k <= stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-3].k { + filtered_5th_symbols.push(element); + } + } + } + } + } + + // final job: adding price information to filtered results + let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) + let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); + let mut task_vec = Vec::new(); + for element in filtered_5th_symbols { + let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); + let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + + let elememt_c = element.clone(); + task_vec.push(tokio::spawn(async move { + let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); + if opclo_30m_option.is_some() { + if rt_price_30m_vec_c[opclo_30m_option.unwrap()] + .1 + .last() + .is_some() + { + let mut filtered_symbols_lock: tokio::sync::MutexGuard< + '_, + Vec<(String, i64, f64)>, + > = filtered_symbols_arc_c.lock().await; + filtered_symbols_lock.push(( + elememt_c.0, + elememt_c.1, + rt_price_30m_vec_c[opclo_30m_option.unwrap()] + .1 + .last() + .unwrap() + .close_price, + )); + } + } + })); + } + + try_join_all(task_vec).await?; + + // TODO: abnormal price filtering (too high current price) + + // 6th filtering condition: MACD + // let mut opclo_30m_vec: Vec = Vec::new(); + // let mut ema3_1d_vec: &Vec = &Vec::new(); + // let mut ema10_1d_vec: &Vec = &Vec::new(); + + // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) + // for element in filtered_6th_symbols { + // let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0); + // let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0); + + // if ema3_1d_option.is_some() && ema10_1d_option.is_some() { + // ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1; + // ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1; + + // if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { + // let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; + // // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); + + // // if macd_search_result.is_ok() { + // if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 { + // filtered_7th_symbols.push(element); + // } + // // } + // } + // } + // } + let a = filtered_symbols_arc.lock().await.clone(); + super::strategy_manager::insert_pre_suggested_coins(3, false, &a, alldata).await; + + Ok(()) +} \ No newline at end of file diff --git a/src/strategy_team/strategy_004.rs b/src/strategy_team/strategy_004.rs new file mode 100644 index 0000000..5a6f4fc --- /dev/null +++ b/src/strategy_team/strategy_004.rs @@ -0,0 +1,268 @@ +// pub async fn strategist_004( +// alldata: &AllData, +// ) -> Result<(), Box> { +// // print rt_price for debugging +// // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); +// // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); + +// // 1st filtering: supertrend(ATR period 10, multiplier: 2.0, 30m close price), the area should be in UP area. +// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_2nd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); +// let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); +// for symbol in valid_symbol_vec_c { +// let mut opclo_30m_vec: Vec = Vec::new(); +// let mut supertrend_vec: Vec = Vec::new(); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); +// let supertrend_option_30m = +// supertrend(&symbol, &rt_price_30m_vec_c, 10, 2.0, true).await; + +// if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { +// opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); +// supertrend_vec = supertrend_option_30m.unwrap(); + +// if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { +// let supertrend_search_result = supertrend_vec.binary_search_by_key( +// &opclo_30m_vec.last().unwrap().close_time, +// |SupertrendData { +// band_value, +// signal, +// area, +// close_time, +// }| *close_time, +// ); +// if supertrend_search_result.is_ok() { +// if supertrend_vec[supertrend_search_result.unwrap()] +// .area +// .contains("UP") +// { +// let mut filtered_2nd_symbols_lock = +// filtered_2nd_symbols_arc_c.lock().await; +// filtered_2nd_symbols_lock +// .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); +// } +// } +// } +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 2nd filtering: lookup tables if the tradepair is already there +// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); +// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); +// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); +// let inspect_table_name_4 = String::from("suggested_coin_list"); + +// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_3rd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); + +// let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); +// for element in filtered_2nd_iter { +// let mut exists_condition_build = String::from("symbol=\'"); +// exists_condition_build.push_str(element.0.as_str()); +// exists_condition_build.push_str("\' AND registerer="); +// exists_condition_build.push_str(4.to_string().as_str()); +// // exists_condition_build.push_str("\' AND close_time="); +// // exists_condition_build.push_str(element.1.to_string().as_str()); +// let exists_condition = Some(exists_condition_build); +// let exists_condition_c = exists_condition.clone(); +// let inspect_table_name_1_c = inspect_table_name_1.clone(); +// let inspect_table_name_2_c = inspect_table_name_2.clone(); +// let inspect_table_name_3_c = inspect_table_name_3.clone(); +// let inspect_table_name_4_c = inspect_table_name_4.clone(); +// let element_c = element.clone(); +// let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let inspect_result_1 = +// exists_record(&inspect_table_name_1_c, &exists_condition_c).await; +// let inspect_result_2 = +// exists_record(&inspect_table_name_2_c, &exists_condition_c).await; +// let inspect_result_3 = +// exists_record(&inspect_table_name_3_c, &exists_condition_c).await; +// let inspect_result_4 = +// exists_record(&inspect_table_name_4_c, &exists_condition_c).await; + +// if inspect_result_1 == false +// && inspect_result_2 == false +// && inspect_result_3 == false +// && inspect_result_4 == false +// { +// let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; +// filtered_3rd_symbols_lock.push(element_c); +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 3rd filtering: EMA30 >= EMA 150 +// let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); +// let ema30_30m_data: Vec<(String, Vec)> = ema( +// 30, +// &alldata.rt_price_30m_vec, +// &filtered_3rd_symbols_c, +// ) +// .await?; +// let ema150_30m_data: Vec<(String, Vec)> = ema( +// 150, +// &alldata.rt_price_30m_vec, +// &filtered_3rd_symbols_c, +// ) +// .await?; + +// let mut task_vec = Vec::new(); +// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_4th_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime) +// for element in filtered_3rd_symbols_c { +// let mut ema30_30m_vec: Vec = Vec::new(); +// let mut ema150_30m_vec: Vec = Vec::new(); +// let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0); +// let ema30_30m_option_c = ema30_30m_option.clone(); +// let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0); +// let ema150_30m_option_c = ema150_30m_option.clone(); +// let element_c = element.clone(); +// let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc); + +// if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() { +// ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone(); +// ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone(); + +// if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 { +// let ema30_30m_vec_c = ema30_30m_vec.clone(); +// let ema150_30m_vec_c = ema150_30m_vec.clone(); + +// task_vec.push(tokio::spawn(async move { +// let ema30_search_result = ema30_30m_vec_c.binary_search_by_key( +// &element_c.1, +// |&EmaData { +// ema_value, +// close_time, +// }| close_time, +// ); +// let ema150_search_result = ema150_30m_vec_c.binary_search_by_key( +// &element_c.1, +// |&EmaData { +// ema_value, +// close_time, +// }| close_time, +// ); + +// if ema30_search_result.is_ok() && ema150_search_result.is_ok() { +// if ema30_30m_vec_c[ema30_search_result.unwrap()-9].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-9].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-8].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-8].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-7].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-7].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-6].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-6].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-5].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-5].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-4].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-4].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value < ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value >= ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value && +// ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value +// { +// let mut filtered_4th_symbols_lock = +// filtered_4th_symbols_arc_c.lock().await; +// filtered_4th_symbols_lock.push(element_c); +// } +// } +// })); +// } +// } +// } +// try_join_all(task_vec).await?; + +// // 4th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be Normal or Low. +// let filtered_4th_symbols_c = filtered_4th_symbols_arc.lock().await.clone(); +// let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_4th_symbols_c { +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let heatmap_volume_option = +// heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) +// .await; +// if heatmap_volume_option.is_some() { +// let heatmap_volume_vec = heatmap_volume_option.unwrap(); +// let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( +// &element.1, +// |HeatmapVolumeData { +// heatmap_value, +// heatmap_level, +// close_time, +// }| *close_time, +// ); +// if heatmap_search_result.is_ok() { +// if (heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::Low +// || +// heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::Normal) && +// (heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level +// == HeatMapLevel::Low +// || +// heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level +// == HeatMapLevel::Normal +// ) +// { +// filtered_5th_symbols.push(element); +// } +// } +// } +// } +// } +// } + +// // final job: adding price information to filtered results +// let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) +// let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); +// let mut task_vec = Vec::new(); +// for element in filtered_5th_symbols { +// let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + +// let elememt_c = element.clone(); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// if rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .is_some() +// { +// let mut filtered_symbols_lock: tokio::sync::MutexGuard< +// '_, +// Vec<(String, i64, f64)>, +// > = filtered_symbols_arc_c.lock().await; +// filtered_symbols_lock.push(( +// elememt_c.0, +// elememt_c.1, +// rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .unwrap() +// .close_price, +// )); +// } +// } +// })); +// } + +// try_join_all(task_vec).await?; + +// let a = filtered_symbols_arc.lock().await.clone(); +// insert_pre_suggested_coins(4, false, &a, alldata).await; + +// Ok(()) +// } \ No newline at end of file diff --git a/src/strategy_team/strategy_005.rs b/src/strategy_team/strategy_005.rs new file mode 100644 index 0000000..6422b44 --- /dev/null +++ b/src/strategy_team/strategy_005.rs @@ -0,0 +1,192 @@ +// pub async fn strategist_005( +// alldata: &AllData, +// ) -> Result<(), Box> { +// // print rt_price for debugging +// // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); +// // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); + +// // 1st filtering: supertrend(ATR period 30, multiplier: 6.0, 30m close price), the area should be in UP area. +// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_2nd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); +// let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); +// for symbol in valid_symbol_vec_c { +// let mut opclo_30m_vec: Vec = Vec::new(); +// let mut supertrend_vec: Vec = Vec::new(); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); +// let supertrend_option_30m = +// supertrend(&symbol, &rt_price_30m_vec_c, 30, 6.0, true).await; + +// if opclo_30m_option.is_some() && supertrend_option_30m.is_some() { +// opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); +// supertrend_vec = supertrend_option_30m.unwrap(); + +// if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 { +// let supertrend_search_result = supertrend_vec.binary_search_by_key( +// &opclo_30m_vec.last().unwrap().close_time, +// |SupertrendData { +// band_value, +// signal, +// area, +// close_time, +// }| *close_time, +// ); +// if supertrend_search_result.is_ok() { +// if supertrend_vec[supertrend_search_result.unwrap()] +// .signal.as_ref().is_some_and(|signal| signal.contains("BUY")) +// { +// let mut filtered_2nd_symbols_lock = +// filtered_2nd_symbols_arc_c.lock().await; +// filtered_2nd_symbols_lock +// .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); +// } +// } +// } +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 2nd filtering: lookup tables if the tradepair is already there +// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); +// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); +// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); +// let inspect_table_name_4 = String::from("suggested_coin_list"); + +// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_3rd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); + +// let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); +// for element in filtered_2nd_iter { +// let mut exists_condition_build = String::from("symbol=\'"); +// exists_condition_build.push_str(element.0.as_str()); +// exists_condition_build.push_str("\' AND registerer="); +// exists_condition_build.push_str(5.to_string().as_str()); +// // exists_condition_build.push_str("\' AND close_time="); +// // exists_condition_build.push_str(element.1.to_string().as_str()); +// let exists_condition = Some(exists_condition_build); +// let exists_condition_c = exists_condition.clone(); +// let inspect_table_name_1_c = inspect_table_name_1.clone(); +// let inspect_table_name_2_c = inspect_table_name_2.clone(); +// let inspect_table_name_3_c = inspect_table_name_3.clone(); +// let inspect_table_name_4_c = inspect_table_name_4.clone(); +// let element_c = element.clone(); +// let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let inspect_result_1 = +// exists_record(&inspect_table_name_1_c, &exists_condition_c).await; +// let inspect_result_2 = +// exists_record(&inspect_table_name_2_c, &exists_condition_c).await; +// let inspect_result_3 = +// exists_record(&inspect_table_name_3_c, &exists_condition_c).await; +// let inspect_result_4 = +// exists_record(&inspect_table_name_4_c, &exists_condition_c).await; + +// if inspect_result_1 == false +// && inspect_result_2 == false +// && inspect_result_3 == false +// && inspect_result_4 == false +// { +// let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; +// filtered_3rd_symbols_lock.push(element_c); +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 3rd filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be Normal or Low. +// let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone(); +// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_3rd_symbols_c { +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let heatmap_volume_option = +// heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5) +// .await; +// if heatmap_volume_option.is_some() { +// let heatmap_volume_vec = heatmap_volume_option.unwrap(); +// let heatmap_search_result = heatmap_volume_vec.binary_search_by_key( +// &element.1, +// |HeatmapVolumeData { +// heatmap_value, +// heatmap_level, +// close_time, +// }| *close_time, +// ); +// if heatmap_search_result.is_ok() { +// if (heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::Low +// || +// heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level +// == HeatMapLevel::Normal) && +// (heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level +// == HeatMapLevel::Low +// || +// heatmap_volume_vec[heatmap_search_result.unwrap()-1].heatmap_level +// == HeatMapLevel::Normal) && +// (heatmap_volume_vec[heatmap_search_result.unwrap()-2].heatmap_level +// == HeatMapLevel::Low +// || +// heatmap_volume_vec[heatmap_search_result.unwrap()-2].heatmap_level +// == HeatMapLevel::Normal) +// { +// filtered_4th_symbols.push(element); +// } +// } +// } +// } +// } +// } + +// // final job: adding price information to filtered results +// let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) +// let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); +// let mut task_vec = Vec::new(); +// for element in filtered_4th_symbols { +// let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + +// let elememt_c = element.clone(); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// if rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .is_some() +// { +// let mut filtered_symbols_lock: tokio::sync::MutexGuard< +// '_, +// Vec<(String, i64, f64)>, +// > = filtered_symbols_arc_c.lock().await; +// filtered_symbols_lock.push(( +// elememt_c.0, +// elememt_c.1, +// rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .unwrap() +// .close_price, +// )); +// } +// } +// })); +// } + +// try_join_all(task_vec).await?; + +// let a = filtered_symbols_arc.lock().await.clone(); +// insert_pre_suggested_coins(5, false, &a, alldata).await; + +// Ok(()) +// } diff --git a/src/strategy_team/strategy_006.rs b/src/strategy_team/strategy_006.rs new file mode 100644 index 0000000..2f14958 --- /dev/null +++ b/src/strategy_team/strategy_006.rs @@ -0,0 +1,203 @@ +// pub async fn strategist_006( +// alldata: &AllData, +// ) -> Result<(), Box> { +// // print rt_price for debugging +// // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT"); +// // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap()); + +// // 1st filtering: making basic form +// let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_2nd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); +// let valid_symbol_vec_c = alldata.valid_symbol_vec.clone(); +// for symbol in valid_symbol_vec_c { +// let mut opclo_30m_vec: Vec = Vec::new(); + +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); +// let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol); + +// if opclo_30m_option.is_some() { +// opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone(); + +// if opclo_30m_vec.len() >= 3 { +// let mut filtered_2nd_symbols_lock = +// filtered_2nd_symbols_arc_c.lock().await; +// filtered_2nd_symbols_lock +// .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time)); +// } +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 2nd filtering: lookup tables if the tradepair is already there +// let inspect_table_name_1 = String::from("buy_ordered_coin_list"); +// let inspect_table_name_2 = String::from("sell_ordered_coin_list"); +// let inspect_table_name_3 = String::from("pre_suggested_coin_list"); +// let inspect_table_name_4 = String::from("suggested_coin_list"); + +// let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new(); +// let mut filtered_3rd_symbols_arc: Arc>> = +// Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime) +// let mut task_vec = Vec::new(); + +// let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter(); +// for element in filtered_2nd_iter { +// let mut exists_condition_build = String::from("symbol=\'"); +// exists_condition_build.push_str(element.0.as_str()); +// exists_condition_build.push_str("\' AND registerer="); +// exists_condition_build.push_str(6.to_string().as_str()); +// // exists_condition_build.push_str("\' AND close_time="); +// // exists_condition_build.push_str(element.1.to_string().as_str()); +// let exists_condition = Some(exists_condition_build); +// let exists_condition_c = exists_condition.clone(); +// let inspect_table_name_1_c = inspect_table_name_1.clone(); +// let inspect_table_name_2_c = inspect_table_name_2.clone(); +// let inspect_table_name_3_c = inspect_table_name_3.clone(); +// let inspect_table_name_4_c = inspect_table_name_4.clone(); +// let element_c = element.clone(); +// let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc); +// task_vec.push(tokio::spawn(async move { +// let inspect_result_1 = +// exists_record(&inspect_table_name_1_c, &exists_condition_c).await; +// let inspect_result_2 = +// exists_record(&inspect_table_name_2_c, &exists_condition_c).await; +// let inspect_result_3 = +// exists_record(&inspect_table_name_3_c, &exists_condition_c).await; +// let inspect_result_4 = +// exists_record(&inspect_table_name_4_c, &exists_condition_c).await; + +// if inspect_result_1 == false +// && inspect_result_2 == false +// && inspect_result_3 == false +// && inspect_result_4 == false +// { +// let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await; +// filtered_3rd_symbols_lock.push(element_c); +// } +// })); +// } +// try_join_all(task_vec).await?; + +// // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth kn > kn-1 +// let filtered_3rd_symbol_c = filtered_3rd_symbols_arc.lock().await.clone(); +// let mut rsi10_1d_data: Vec<(String, Vec)> = rsi( +// 10, +// &alldata.rt_price_1d_vec, +// &filtered_3rd_symbol_c, +// ) +// .await?; +// let stoch_rsi_data = stoch_rsi(&rsi10_1d_data, 10, 3, 3).await?; +// let mut stoch_rsi10_1d_vec: Vec = Vec::new(); +// let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_3rd_symbol_c { +// let stoch_rsi10_1d_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0); + +// if stoch_rsi10_1d_option.is_some() { +// stoch_rsi10_1d_vec = stoch_rsi_data[stoch_rsi10_1d_option.unwrap()].1.clone(); + +// if stoch_rsi10_1d_vec.len() >= 3 { +// let stoch_rsi_search_result = stoch_rsi10_1d_vec.binary_search_by_key( +// &element.1, +// |&StochRsiData { +// k, +// d, +// close_time, +// }| close_time, +// ); +// if stoch_rsi_search_result.is_ok() { +// if stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k > stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()-1].k && +// stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()].k < 90.0 && +// stoch_rsi10_1d_vec[stoch_rsi_search_result.unwrap()-1].k > 10.0 { +// filtered_4th_symbols.push(element); +// } +// } +// } +// } +// } + +// // 6th filtering condition: MACD +// let mut opclo_30m_vec: Vec = Vec::new(); +// let mut ema3_1d_vec: &Vec = &Vec::new(); +// let mut ema10_1d_vec: &Vec = &Vec::new(); + +// let ema3_1d_data: Vec<(String, Vec)> = ema( +// 3, +// &alldata.rt_price_1d_vec, +// &filtered_4th_symbols, +// ) +// .await?; +// let ema10_1d_data: Vec<(String, Vec)> = ema( +// 10, +// &alldata.rt_price_1d_vec, +// &filtered_4th_symbols, +// ) +// .await?; + +// let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime) +// for element in filtered_4th_symbols { +// let ema3_1d_option = ema3_1d_data.iter().position(|x| *x.0 == *element.0); +// let ema10_1d_option = ema10_1d_data.iter().position(|x| *x.0 == *element.0); + +// if ema3_1d_option.is_some() && ema10_1d_option.is_some() { +// ema3_1d_vec = &ema3_1d_data[ema3_1d_option.unwrap()].1; +// ema10_1d_vec = &ema10_1d_data[ema10_1d_option.unwrap()].1; + +// if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 { +// let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?; +// // let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time); + +// // if macd_search_result.is_ok() { +// if macd_vec.last().unwrap().macd_value > macd_vec[macd_vec.len() -1].macd_value { +// filtered_5th_symbols.push(element); +// } +// // } +// } +// } +// } + +// // final job: adding price information to filtered results +// let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price) +// let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols)); +// let mut task_vec = Vec::new(); +// for element in filtered_5th_symbols { +// let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc); +// let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone(); + +// let elememt_c = element.clone(); +// task_vec.push(tokio::spawn(async move { +// let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0); +// if opclo_30m_option.is_some() { +// if rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .is_some() +// { +// let mut filtered_symbols_lock: tokio::sync::MutexGuard< +// '_, +// Vec<(String, i64, f64)>, +// > = filtered_symbols_arc_c.lock().await; +// filtered_symbols_lock.push(( +// elememt_c.0, +// elememt_c.1, +// rt_price_30m_vec_c[opclo_30m_option.unwrap()] +// .1 +// .last() +// .unwrap() +// .close_price, +// )); +// } +// } +// })); +// } + +// try_join_all(task_vec).await?; + +// let a = filtered_symbols_arc.lock().await.clone(); +// insert_pre_suggested_coins(6, true, &a, alldata).await; + +// Ok(()) +// } \ No newline at end of file diff --git a/src/strategy_team/strategy_manager.rs b/src/strategy_team/strategy_manager.rs new file mode 100644 index 0000000..6cde5b5 --- /dev/null +++ b/src/strategy_team/strategy_manager.rs @@ -0,0 +1,641 @@ +use crate::coex::exchange_team::*; +use crate::coex::order_team::*; +use crate::coin_health_check_team::request_others::CoinPriceData; +use csv::{DeserializeRecordsIter, StringRecord}; +use rust_decimal::prelude::ToPrimitive; +use rust_decimal::Decimal; +use serde::Deserialize; + +use tokio::time::{sleep, Duration, Instant}; +use crate::signal_association::signal_decision::*; +use super::{AllData, RealtimePriceData, exists_record, try_select_record, insert_one_record, FromRow}; + +#[derive(Debug, FromRow)] +struct ServerEpoch { + server_epoch: u64, +} + +#[derive(Debug, FromRow)] +struct Record { + symbol: String, + suggested_price: Decimal, + close_time: u64, + registered_server_epoch: u64, + registerer: u16, + is_long: u8, +} + +pub async fn execute_list_up_for_buy( + all_data: &AllData, +) -> Result<(), Box> { + // strategist_001(all_data).await?; + // strategist_002(all_data).await?; + crate::strategy_team::strategy_003::list_up_for_buy(all_data).await?; + // strategist_004(all_data).await?; + // strategist_005(all_data).await?; + // strategist_006(all_data).await?; + + Ok(()) +} + +// useful functions for strategists +pub async fn get_current_price( + symbol: &String, + rt_price_vec: &Vec<(String, Vec)>, +) -> Option { + let index_result = rt_price_vec.iter().position(|x| *x.0 == *symbol); + match index_result { + Some(T) => { + if rt_price_vec[T].1.last().is_some() { + Some(rt_price_vec[T].1.last().unwrap().close_price) + } else { + None + } + } + None => None, + } +} + +pub async fn insert_pre_suggested_coins( + registerer: i32, + is_long: bool, + filtered_symbols: &Vec<(String, i64, f64)>, + alldata: &AllData, +) -> Result<(), Box> { + // Check the existance of record that is registered by this strategist + let mut dest_table_name = String::from("suggested_coin_list"); + let mut dest2_table_name = String::from("buy_ordered_coin_list"); + let mut dest3_table_name = String::from("pre_suggested_coin_list"); + let mut insert_table_name = String::from("pre_suggested_coin_list"); + let mut exists_condition_build = String::from("registerer="); + exists_condition_build.push_str(registerer.to_string().as_str()); + let mut exists_condition = Some(exists_condition_build); + let exists_result1 = exists_record(&dest_table_name, &exists_condition).await; + let exists_result2 = exists_record(&dest2_table_name, &exists_condition).await; + let exists_result3 = exists_record(&dest3_table_name, &exists_condition).await; + let insert_columns = vec![ + "symbol", + "close_time", + "suggested_price", + "current_price", + "registered_server_epoch", + "profit_percent", + "minimum_profit_percent", + "maximum_profit_percent", + "registerer", + "is_long", + ]; + + if exists_result1 == true && exists_result2 == true && exists_result3 == true { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + #[derive(FromRow)] + struct SelectData2 { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let mut select_columns2 = String::from("symbol, close_time"); + let select_data_structure2 = SelectData2 { + symbol: String::new(), + close_time: 0, + }; + let suggested_coin_list = try_select_record( + &dest_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + let ordered_coin_list = try_select_record( + &dest2_table_name, + &select_columns2, + &select_condition, + &select_data_structure2, + ) + .await?; + let pre_suggested_coin_list = try_select_record( + &dest3_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + + // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + for list_element in &ordered_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + for list_element in &pre_suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else if exists_result1 == true && exists_result2 == true && exists_result3 == false { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + #[derive(FromRow)] + struct SelectData2 { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let mut select_columns2 = String::from("symbol, close_time"); + let select_data_structure2 = SelectData2 { + symbol: String::new(), + close_time: 0, + }; + let suggested_coin_list = try_select_record( + &dest_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + let ordered_coin_list = try_select_record( + &dest2_table_name, + &select_columns2, + &select_condition, + &select_data_structure2, + ) + .await?; + + // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + for list_element in &ordered_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else if exists_result1 == true && exists_result2 == false && exists_result3 == true { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let suggested_coin_list = try_select_record( + &dest_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + let pre_suggested_coin_list = try_select_record( + &dest3_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + + // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + for list_element in &pre_suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else if exists_result1 == true && exists_result2 == false && exists_result3 == false { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let suggested_coin_list = try_select_record( + &dest_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + + // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else if exists_result1 == false && exists_result2 == true && exists_result3 == true { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + #[derive(FromRow)] + struct SelectData2 { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let mut select_columns2 = String::from("symbol, close_time"); + let select_data_structure2 = SelectData2 { + symbol: String::new(), + close_time: 0, + }; + let ordered_coin_list = try_select_record( + &dest2_table_name, + &select_columns2, + &select_condition, + &select_data_structure2, + ) + .await?; + let pre_suggested_coin_list = try_select_record( + &dest3_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + + // insert record without duplicate(registerer, close_time, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &ordered_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + for list_element in &pre_suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else if exists_result1 == false && exists_result2 == true && exists_result3 == false { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + #[derive(FromRow)] + struct SelectData2 { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let mut select_columns2 = String::from("symbol, close_time"); + let select_data_structure2 = SelectData2 { + symbol: String::new(), + close_time: 0, + }; + let ordered_coin_list = try_select_record( + &dest2_table_name, + &select_columns2, + &select_condition, + &select_data_structure2, + ) + .await?; + + // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &ordered_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else if exists_result1 == false && exists_result2 == false && exists_result3 == true { + // Bring the current list of pre-suggested coins from [pre_suggested_coin_list] and [ordered_coin_list] + #[derive(FromRow)] + struct SelectData { + symbol: String, + close_time: i64, + } + let mut select_columns = String::from("symbol, close_time"); + let mut condition_build = String::from("WHERE registerer="); + condition_build.push_str(registerer.to_string().as_str()); + let select_condition = Some(condition_build); + let select_data_structure = SelectData { + symbol: String::new(), + close_time: 0, + }; + let pre_suggested_coin_list = try_select_record( + &dest3_table_name, + &select_columns, + &select_condition, + &select_data_structure, + ) + .await?; + + // insert record without duplicate(registerer, closetime, symbol) into [pre_suggested_coin_list] + for filtered_element in filtered_symbols { + let mut is_dupe = false; // initialize + + for list_element in &pre_suggested_coin_list { + if (filtered_element.0 == list_element.symbol) + && (filtered_element.1 == list_element.close_time) + { + is_dupe = true; + break; + } + } + + if is_dupe == false { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + } else { + for filtered_element in filtered_symbols { + let mut insert_values = vec![ + filtered_element.0.clone(), // symbol + filtered_element.1.to_string(), // close_time + filtered_element.2.to_string(), // suggested_price + filtered_element.2.to_string(), // current_price + server_epoch().await.to_string(), // registered_server_epoch + 0.0.to_string(), // profit_percent + 0.0.to_string(), // minimum_profit_percent + 0.0.to_string(), // maximum_profit_percent + registerer.to_string(), // registerer + ]; + + if is_long == true { + insert_values.push(1.to_string()); // is_long + } else { + insert_values.push(0.to_string()); // is_long + } + + insert_one_record(&insert_table_name, &insert_columns, &insert_values).await; + } + } + + Ok(()) +} + diff --git a/src/value_estimation_team/datapoints.rs b/src/value_estimation_team/datapoints.rs deleted file mode 100644 index 581004c..0000000 --- a/src/value_estimation_team/datapoints.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod price_data; diff --git a/src/value_estimation_team/datapoints/mod.rs b/src/value_estimation_team/datapoints/mod.rs new file mode 100644 index 0000000..23eec08 --- /dev/null +++ b/src/value_estimation_team/datapoints/mod.rs @@ -0,0 +1 @@ +pub mod price_data; \ No newline at end of file diff --git a/src/value_estimation_team/indicators.rs b/src/value_estimation_team/indicators/mod.rs similarity index 100% rename from src/value_estimation_team/indicators.rs rename to src/value_estimation_team/indicators/mod.rs diff --git a/src/value_estimation_team.rs b/src/value_estimation_team/mod.rs similarity index 50% rename from src/value_estimation_team.rs rename to src/value_estimation_team/mod.rs index 2ef7663..b684404 100644 --- a/src/value_estimation_team.rs +++ b/src/value_estimation_team/mod.rs @@ -1,2 +1,2 @@ pub mod datapoints; -pub mod indicators; +pub mod indicators; \ No newline at end of file