Add log level and input argument (#4)

Co-authored-by: Sik Yoon <younxxxx@gmail.com>
Reviewed-on: http://siknas.duckdns.org:3000/Sik/tradingbot/pulls/4
This commit is contained in:
Sik 2024-02-03 16:28:14 +00:00
parent 0ef2d381da
commit a247ee63f0
9 changed files with 1163 additions and 959 deletions

285
Cargo.lock generated
View File

@ -70,6 +70,54 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "arrayvec"
version = "0.7.4"
@ -265,7 +313,50 @@ dependencies = [
"num-traits",
"serde",
"wasm-bindgen",
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
name = "clap"
version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_lex"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys 0.48.0",
]
[[package]]
@ -385,6 +476,15 @@ dependencies = [
"pem-rfc7468",
]
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
]
[[package]]
name = "digest"
version = "0.10.7"
@ -440,7 +540,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -939,7 +1039,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
dependencies = [
"libc",
"wasi",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -998,6 +1098,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-integer"
version = "0.1.45"
@ -1039,6 +1145,15 @@ dependencies = [
"libc",
]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]]
name = "object"
version = "0.32.1"
@ -1149,7 +1264,7 @@ dependencies = [
"libc",
"redox_syscall 0.4.1",
"smallvec",
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
@ -1213,6 +1328,12 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1509,7 +1630,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1524,7 +1645,7 @@ version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
dependencies = [
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1654,6 +1775,18 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a"
[[package]]
name = "simple_logger"
version = "4.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e7e46c8c90251d47d08b28b8a419ffb4aede0f87c2eea95e17d1d5bacbf3ef1"
dependencies = [
"colored",
"log",
"time",
"windows-sys 0.48.0",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -1686,7 +1819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1825,6 +1958,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "subtle"
version = "2.5.0"
@ -1902,7 +2041,7 @@ dependencies = [
"fastrand",
"redox_syscall 0.4.1",
"rustix",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1948,6 +2087,39 @@ dependencies = [
"syn 2.0.39",
]
[[package]]
name = "time"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b24b79b7a07f10209f19e683ca1e289d80b1e76ffa8c2b779718566a083679"
dependencies = [
"deranged",
"itoa",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -1979,7 +2151,7 @@ dependencies = [
"signal-hook-registry",
"socket2 0.5.5",
"tokio-macros",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -2075,10 +2247,12 @@ name = "tradingbot"
version = "0.10.0"
dependencies = [
"chrono",
"clap",
"csv",
"futures",
"hex",
"hmac-sha256",
"log",
"ord_subset",
"rand",
"reqwest",
@ -2086,6 +2260,7 @@ dependencies = [
"rust_decimal_macros",
"serde",
"serde_json",
"simple_logger",
"sqlx",
"thirtyfour",
"tokio",
@ -2153,6 +2328,12 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "110352d4e9076c67839003c7788d8604e24dcded13e0b375af3efaa8cf468517"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.5.0"
@ -2290,7 +2471,7 @@ version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
@ -2299,7 +2480,16 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
]
[[package]]
@ -2308,13 +2498,28 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
]
[[package]]
@ -2323,42 +2528,84 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "winnow"
version = "0.5.19"
@ -2375,7 +2622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
dependencies = [
"cfg-if",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]

View File

@ -24,3 +24,6 @@ thirtyfour = { version = "0.28.1", features = ["tokio-runtime"]}
ord_subset = "3.1.1"
rust_decimal = "1.29.1"
rust_decimal_macros = "1.29.1"
clap = "4.4.18"
log = "0.4.20"
simple_logger = "4.3.3"

View File

@ -11,6 +11,7 @@ use rust_decimal::{prelude::ToPrimitive, Decimal, RoundingStrategy};
use rust_decimal_macros::dec;
use serde_json::{Result, Value};
use sqlx::FromRow;
use log;
#[derive(Debug, FromRow)]
pub struct AchievementEvaluationInfo {
@ -155,15 +156,17 @@ pub async fn add_extra_usdt(extra_usdt: Decimal) {
// add additional_usdt into [wallet_simul]
let mut update_table_name = String::new();
if RUNNING_MODE == SIMUL {
let update_table_name = String::from("wallet");
let mut value_build = String::from("free + ");
value_build.push_str(extra_usdt.to_string().as_str());
let update_values = vec![(String::from("free"), value_build)];
let update_condition = vec![(String::from("asset"), String::from("USDT"))];
update_record3(&update_table_name, &update_values, &update_condition)
.await
.unwrap();
unsafe{
if RUNNING_MODE == SIMUL {
let update_table_name = String::from("wallet");
let mut value_build = String::from("free + ");
value_build.push_str(extra_usdt.to_string().as_str());
let update_values = vec![(String::from("free"), value_build)];
let update_condition = vec![(String::from("asset"), String::from("USDT"))];
update_record3(&update_table_name, &update_values, &update_condition)
.await
.unwrap();
}
}
println!("add_extra_usdt 완료");
@ -172,54 +175,57 @@ pub async fn add_extra_usdt(extra_usdt: Decimal) {
// update current_total_usdt and profit of asset
pub async fn update_current_total_usdt() {
let mut update_values: Vec<(String, String)> = Vec::new();
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
let free_usdt = fetch_free_usdt().await;
let initial_usdt = select_asset_manage_announcement().await.initial_usdt;
// println!("update_current_total_usdt실행 free_usdt: {}, initial_usdt: {}", free_usdt, initial_usdt);
let mut profit: Decimal;
if initial_usdt.is_zero() {
profit = dec!(0.0);
unsafe {
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
let free_usdt = fetch_free_usdt().await;
let initial_usdt = select_asset_manage_announcement().await.initial_usdt;
// println!("update_current_total_usdt실행 free_usdt: {}, initial_usdt: {}", free_usdt, initial_usdt);
let mut profit: Decimal;
if initial_usdt.is_zero() {
profit = dec!(0.0);
} else {
profit = decimal_sub(decimal_div(free_usdt, initial_usdt), dec!(1));
}
update_values = vec![
(String::from("current_total_usdt"), free_usdt.to_string()),
(String::from("profit"), profit.to_string()),
(
String::from("realtime_expected_total_usdt"),
0.0.to_string(),
),
(String::from("realtime_profit"), 0.0.to_string()),
];
} else {
profit = decimal_sub(decimal_div(free_usdt, initial_usdt), dec!(1));
let asset_info = select_asset_manage_announcement().await;
let achievement_evaluation = select_achievement_evaluation().await;
let balance = decimal_sub(
achievement_evaluation.usdt_profit,
achievement_evaluation.invested_usdt,
);
let current_total_usdt = decimal_add(asset_info.initial_usdt, balance);
let profit = decimal_sub(
decimal_div(current_total_usdt, asset_info.initial_usdt),
dec!(1),
);
update_values = vec![
(
String::from("current_total_usdt"),
current_total_usdt.to_string(),
),
(String::from("profit"), profit.to_string()),
(
String::from("realtime_expected_total_usdt"),
0.0.to_string(),
),
(String::from("realtime_profit"), 0.0.to_string()),
];
}
update_values = vec![
(String::from("current_total_usdt"), free_usdt.to_string()),
(String::from("profit"), profit.to_string()),
(
String::from("realtime_expected_total_usdt"),
0.0.to_string(),
),
(String::from("realtime_profit"), 0.0.to_string()),
];
} else {
let asset_info = select_asset_manage_announcement().await;
let achievement_evaluation = select_achievement_evaluation().await;
let balance = decimal_sub(
achievement_evaluation.usdt_profit,
achievement_evaluation.invested_usdt,
);
let current_total_usdt = decimal_add(asset_info.initial_usdt, balance);
let profit = decimal_sub(
decimal_div(current_total_usdt, asset_info.initial_usdt),
dec!(1),
);
update_values = vec![
(
String::from("current_total_usdt"),
current_total_usdt.to_string(),
),
(String::from("profit"), profit.to_string()),
(
String::from("realtime_expected_total_usdt"),
0.0.to_string(),
),
(String::from("realtime_profit"), 0.0.to_string()),
];
}
let update_table_name = String::from("asset_manage_announcement");
let update_condition = vec![(String::from("id"), String::from("1"))];
update_record3(&update_table_name, &update_values, &update_condition)
@ -238,33 +244,35 @@ pub async fn monitoring_asset_usdt(previous_result: &mut bool, client: &Client)
let sell_list_result = exists_record(&table_name, &condition).await;
if buy_list_result == false && sell_list_result == false {
if buy_list_result == false
&& sell_list_result == false
&& *previous_result == true
&& (RUNNING_MODE == TEST || RUNNING_MODE == REAL)
{
let mut result = crate::coex::order_team::account_information(&client).await; // (/api, Weight(IP) 10)
loop {
if result.is_ok() {
break;
} else {
println!("retry account_information()");
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
result = crate::coex::order_team::account_information(&client).await;
// (/api, Weight(IP) 10)
unsafe {
if buy_list_result == false
&& sell_list_result == false
&& *previous_result == true
&& (RUNNING_MODE == TEST || RUNNING_MODE == REAL)
{
let mut result = crate::coex::order_team::account_information(&client).await; // (/api, Weight(IP) 10)
loop {
if result.is_ok() {
break;
} else {
log::warn!("retry account_information()");
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
result = crate::coex::order_team::account_information(&client).await;
// (/api, Weight(IP) 10)
}
}
// FIXME: 아래 함수들을 고쳐야함. 순환 오류 빠지는 듯
update_current_total_usdt().await;
set_available_usdt().await;
set_unit_usdt().await;
} else if buy_list_result == false
&& sell_list_result == false
&& *previous_result == true
&& (RUNNING_MODE == SIMUL)
{
update_current_total_usdt().await;
set_is_tradable().await;
}
// FIXME: 아래 함수들을 고쳐야함. 순환 오류 빠지는 듯
update_current_total_usdt().await;
set_available_usdt().await;
set_unit_usdt().await;
} else if buy_list_result == false
&& sell_list_result == false
&& *previous_result == true
&& (RUNNING_MODE == SIMUL)
{
update_current_total_usdt().await;
set_is_tradable().await;
}
*previous_result = false;
} else {
@ -533,10 +541,12 @@ pub async fn select_asset_manage_announcement() -> AssetInfo {
pub async fn fetch_free_usdt() -> Decimal {
let wallet_info = WalletInfo::new();
let select_table_name = {
if RUNNING_MODE == SIMUL || RUNNING_MODE == REAL {
String::from("wallet")
} else {
String::from("wallet_testnet")
unsafe{
if RUNNING_MODE == SIMUL || RUNNING_MODE == REAL {
String::from("wallet")
} else {
String::from("wallet_testnet")
}
}
};

View File

@ -31,6 +31,7 @@ use serde_json::Value;
use sqlx::FromRow;
use tokio::time::*;
use std::collections::HashMap;
use log;
pub enum OrderSide {
Buy,
@ -198,12 +199,14 @@ pub async fn limit_order_buy_test(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe{
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/order?";
@ -333,163 +336,165 @@ pub async fn limit_order_buy(
let mut insert_values: Vec<Vec<String>> = Vec::new();
let mut insert_value_container: Vec<String> = Vec::new();
let server_epoch = get_server_epoch().await;
if RUNNING_MODE == SIMUL {
insert_value_container.push(element.symbol.clone()); // symbol
insert_value_container.push(0.to_string()); // order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(element.close_time.to_string()); // close_time
insert_value_container.push(String::from("SIMUL")); // status
insert_value_container.push(used_usdt.to_string()); // used_usdt
insert_value_container.push(0.0.to_string()); // expected_get_usdt
insert_value_container.push(0.0.to_string()); // expected_usdt_profit
insert_value_container.push(order_price.to_string()); // buy_price
insert_value_container.push(0.0.to_string()); // current_price
insert_value_container.push(element.stoploss.to_string()); // stoploss
insert_value_container.push(element.target_price.to_string()); // target_price
insert_value_container.push(order_quantity.to_string()); // base_qty_ordered
insert_value_container.push(simul_base_qty_fee_adjusted.to_string()); // base_qty_fee_adjusted
insert_value_container.push(0.0.to_string()); // pure_profit_percent
insert_value_container.push(0.0.to_string()); // minimum_profit_percent
insert_value_container.push(0.0.to_string()); // maximum_profit_percent
insert_value_container.push(element.registerer.to_string()); // registerer
insert_value_container.push(0.to_string()); // is_long
unsafe {
if RUNNING_MODE == SIMUL {
insert_value_container.push(element.symbol.clone()); // symbol
insert_value_container.push(0.to_string()); // order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(element.close_time.to_string()); // close_time
insert_value_container.push(String::from("SIMUL")); // status
insert_value_container.push(used_usdt.to_string()); // used_usdt
insert_value_container.push(0.0.to_string()); // expected_get_usdt
insert_value_container.push(0.0.to_string()); // expected_usdt_profit
insert_value_container.push(order_price.to_string()); // buy_price
insert_value_container.push(0.0.to_string()); // current_price
insert_value_container.push(element.stoploss.to_string()); // stoploss
insert_value_container.push(element.target_price.to_string()); // target_price
insert_value_container.push(order_quantity.to_string()); // base_qty_ordered
insert_value_container.push(simul_base_qty_fee_adjusted.to_string()); // base_qty_fee_adjusted
insert_value_container.push(0.0.to_string()); // pure_profit_percent
insert_value_container.push(0.0.to_string()); // minimum_profit_percent
insert_value_container.push(0.0.to_string()); // maximum_profit_percent
insert_value_container.push(element.registerer.to_string()); // registerer
insert_value_container.push(0.to_string()); // is_long
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
// reflect available_usdt in [asset_manage_announcement]
sub_available_usdt(used_usdt).await;
// reflect available_usdt in [asset_manage_announcement]
sub_available_usdt(used_usdt).await;
println!("SIMUL buy coin: {}", element.symbol);
} else {
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
println!("SIMUL buy coin: {}", element.symbol);
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
}
let endpoint_url = "/api/v3/order?";
url.push_str(endpoint_url);
let mut url_build = String::new();
// add parameters into URL
url_build.push_str("&symbol=");
url_build.push_str(&element.symbol);
url_build.push_str("&side=BUY");
match tif {
TimeInForce::Gtc => {
url_build.push_str("&timeInForce=GTC");
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
}
TimeInForce::Ioc => {
url_build.push_str("&timeInForce=IOC");
}
TimeInForce::Fok => {
url_build.push_str("&timeInForce=FOK");
}
}
url_build.push_str("&type=LIMIT");
url_build.push_str("&quantity=");
url_build.push_str(order_quantity.to_string().as_str());
url_build.push_str("&price=");
url_build.push_str(order_price.to_string().as_str());
hmac_signature(&mut url_build).await;
url.push_str(&url_build);
let endpoint_url = "/api/v3/order?";
url.push_str(endpoint_url);
let res = client
.post(&url)
.header("X-MBX-APIKEY", api_key)
.send()
.await
.unwrap();
let mut url_build = String::new();
let body = res.text_with_charset("utf-8").await.unwrap();
// deserialize JSON and then insert record into table
let v = serde_json::from_str::<Value>(body.as_str());
// add parameters into URL
url_build.push_str("&symbol=");
url_build.push_str(&element.symbol);
url_build.push_str("&side=BUY");
match v {
Ok(T) => {
if T.get("code").is_some() { // when request failed
} else {
// when request succeed
insert_value_container
.push(T.get("symbol").unwrap().as_str().unwrap().to_string()); // symbol
insert_value_container
.push(T.get("orderId").unwrap().as_u64().unwrap().to_string()); // order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(element.close_time.to_string()); // close_time
insert_value_container
.push(T.get("status").unwrap().as_str().unwrap().to_string()); // status
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
let base_qty_ordered = rust_decimal::prelude::FromStr::from_str(
T.get("origQty").unwrap().as_str().unwrap(),
)
.unwrap();
let base_qty_fee_adjusted =
decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee));
let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str(
T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(),
)
.unwrap();
// let base_asset_precision = exchange_info_vec
// .iter()
// .find(|exchange_info| exchange_info.symbol == element.symbol)
// .unwrap()
// .base_asset_precision;
let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered)
.round_dp_with_strategy(8, RoundingStrategy::ToZero);
insert_value_container.push(cummulative_quote_qty.to_string()); // used_usdt
insert_value_container.push(0.0.to_string()); // expected_get_usdt
insert_value_container.push(0.0.to_string()); // expected_usdt_profit
insert_value_container.push(buy_price.to_string()); // buy_price
insert_value_container.push(0.0.to_string()); // current_price
insert_value_container.push(element.stoploss.to_string()); // stoploss
insert_value_container.push(element.target_price.to_string()); // target_price
insert_value_container.push(base_qty_ordered.to_string()); // base_qty_ordered
insert_value_container.push(base_qty_fee_adjusted.to_string()); // base_qty_fee_adjusted
// reflect available_usdt in [asset_manage_announcement]
// sub_available_usdt(cummulative_quote_qty).await;
sub_available_usdt(used_usdt).await;
println!("buy {}", element.symbol);
} else {
insert_value_container.push(used_usdt.to_string()); // used_usdt
insert_value_container.push(0.0.to_string()); // expected_get_usdt
insert_value_container.push(0.0.to_string()); // expected_usdt_profit
insert_value_container.push(0.0.to_string()); // buy_price
insert_value_container.push(0.0.to_string()); // current_price
insert_value_container.push(element.stoploss.to_string()); // stoploss
insert_value_container.push(element.target_price.to_string()); // target_price
insert_value_container
.push(T.get("origQty").unwrap().as_str().unwrap().to_string()); // base_qty_ordered
insert_value_container.push(0.0.to_string()); // base_qty_fee_adjusted
// reflect available_usdt in [asset_manage_announcement]
sub_available_usdt(used_usdt).await;
}
insert_value_container.push(0.0.to_string()); // pure_profit_percent
insert_value_container.push(0.0.to_string()); // minimum_profit_percent
insert_value_container.push(0.0.to_string()); // maximum_profit_percent
insert_value_container.push(element.registerer.to_string()); // registerer
insert_value_container.push(0.to_string()); // is_long
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
match tif {
TimeInForce::Gtc => {
url_build.push_str("&timeInForce=GTC");
}
TimeInForce::Ioc => {
url_build.push_str("&timeInForce=IOC");
}
TimeInForce::Fok => {
url_build.push_str("&timeInForce=FOK");
}
}
Err(e) => {
println!("order failed!: {}", body);
url_build.push_str("&type=LIMIT");
url_build.push_str("&quantity=");
url_build.push_str(order_quantity.to_string().as_str());
url_build.push_str("&price=");
url_build.push_str(order_price.to_string().as_str());
hmac_signature(&mut url_build).await;
url.push_str(&url_build);
let res = client
.post(&url)
.header("X-MBX-APIKEY", api_key)
.send()
.await
.unwrap();
let body = res.text_with_charset("utf-8").await.unwrap();
// deserialize JSON and then insert record into table
let v = serde_json::from_str::<Value>(body.as_str());
match v {
Ok(T) => {
if T.get("code").is_some() { // when request failed
} else {
// when request succeed
insert_value_container
.push(T.get("symbol").unwrap().as_str().unwrap().to_string()); // symbol
insert_value_container
.push(T.get("orderId").unwrap().as_u64().unwrap().to_string()); // order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(element.close_time.to_string()); // close_time
insert_value_container
.push(T.get("status").unwrap().as_str().unwrap().to_string()); // status
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
let base_qty_ordered = rust_decimal::prelude::FromStr::from_str(
T.get("origQty").unwrap().as_str().unwrap(),
)
.unwrap();
let base_qty_fee_adjusted =
decimal_mul(base_qty_ordered, decimal_sub(dec!(1), trade_fee));
let cummulative_quote_qty = rust_decimal::prelude::FromStr::from_str(
T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(),
)
.unwrap();
// let base_asset_precision = exchange_info_vec
// .iter()
// .find(|exchange_info| exchange_info.symbol == element.symbol)
// .unwrap()
// .base_asset_precision;
let buy_price = decimal_div(cummulative_quote_qty, base_qty_ordered)
.round_dp_with_strategy(8, RoundingStrategy::ToZero);
insert_value_container.push(cummulative_quote_qty.to_string()); // used_usdt
insert_value_container.push(0.0.to_string()); // expected_get_usdt
insert_value_container.push(0.0.to_string()); // expected_usdt_profit
insert_value_container.push(buy_price.to_string()); // buy_price
insert_value_container.push(0.0.to_string()); // current_price
insert_value_container.push(element.stoploss.to_string()); // stoploss
insert_value_container.push(element.target_price.to_string()); // target_price
insert_value_container.push(base_qty_ordered.to_string()); // base_qty_ordered
insert_value_container.push(base_qty_fee_adjusted.to_string()); // base_qty_fee_adjusted
// reflect available_usdt in [asset_manage_announcement]
// sub_available_usdt(cummulative_quote_qty).await;
sub_available_usdt(used_usdt).await;
println!("buy {}", element.symbol);
} else {
insert_value_container.push(used_usdt.to_string()); // used_usdt
insert_value_container.push(0.0.to_string()); // expected_get_usdt
insert_value_container.push(0.0.to_string()); // expected_usdt_profit
insert_value_container.push(0.0.to_string()); // buy_price
insert_value_container.push(0.0.to_string()); // current_price
insert_value_container.push(element.stoploss.to_string()); // stoploss
insert_value_container.push(element.target_price.to_string()); // target_price
insert_value_container
.push(T.get("origQty").unwrap().as_str().unwrap().to_string()); // base_qty_ordered
insert_value_container.push(0.0.to_string()); // base_qty_fee_adjusted
// reflect available_usdt in [asset_manage_announcement]
sub_available_usdt(used_usdt).await;
}
insert_value_container.push(0.0.to_string()); // pure_profit_percent
insert_value_container.push(0.0.to_string()); // minimum_profit_percent
insert_value_container.push(0.0.to_string()); // maximum_profit_percent
insert_value_container.push(element.registerer.to_string()); // registerer
insert_value_container.push(0.to_string()); // is_long
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
}
}
Err(e) => {
log::warn!("order failed!: {}", body);
}
}
}
}
@ -699,190 +704,192 @@ pub async fn limit_order_sell(
let mut insert_values: Vec<Vec<String>> = Vec::new();
let mut insert_value_container: Vec<String> = Vec::new();
let server_epoch = get_server_epoch().await;
if RUNNING_MODE == SIMUL && buy_ordered_coin.status == "SIMUL" {
if exchange_info_map.contains_key(&buy_ordered_coin.symbol) && trade_fee_map.contains_key(&buy_ordered_coin.symbol) {
let quote_asset_precision = exchange_info_map.get(&buy_ordered_coin.symbol).unwrap().quote_asset_precision;
let trade_fee = trade_fee_map.get(&buy_ordered_coin.symbol).unwrap().takercommission;
unsafe {
if RUNNING_MODE == SIMUL && buy_ordered_coin.status == "SIMUL" {
if exchange_info_map.contains_key(&buy_ordered_coin.symbol) && trade_fee_map.contains_key(&buy_ordered_coin.symbol) {
let quote_asset_precision = exchange_info_map.get(&buy_ordered_coin.symbol).unwrap().quote_asset_precision;
let trade_fee = trade_fee_map.get(&buy_ordered_coin.symbol).unwrap().takercommission;
let get_usdt = decimal_mul(sell_base_quantity, sell_base_price)
.round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero);
let get_usdt_fee_adjusted = decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee))
.round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero);
let get_usdt = decimal_mul(sell_base_quantity, sell_base_price)
.round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero);
let get_usdt_fee_adjusted = decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee))
.round_dp_with_strategy(quote_asset_precision, RoundingStrategy::ToZero);
insert_value_container.push(buy_ordered_coin.symbol.to_string()); // symbol
insert_value_container.push(0.to_string()); // buy_order_id
insert_value_container.push(0.to_string()); // sell_order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(buy_ordered_coin.close_time.to_string()); // close_time
insert_value_container.push(String::from("SIMUL")); // status
insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt
insert_value_container.push(get_usdt.to_string()); // get_usdt
insert_value_container.push(get_usdt_fee_adjusted.to_string()); // get_usdt_fee_adjusted
insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price
insert_value_container.push(sell_base_price.to_string()); // sell_price
insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss
insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price
insert_value_container.push(sell_base_quantity.to_string()); // base_qty_ordered
insert_value_container.push(buy_ordered_coin.symbol.to_string()); // symbol
insert_value_container.push(0.to_string()); // buy_order_id
insert_value_container.push(0.to_string()); // sell_order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(buy_ordered_coin.close_time.to_string()); // close_time
insert_value_container.push(String::from("SIMUL")); // status
insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt
insert_value_container.push(get_usdt.to_string()); // get_usdt
insert_value_container.push(get_usdt_fee_adjusted.to_string()); // get_usdt_fee_adjusted
insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price
insert_value_container.push(sell_base_price.to_string()); // sell_price
insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss
insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price
insert_value_container.push(sell_base_quantity.to_string()); // base_qty_ordered
let pure_profit_percent = decimal_mul(
decimal_sub(
decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt),
dec!(1),
),
dec!(100),
);
insert_value_container.push(pure_profit_percent.to_string()); // pure_profit_percent
insert_value_container.push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent
insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer
insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long
let pure_profit_percent = decimal_mul(
decimal_sub(
decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt),
dec!(1),
),
dec!(100),
);
insert_value_container.push(pure_profit_percent.to_string()); // pure_profit_percent
insert_value_container.push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent
insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer
insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
// delete record in buy_ordered_coin_list
let delete_table_name = String::from("buy_ordered_coin_list");
let mut delete_condition = String::from("WHERE id = ");
delete_condition.push_str(buy_ordered_coin.id.to_string().as_str());
delete_record(&delete_table_name, &delete_condition).await;
}
} else if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
}
// delete record in buy_ordered_coin_list
let delete_table_name = String::from("buy_ordered_coin_list");
let mut delete_condition = String::from("WHERE id = ");
delete_condition.push_str(buy_ordered_coin.id.to_string().as_str());
delete_record(&delete_table_name, &delete_condition).await;
}
} else if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
}
let endpoint_url = "/api/v3/order?";
url.push_str(endpoint_url);
let endpoint_url = "/api/v3/order?";
url.push_str(endpoint_url);
let mut url_build = String::new();
let mut url_build = String::new();
// add parameters into URL
url_build.push_str("&symbol=");
url_build.push_str(&buy_ordered_coin.symbol);
url_build.push_str("&side=SELL");
url_build.push_str("&timeInForce=GTC");
// add parameters into URL
url_build.push_str("&symbol=");
url_build.push_str(&buy_ordered_coin.symbol);
url_build.push_str("&side=SELL");
url_build.push_str("&timeInForce=GTC");
url_build.push_str("&type=LIMIT");
url_build.push_str("&quantity=");
url_build.push_str(sell_base_quantity.to_string().as_str());
url_build.push_str("&price=");
url_build.push_str(sell_base_price.to_string().as_str());
url_build.push_str("&type=LIMIT");
url_build.push_str("&quantity=");
url_build.push_str(sell_base_quantity.to_string().as_str());
url_build.push_str("&price=");
url_build.push_str(sell_base_price.to_string().as_str());
hmac_signature(&mut url_build).await;
url.push_str(&url_build);
hmac_signature(&mut url_build).await;
url.push_str(&url_build);
let res = client
.post(&url)
.header("X-MBX-APIKEY", api_key)
.send()
.await?;
let res = client
.post(&url)
.header("X-MBX-APIKEY", api_key)
.send()
.await?;
let body = res.text_with_charset("utf-8").await.unwrap();
// println!("limit_order_sell실행 body: {}", body);
// deserialize JSON and then insert record into table
let v = serde_json::from_str::<Value>(body.as_str());
let body = res.text_with_charset("utf-8").await.unwrap();
// println!("limit_order_sell실행 body: {}", body);
// deserialize JSON and then insert record into table
let v = serde_json::from_str::<Value>(body.as_str());
match v {
Ok(T) => {
if T.get("code").is_some() {
// when request failed
sleep(Duration::from_secs(1)).await;
} else {
// when request succeed
insert_value_container
.push(T.get("symbol").unwrap().as_str().unwrap().to_string()); // symbol
insert_value_container.push(buy_ordered_coin.order_id.to_string()); // buy_order_id
insert_value_container
.push(T.get("orderId").unwrap().as_u64().unwrap().to_string()); // sell_order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(buy_ordered_coin.close_time.to_string()); // close_time
insert_value_container
.push(T.get("status").unwrap().as_str().unwrap().to_string()); // status
insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt
if exchange_info_map.contains_key(&buy_ordered_coin.symbol) && trade_fee_map.contains_key(&buy_ordered_coin.symbol) {
let quote_asset_precision = exchange_info_map.get(&buy_ordered_coin.symbol).unwrap().quote_asset_precision;
let trade_fee = trade_fee_map.get(&buy_ordered_coin.symbol).unwrap().takercommission;
let get_usdt = rust_decimal::prelude::FromStr::from_str(
T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(),
)
.unwrap();
let get_usdt_fee_adjusted =
decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee))
.round_dp_with_strategy(
quote_asset_precision,
RoundingStrategy::ToZero,
);
let ordered_base_qty = rust_decimal::prelude::FromStr::from_str(
T.get("origQty").unwrap().as_str().unwrap(),
)
.unwrap();
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
insert_value_container.push(get_usdt.to_string()); // get_usdt
insert_value_container.push(get_usdt_fee_adjusted.to_string());
// get_usdt_fee_adjusted
} else {
insert_value_container.push(0.0.to_string()); // get_usdt
insert_value_container.push(0.0.to_string()); // get_usdt_fee_adjusted
}
insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
let sell_price = decimal_div(get_usdt, ordered_base_qty)
.round_dp_with_strategy(
quote_asset_precision,
RoundingStrategy::ToZero,
);
insert_value_container.push(sell_price.to_string());
// sell_price
} else {
insert_value_container.push(0.0.to_string()); // sell_price
}
insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss
insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price
insert_value_container.push(ordered_base_qty.to_string()); // base_qty_ordered
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
let pure_profit_percent = decimal_mul(
decimal_sub(
decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt),
dec!(1),
),
dec!(100),
);
insert_value_container
.push(buy_ordered_coin.pure_profit_percent.to_string());
// pure_profit_percent
} else {
insert_value_container.push(0.0.to_string()); // pure_profit_percent
}
match v {
Ok(T) => {
if T.get("code").is_some() {
// when request failed
sleep(Duration::from_secs(1)).await;
} else {
// when request succeed
insert_value_container
.push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent
insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer
insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long
.push(T.get("symbol").unwrap().as_str().unwrap().to_string()); // symbol
insert_value_container.push(buy_ordered_coin.order_id.to_string()); // buy_order_id
insert_value_container
.push(T.get("orderId").unwrap().as_u64().unwrap().to_string()); // sell_order_id
insert_value_container.push(server_epoch.to_string()); // transact_time
insert_value_container.push(buy_ordered_coin.close_time.to_string()); // close_time
insert_value_container
.push(T.get("status").unwrap().as_str().unwrap().to_string()); // status
insert_value_container.push(buy_ordered_coin.used_usdt.to_string()); // used_usdt
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
if exchange_info_map.contains_key(&buy_ordered_coin.symbol) && trade_fee_map.contains_key(&buy_ordered_coin.symbol) {
let quote_asset_precision = exchange_info_map.get(&buy_ordered_coin.symbol).unwrap().quote_asset_precision;
let trade_fee = trade_fee_map.get(&buy_ordered_coin.symbol).unwrap().takercommission;
let get_usdt = rust_decimal::prelude::FromStr::from_str(
T.get("cummulativeQuoteQty").unwrap().as_str().unwrap(),
)
.unwrap();
let get_usdt_fee_adjusted =
decimal_mul(get_usdt, decimal_sub(dec!(1), trade_fee))
.round_dp_with_strategy(
quote_asset_precision,
RoundingStrategy::ToZero,
);
let ordered_base_qty = rust_decimal::prelude::FromStr::from_str(
T.get("origQty").unwrap().as_str().unwrap(),
)
.unwrap();
// delete record in buy_ordered_coin_list
let delete_table_name = String::from("buy_ordered_coin_list");
let mut delete_condition = String::from("WHERE id = ");
delete_condition.push_str(buy_ordered_coin.id.to_string().as_str());
delete_record(&delete_table_name, &delete_condition).await;
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
insert_value_container.push(get_usdt.to_string()); // get_usdt
insert_value_container.push(get_usdt_fee_adjusted.to_string());
// get_usdt_fee_adjusted
} else {
insert_value_container.push(0.0.to_string()); // get_usdt
insert_value_container.push(0.0.to_string()); // get_usdt_fee_adjusted
}
insert_value_container.push(buy_ordered_coin.buy_price.to_string()); // buy_price
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
let sell_price = decimal_div(get_usdt, ordered_base_qty)
.round_dp_with_strategy(
quote_asset_precision,
RoundingStrategy::ToZero,
);
insert_value_container.push(sell_price.to_string());
// sell_price
} else {
insert_value_container.push(0.0.to_string()); // sell_price
}
insert_value_container.push(buy_ordered_coin.stoploss.to_string()); // stoploss
insert_value_container.push(buy_ordered_coin.target_price.to_string()); // target_price
insert_value_container.push(ordered_base_qty.to_string()); // base_qty_ordered
if T.get("status").unwrap().as_str().unwrap() == "FILLED" {
let pure_profit_percent = decimal_mul(
decimal_sub(
decimal_div(get_usdt_fee_adjusted, buy_ordered_coin.used_usdt),
dec!(1),
),
dec!(100),
);
insert_value_container
.push(buy_ordered_coin.pure_profit_percent.to_string());
// pure_profit_percent
} else {
insert_value_container.push(0.0.to_string()); // pure_profit_percent
}
insert_value_container
.push(buy_ordered_coin.maximum_profit_percent.to_string()); // maximum_profit_percent
insert_value_container.push(buy_ordered_coin.registerer.to_string()); // registerer
insert_value_container.push(buy_ordered_coin.is_long.to_string()); // is_long
insert_values.push(insert_value_container.clone());
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
// delete record in buy_ordered_coin_list
let delete_table_name = String::from("buy_ordered_coin_list");
let mut delete_condition = String::from("WHERE id = ");
delete_condition.push_str(buy_ordered_coin.id.to_string().as_str());
delete_record(&delete_table_name, &delete_condition).await;
}
}
}
}
Err(e) => {
println!("sell order failed!: {}", body);
Err(e) => {
log::warn!("sell order failed!: {}", body);
}
}
}
}
@ -1037,12 +1044,14 @@ pub async fn market_order(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/order?";
@ -1083,12 +1092,14 @@ pub async fn cancel_buy_order(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/order?";
@ -1210,7 +1221,7 @@ pub async fn cancel_buy_order(
}
Err(e) => {
query_buy_order(order, &client, trade_fee_map).await;
// println!("cancel order buy failed!: {}", body);
log::warn!("cancel order buy failed!: {}", body);
}
}
@ -1227,12 +1238,14 @@ pub async fn cancel_sell_order(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/order?";
@ -1485,7 +1498,7 @@ pub async fn cancel_sell_order(
}
}
Err(e) => {
println!("cancel sell order failed!: {}", body);
log::warn!("cancel sell order failed!: {}", body);
}
}
Ok(())
@ -1498,10 +1511,12 @@ pub async fn cancel_all_order(
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// building URL
let mut url = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
} else if RUNNING_MODE == REAL {
url.push_str(URL);
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
} else if RUNNING_MODE == REAL {
url.push_str(URL);
}
}
let endpoint_url = "/api/v3/openOrders?";
@ -1526,12 +1541,14 @@ pub async fn all_orders(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/allOrders?";
@ -1565,12 +1582,14 @@ pub async fn query_buy_order(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/order?";
@ -1686,7 +1705,7 @@ pub async fn query_buy_order(
}
}
Err(e) => {
println!("query order failed!: {}", body);
log::warn!("query order failed!: {}", body);
}
}
Ok(())
@ -1702,12 +1721,14 @@ pub async fn query_sell_order(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/order?";
@ -1790,7 +1811,7 @@ pub async fn query_sell_order(
}
}
Err(e) => {
println!("query sell order failed!: {}", body);
log::warn!("query sell order failed!: {}", body);
}
}
Ok(())
@ -1803,12 +1824,14 @@ pub async fn current_open_orders(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/openOrders?";
@ -1888,7 +1911,7 @@ pub async fn all_coins_information(
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
}
Err(e) => {
println!("all coins information failed!: {}", body);
log::warn!("all coins information failed!: {}", body);
}
}
Ok(())
@ -1901,12 +1924,14 @@ pub async fn account_information(
// building URL and API-keys
let mut url = String::new();
let mut api_key = String::new();
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
unsafe {
if RUNNING_MODE == TEST {
url.push_str(URL_TEST);
api_key = API_KEY_TESTNET.to_string();
} else if RUNNING_MODE == REAL {
url.push_str(URL);
api_key = API_KEY.to_string();
}
}
let endpoint_url = "/api/v3/account?";
@ -1940,10 +1965,12 @@ pub async fn account_information(
// insert contents into table
let mut insert_table_name = String::new();
if RUNNING_MODE == TEST {
insert_table_name = String::from("wallet_testnet");
} else if RUNNING_MODE == REAL {
insert_table_name = String::from("wallet");
unsafe {
if RUNNING_MODE == TEST {
insert_table_name = String::from("wallet_testnet");
} else if RUNNING_MODE == REAL {
insert_table_name = String::from("wallet");
}
}
let insert_columns = vec!["asset", "free", "locked"];
let mut insert_values: Vec<Vec<String>> = Vec::new();
@ -1966,7 +1993,7 @@ pub async fn account_information(
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
}
Err(e) => {
println!("account information failed!: {}", body);
log::warn!("account information failed!: {}", body);
}
}
Ok(())
@ -2012,10 +2039,12 @@ async fn hmac_signature(query: &mut String) {
query_build.push_str(&recv_window_size);
let mut secret_key = String::new();
if RUNNING_MODE == TEST {
secret_key.push_str(SECRET_KEY_TESTNET);
} else if RUNNING_MODE == REAL {
secret_key.push_str(SECRET_KEY);
unsafe {
if RUNNING_MODE == TEST {
secret_key.push_str(SECRET_KEY_TESTNET);
} else if RUNNING_MODE == REAL {
secret_key.push_str(SECRET_KEY);
}
}
query.push_str(&query_build);

View File

@ -10,6 +10,7 @@ use std::borrow::{Borrow, BorrowMut};
use std::sync::Arc;
use std::collections::HashMap;
use tokio::{join, sync::Mutex, time::*};
use log;
#[derive(Debug, Clone)]
pub struct TradeFee {
@ -90,7 +91,7 @@ async fn de_all_coin_price_json(
"symbol" => symbol = element.1.as_str().unwrap().to_string(),
"price" => price = element.1.as_str().unwrap().parse::<f64>().unwrap(),
_ => {
println!("Elements in body msg are changed. Please update both your coinprices table and vectors.");
log::error!("Elements in body msg are changed. Please update both your coinprices table and vectors.");
}
}
price_vec.insert(symbol.clone(), price);
@ -157,7 +158,7 @@ pub async fn request_trade_fee(
// println!("tradefee 완료");
}
Err(E) => {
println!("request_trade_fee body failed!: {:?}", E);
log::warn!("request_trade_fee body failed!: {:?}", E);
}
}
@ -197,7 +198,7 @@ async fn de_trade_fee_json(
.unwrap()
}
_ => {
println!("Elements in body msg are changed. Please update both your tradefees table and vectors.");
log::error!("Elements in body msg are changed. Please update both your tradefees table and vectors.");
}
}
}
@ -226,7 +227,7 @@ pub async fn request_24hr_ticker_price_change_statistics(
// println!("24h change 완료");
}
Err(E) => {
println!(
log::warn!(
"request_24hr_ticker_price_change_statistics body failed!: {:?}",
E
);
@ -234,7 +235,7 @@ pub async fn request_24hr_ticker_price_change_statistics(
}
}
Err(E) => {
println!(
log::warn!(
"request_24hr_ticker_price_change_statistics response failed!: {:?}",
E
);
@ -307,7 +308,7 @@ async fn de_24h_change_json(body: &String) -> Result<(), Box<dyn std::error::Err
"lastId" => value_vec[19] = element.1.as_i64().unwrap().to_string(),
"count" => value_vec[20] = element.1.as_i64().unwrap().to_string(),
_ => {
println!("Elements in body msg are changed. Please update both your 24h_change table and vectors.");
log::error!("Elements in body msg are changed. Please update both your 24h_change table and vectors.");
}
}
}

View File

@ -841,45 +841,47 @@ async fn initialize_database() {
.expect("Failed to delete rows!");
// table initialization for SIMUL MODE
if RUNNING_MODE == SIMUL {
#[derive(Debug, FromRow)]
struct Symbols {
symbol: String,
}
let fetch_table_name = String::from("valid_usdt_trades");
let column_name = String::from("symbol");
let condition = None;
let mut symbols = Symbols {
symbol: String::new(),
};
let symbols_vec = select_record(&fetch_table_name, &column_name, &condition, &symbols)
.await
.expect("Failed to fetch records!");
let insert_table_name = String::from("wallet");
let insert_columns = vec!["asset", "free", "locked"];
let mut insert_values: Vec<Vec<String>> = Vec::new();
let mut insert_value_container: Vec<String> = Vec::new();
let mut symbol_truncated = String::new();
unsafe {
if RUNNING_MODE == SIMUL {
#[derive(Debug, FromRow)]
struct Symbols {
symbol: String,
}
let fetch_table_name = String::from("valid_usdt_trades");
let column_name = String::from("symbol");
let condition = None;
let mut symbols = Symbols {
symbol: String::new(),
};
let symbols_vec = select_record(&fetch_table_name, &column_name, &condition, &symbols)
.await
.expect("Failed to fetch records!");
let insert_table_name = String::from("wallet");
let insert_columns = vec!["asset", "free", "locked"];
let mut insert_values: Vec<Vec<String>> = Vec::new();
let mut insert_value_container: Vec<String> = Vec::new();
let mut symbol_truncated = String::new();
insert_value_container.clear();
insert_value_container.push(String::from("USDT"));
insert_value_container.push(0.to_string());
insert_value_container.push(0.to_string());
insert_values.push(insert_value_container.clone());
for mut element in symbols_vec {
insert_value_container.clear();
symbol_truncated.clear();
element.symbol.pop();
element.symbol.pop();
element.symbol.pop();
element.symbol.pop();
insert_value_container.push(element.symbol);
insert_value_container.push(String::from("USDT"));
insert_value_container.push(0.to_string());
insert_value_container.push(0.to_string());
insert_values.push(insert_value_container.clone());
for mut element in symbols_vec {
insert_value_container.clear();
symbol_truncated.clear();
element.symbol.pop();
element.symbol.pop();
element.symbol.pop();
element.symbol.pop();
insert_value_container.push(element.symbol);
insert_value_container.push(0.to_string());
insert_value_container.push(0.to_string());
insert_values.push(insert_value_container.clone());
}
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
}
insert_records(&insert_table_name, &insert_columns, &insert_values).await;
}
println!("Ok");
@ -1025,37 +1027,39 @@ async fn initialize_database() {
.expect("Failed to insert initial row!");
}
if RUNNING_MODE == SIMUL {
assets_managing_team::add_extra_usdt(dec!(10000000.0)).await;
assets_managing_team::update_current_total_usdt().await;
} else {
let mut table_name = String::new();
let column = String::from("free");
let condition = Some(String::from("WHERE asset = 'USDT'"));
unsafe {
if RUNNING_MODE == SIMUL {
assets_managing_team::add_extra_usdt(dec!(10000000.0)).await;
assets_managing_team::update_current_total_usdt().await;
} else {
let mut table_name = String::new();
let column = String::from("free");
let condition = Some(String::from("WHERE asset = 'USDT'"));
#[derive(FromRow)]
struct OneDecimal {
free: Decimal,
};
#[derive(FromRow)]
struct OneDecimal {
free: Decimal,
};
let data_struct = OneDecimal {
free: Decimal::new(0, 8),
};
let data_struct = OneDecimal {
free: Decimal::new(0, 8),
};
order_team::account_information(&client).await;
order_team::account_information(&client).await;
if RUNNING_MODE == TEST {
table_name = String::from("wallet_testnet");
} else if RUNNING_MODE == REAL {
table_name = String::from("wallet");
if RUNNING_MODE == TEST {
table_name = String::from("wallet_testnet");
} else if RUNNING_MODE == REAL {
table_name = String::from("wallet");
}
let result = select_record(&table_name, &column, &condition, &data_struct)
.await
.unwrap();
let free_usdt = result.first().unwrap().free;
assets_managing_team::add_extra_usdt(free_usdt).await;
assets_managing_team::update_current_total_usdt().await;
}
let result = select_record(&table_name, &column, &condition, &data_struct)
.await
.unwrap();
let free_usdt = result.first().unwrap().free;
assets_managing_team::add_extra_usdt(free_usdt).await;
assets_managing_team::update_current_total_usdt().await;
}
assets_managing_team::update_kelly_criterion().await;
assets_managing_team::set_available_usdt().await;
@ -1193,6 +1197,7 @@ async fn initialize_database() {
("pure_profit_percent", "double", None),
("minimum_profit_percent", "double", None),
("maximum_profit_percent", "double", None),
// ("sell_count", "smallint", Some("UN")),
("registerer", "smallint", Some("UN")),
("is_long", "tinyint", Some("UN")),
];
@ -1274,6 +1279,7 @@ async fn initialize_database() {
("base_qty_ordered", "decimal(16,8)", None),
("pure_profit_percent", "decimal(16,8)", None),
("maximum_profit_percent", "double", None),
// ("sell_count", "smallint", Some("UN")),
("registerer", "smallint", Some("UN")),
("is_long", "tinyint", Some("UN")),
];
@ -1293,46 +1299,49 @@ async fn initialize_database() {
}
// delete records tagged SIMUL
if RUNNING_MODE == SIMUL {
let select_table_name = String::from("sell_ordered_coin_list");
let select_columns = String::from("*");
let select_condition = Some(String::from("WHERE status = 'SIMUL'"));
let data_struct = SellOrderedCoinList {
id: 0,
symbol: String::new(),
buy_order_id: 0,
sell_order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
get_usdt: Decimal::new(0, 8),
get_usdt_fee_adjusted: Decimal::new(0, 8),
buy_price: Decimal::new(0, 8),
sell_price: Decimal::new(0, 8),
stoploss: Decimal::new(0, 8),
target_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
pure_profit_percent: Decimal::new(0, 8),
maximum_profit_percent: 0.0,
registerer: 0,
is_long: 0,
};
unsafe {
if RUNNING_MODE == SIMUL {
let select_table_name = String::from("sell_ordered_coin_list");
let select_columns = String::from("*");
let select_condition = Some(String::from("WHERE status = 'SIMUL'"));
let data_struct = SellOrderedCoinList {
id: 0,
symbol: String::new(),
buy_order_id: 0,
sell_order_id: 0,
transact_time: 0,
close_time: 0,
status: String::new(),
used_usdt: Decimal::new(0, 8),
get_usdt: Decimal::new(0, 8),
get_usdt_fee_adjusted: Decimal::new(0, 8),
buy_price: Decimal::new(0, 8),
sell_price: Decimal::new(0, 8),
stoploss: Decimal::new(0, 8),
target_price: Decimal::new(0, 8),
base_qty_ordered: Decimal::new(0, 8),
pure_profit_percent: Decimal::new(0, 8),
maximum_profit_percent: 0.0,
// sell_count: 0,
registerer: 0,
is_long: 0,
};
let select_result = try_select_record(
&select_table_name,
&select_columns,
&select_condition,
&data_struct,
)
.await
.unwrap();
let select_result = try_select_record(
&select_table_name,
&select_columns,
&select_condition,
&data_struct,
)
.await
.unwrap();
if !select_result.is_empty() {
for element in select_result {
let mut condition = String::from("WHERE id=");
condition.push_str(element.id.to_string().as_str());
delete_record(&select_table_name, &condition).await;
if !select_result.is_empty() {
for element in select_result {
let mut condition = String::from("WHERE id=");
condition.push_str(element.id.to_string().as_str());
delete_record(&select_table_name, &condition).await;
}
}
}
}

View File

@ -22,7 +22,8 @@ pub enum RunningMode {
TEST,
REAL,
}
pub const RUNNING_MODE: RunningMode = RunningMode::SIMUL;
pub static mut RUNNING_MODE: RunningMode = RunningMode::SIMUL;
pub mod coex;
pub mod coin_health_check_team;

View File

@ -18,9 +18,16 @@ use std::{
};
use tokio::{fs::*, join, sync::mpsc, sync::watch, sync::Mutex, task::*, time::*};
use tradingbot::{RunningMode::*, *};
use clap::{arg, Command};
use log::Level;
use simple_logger::set_up_color_terminal;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// parse argument and set program preference
program_setting();
// Datebase initialization
initialization::initialization().await;
// // let c1 = vec!(("name", "Shima Nabil"));
@ -210,14 +217,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut exchange_info_map_capacity = rx_exchange_info_map.clone();
{
if RUNNING_MODE == RunningMode::REAL {
println!("*** REAL MODE ***");
} else if RUNNING_MODE == RunningMode::TEST {
println!("*** TEST MODE ***");
} else if RUNNING_MODE == RunningMode::SIMUL {
println!("*** SIMULATION MODE ***");
}
// pre-fetching candle data: 30m, 1d, 1w and 1mon
print!("pre-fetching candle data: 30m, 1d, 1w and 1mon..");
std::io::stdout().flush();
@ -245,29 +244,31 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// sleep as much as the loop recurs per 60 seconds, expecting child threads will have finished within 60 seconds.
println!("Ok..");
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
let mut elapsed_time = instant.elapsed().as_secs();
let mut remaining_time: u64 = 60 - elapsed_time;
unsafe {
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
let mut elapsed_time = instant.elapsed().as_secs();
let mut remaining_time: u64 = 60 - elapsed_time;
while remaining_time > 0 && 60 > remaining_time {
print!("\rstart tradingbot in {:2} seconds", remaining_time);
io::stdout().flush();
elapsed_time = instant.elapsed().as_secs();
loop {
let temp_elapsed_time = instant.elapsed().as_secs();
let is_overflowed = remaining_time.overflowing_sub(1).1;
while remaining_time > 0 && 60 > remaining_time {
print!("\rstart tradingbot in {:2} seconds", remaining_time);
io::stdout().flush();
elapsed_time = instant.elapsed().as_secs();
loop {
let temp_elapsed_time = instant.elapsed().as_secs();
let is_overflowed = remaining_time.overflowing_sub(1).1;
if is_overflowed == true {
break;
}
if elapsed_time < temp_elapsed_time {
remaining_time -= 1;
break;
if is_overflowed == true {
break;
}
if elapsed_time < temp_elapsed_time {
remaining_time -= 1;
break;
}
}
}
}
println!("\nTradingbot is running");
println!("\nTradingbot is running");
}
}
}
@ -620,7 +621,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tx_task4.send(4).expect("The mpsc channel has been closed.");
}
Err(E) => {
println!(">>> Failed to monitor usdt_24h_change_profit_index.");
log::warn!(">>> Failed to monitor usdt_24h_change_profit_index.");
}
}
// match result {
@ -629,7 +630,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// match result {
// Ok(T) => {},
// Err(E) => {
// println!(">>> Failed to monitor total_24h_change_profit_index.");
// log::warn!(">>> Failed to monitor total_24h_change_profit_index.");
// }
// };
@ -637,7 +638,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// match result {
// Ok(T) => {},
// Err(E) => {
// println!(">>> Failed to monitor usdt_24h_change_profit_index.");
// log::warn!(">>> Failed to monitor usdt_24h_change_profit_index.");
// }
// };
@ -645,12 +646,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// match result {
// Ok(T) => {},
// Err(E) => {
// println!(">>> Failed to monitor total_price_down_dist_index.");
// log::warn!(">>> Failed to monitor total_price_down_dist_index.");
// }
// };
// },
// Err(E) => {
// println!(">>> Failed to fetch 24h price change data from endpoint or parse message.");
// log::warn!(">>> Failed to fetch 24h price change data from endpoint or parse message.");
// }
// };
@ -698,7 +699,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.await;
rt_price_1m_map_write_temp_c = rt_price_1m_map_write_temp.clone();
if tx_rt_price_1m_map.is_closed() {
eprintln!("tx_rt_price_1m_vec has been closed!");
log::error!("tx_rt_price_1m_vec has been closed!");
} else {
tx_rt_price_1m_map.send_modify(|vec| *vec = rt_price_1m_map_write_temp);
}
@ -721,7 +722,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.await;
rt_price_30m_map_write_temp_c = rt_price_30m_map_write_temp.clone();
if tx_rt_price_30m_map.is_closed() {
eprintln!("tx_rt_price_30m_vec has been closed!");
log::error!("tx_rt_price_30m_vec has been closed!");
} else {
tx_rt_price_30m_map
.send_modify(|map: &mut HashMap<String, Vec<RealtimePriceData>>| *map = rt_price_30m_map_write_temp);
@ -748,7 +749,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
match result {
Ok(T) => {
if tx_rt_price_1d_map.is_closed() {
eprintln!("tx_rt_price_1d_vec has been closed!");
log::error!("tx_rt_price_1d_vec has been closed!");
} else {
tx_rt_price_1d_map.send_modify(|map| *map = rt_price_1d_map_write_temp);
}
@ -1004,124 +1005,128 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// COEX part
// Task#16: execute strategis for buy
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move {
sleep(Duration::from_secs(40)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
unsafe {
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move {
sleep(Duration::from_secs(40)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let mut all_data = AllData::new();
all_data.valid_symbol_vec = rx3_valid_usdt_trade_set.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx3_rt_price_1m_map.borrow().clone();
all_data.rt_price_30m_vec = rx3_rt_price_30m_map.borrow().clone();
all_data.rt_price_1d_vec = rx3_rt_price_1d_map.borrow().clone();
all_data.rt_price_1w_vec = rx3_rt_price_1w_map.borrow().clone();
all_data.rt_price_1mon_vec = rx3_rt_price_1mon_map.borrow().clone();
let result =
strategy_team::strategy_manager::execute_list_up_for_buy(&all_data).await;
match result {
Ok(T) => {
tx_task16
.send(16)
.expect("The mpsc channel has been closed.");
}
Err(E) => {
// log::error!("Couldn't execute strategists.");
}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
});
} else {
tokio::task::spawn(async move {
sleep(Duration::from_secs(10)).await;
let mut elapsed_time = 0;
let mut all_data = AllData::new();
all_data.valid_symbol_vec = rx3_valid_usdt_trade_set.borrow().clone();
loop {
let instant = Instant::now();
all_data.valid_symbol_vec = rx3_valid_usdt_trade_set.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx3_rt_price_1m_map.borrow().clone();
all_data.rt_price_30m_vec = rx3_rt_price_30m_map.borrow().clone();
all_data.rt_price_1d_vec = rx3_rt_price_1d_map.borrow().clone();
all_data.rt_price_1w_vec = rx3_rt_price_1w_map.borrow().clone();
all_data.rt_price_1mon_vec = rx3_rt_price_1mon_map.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx3_rt_price_1m_map.borrow().clone();
all_data.rt_price_30m_vec = rx3_rt_price_30m_map.borrow().clone();
all_data.rt_price_1d_vec = rx3_rt_price_1d_map.borrow().clone();
all_data.rt_price_1w_vec = rx3_rt_price_1w_map.borrow().clone();
all_data.rt_price_1mon_vec = rx3_rt_price_1mon_map.borrow().clone();
// let result = coex::strategy_team::execute_strategist_for_test(&all_data).await;
let result =
strategy_team::strategy_manager::execute_list_up_for_buy(&all_data).await;
// match result {
// Ok(T) => {
// tx_task16
// .send(16)
// .expect("The mpsc channel has been closed.");
// }
// Err(E) => {}
// }
match result {
Ok(T) => {
tx_task16
.send(16)
.expect("The mpsc channel has been closed.");
}
Err(E) => {
// eprintln!("Couldn't execute strategists.");
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
});
} else {
tokio::task::spawn(async move {
sleep(Duration::from_secs(10)).await;
let mut elapsed_time = 0;
let mut all_data = AllData::new();
loop {
let instant = Instant::now();
all_data.valid_symbol_vec = rx3_valid_usdt_trade_set.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx3_rt_price_1m_map.borrow().clone();
all_data.rt_price_30m_vec = rx3_rt_price_30m_map.borrow().clone();
all_data.rt_price_1d_vec = rx3_rt_price_1d_map.borrow().clone();
all_data.rt_price_1w_vec = rx3_rt_price_1w_map.borrow().clone();
all_data.rt_price_1mon_vec = rx3_rt_price_1mon_map.borrow().clone();
// let result = coex::strategy_team::execute_strategist_for_test(&all_data).await;
// match result {
// Ok(T) => {
// tx_task16
// .send(16)
// .expect("The mpsc channel has been closed.");
// }
// Err(E) => {}
// }
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
});
});
}
}
// Task#17: execute strategis for sell
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move {
sleep(Duration::from_secs(40)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let mut all_data = AllData::new();
let mut exchange_info_map: HashMap<String, ExchangeInfo> = HashMap::new();
let mut trade_fee_map: HashMap<String, TradeFee> = HashMap::new();
unsafe {
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL {
tokio::task::spawn(async move {
sleep(Duration::from_secs(40)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let mut all_data = AllData::new();
let mut exchange_info_map: HashMap<String, ExchangeInfo> = HashMap::new();
let mut trade_fee_map: HashMap<String, TradeFee> = HashMap::new();
all_data.valid_symbol_vec = rx4_valid_usdt_trade_set.borrow().clone();
exchange_info_map = rx6_exchange_info_map.borrow().clone();
trade_fee_map = rx5_tradefee_map.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx5_rt_price_1m_map.borrow().clone();
all_data.rt_price_30m_vec = rx5_rt_price_30m_map.borrow().clone();
all_data.rt_price_1d_vec = rx4_rt_price_1d_map.borrow().clone();
all_data.rt_price_1w_vec = rx4_rt_price_1w_map.borrow().clone();
all_data.rt_price_1mon_vec = rx4_rt_price_1mon_map.borrow().clone();
all_data.valid_symbol_vec = rx4_valid_usdt_trade_set.borrow().clone();
exchange_info_map = rx6_exchange_info_map.borrow().clone();
trade_fee_map = rx5_tradefee_map.borrow().clone();
// realtime price data
all_data.rt_price_1m_vec = rx5_rt_price_1m_map.borrow().clone();
all_data.rt_price_30m_vec = rx5_rt_price_30m_map.borrow().clone();
all_data.rt_price_1d_vec = rx4_rt_price_1d_map.borrow().clone();
all_data.rt_price_1w_vec = rx4_rt_price_1w_map.borrow().clone();
all_data.rt_price_1mon_vec = rx4_rt_price_1mon_map.borrow().clone();
let result = strategy_team::strategy_manager::execute_list_up_for_sell(
&all_data,
&exchange_info_map,
&trade_fee_map,
)
.await;
let result = strategy_team::strategy_manager::execute_list_up_for_sell(
&all_data,
&exchange_info_map,
&trade_fee_map,
)
.await;
match result {
Ok(T) => {
tx_task17
.send(17)
.expect("The mpsc channel has been closed.");
match result {
Ok(T) => {
tx_task17
.send(17)
.expect("The mpsc channel has been closed.");
}
Err(E) => {
// log::error!("Couldn't execute strategists.");
}
}
Err(E) => {
// eprintln!("Couldn't execute strategists.");
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
});
});
}
}
// Task#18: monitoring pre-suggested coins
@ -1152,47 +1157,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
});
// Task#19: buy_coin
if RUNNING_MODE == REAL || RUNNING_MODE == SIMUL || RUNNING_MODE == TEST {
tokio::task::spawn(async move {
sleep(Duration::from_secs(30)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let exchange_info_map = rx_exchange_info_map.borrow().clone();
let trade_fee_map = rx_tradefee_map.borrow().clone();
let result =
coex::exchange_team::buy_coin(&exchange_info_map, &trade_fee_map).await;
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task19
.send(19)
.expect("The mpsc channel has been closed.");
}
Err(E) => {
eprint!("Error: {:?}", E);
}
}
// sleep as much as the loop recurs per 200ms second if all operation finished within 200ms
elapsed_time = instant.elapsed().as_millis();
if 200 > elapsed_time {
sleep(Duration::from_millis((200 - elapsed_time) as u64)).await;
}
}
});
} else {
tokio::task::spawn(async move {
sleep(Duration::from_secs(15)).await;
let mut elapsed_time = 0;
tokio::task::spawn(async move {
sleep(Duration::from_secs(30)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let exchange_info_vec = rx_exchange_info_map.borrow().clone();
let trade_fee_vec = rx_tradefee_map.borrow().clone();
// let result = coex::exchange_team::buy_coin_for_test(&client, &coin_price_vec, &exchange_info_vec, &trade_fee_vec).await;
let result = coex::exchange_team::buy_coin(&exchange_info_vec, &trade_fee_vec).await;
let exchange_info_map = rx_exchange_info_map.borrow().clone();
let trade_fee_map = rx_tradefee_map.borrow().clone();
let result =
coex::exchange_team::buy_coin(&exchange_info_map, &trade_fee_map).await;
// send Task#0 a message to notify running on
match result {
@ -1201,7 +1175,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.send(19)
.expect("The mpsc channel has been closed.");
}
Err(E) => {}
Err(E) => {
eprint!("Error: {:?}", E);
}
}
// sleep as much as the loop recurs per 200ms second if all operation finished within 200ms
@ -1209,57 +1185,51 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
if 200 > elapsed_time {
sleep(Duration::from_millis((200 - elapsed_time) as u64)).await;
}
});
}
}
});
// Task#20: monitoring_open_buy_order
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
tokio::task::spawn(async move {
if RUNNING_MODE == REAL {
unsafe {
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
tokio::task::spawn(async move {
sleep(Duration::from_secs(30)).await;
} else if RUNNING_MODE == TEST {
sleep(Duration::from_secs(10)).await;
}
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000))
.build()
.unwrap();
let trade_fee_map = rx2_tradefee_map.borrow().clone();
let result = coex::order_team::monitoring_open_buy_order(
&client,
&trade_fee_map,
)
.await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000))
.build()
.unwrap();
let trade_fee_map = rx2_tradefee_map.borrow().clone();
let result = coex::order_team::monitoring_open_buy_order(
&client,
&trade_fee_map,
)
.await;
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task20
.send(20)
.expect("The mpsc channel has been closed.");
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task20
.send(20)
.expect("The mpsc channel has been closed.");
}
Err(E) => {}
}
Err(E) => {}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 200 > elapsed_time {
sleep(Duration::from_millis((200 - elapsed_time) as u64)).await;
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 200 > elapsed_time {
sleep(Duration::from_millis((200 - elapsed_time) as u64)).await;
}
}
}
});
});
}
}
// Task#21: update_price_of_filled_buy_order
tokio::task::spawn(async move {
if RUNNING_MODE == TEST {
sleep(Duration::from_secs(10)).await;
} else {
sleep(Duration::from_secs(30)).await;
}
sleep(Duration::from_secs(30)).await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
@ -1294,46 +1264,44 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
});
// Task#22: monitoring_open_sell_order
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
tokio::task::spawn(async move {
if RUNNING_MODE == REAL {
unsafe {
if RUNNING_MODE == REAL || RUNNING_MODE == TEST {
tokio::task::spawn(async move {
sleep(Duration::from_secs(30)).await;
} else if RUNNING_MODE == TEST {
sleep(Duration::from_secs(10)).await;
}
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000))
.build()
.unwrap();
let exchange_info_vec = rx4_exchange_info_map.borrow().clone();
let trade_fee_vec = rx4_tradefee_map.borrow().clone();
let result = coex::order_team::monitoring_open_sell_order(
&client,
&exchange_info_vec,
&trade_fee_vec,
)
.await;
let mut elapsed_time = 0;
loop {
let instant = Instant::now();
let client = ClientBuilder::new()
.timeout(tokio::time::Duration::from_millis(3000))
.build()
.unwrap();
let exchange_info_vec = rx4_exchange_info_map.borrow().clone();
let trade_fee_vec = rx4_tradefee_map.borrow().clone();
let result = coex::order_team::monitoring_open_sell_order(
&client,
&exchange_info_vec,
&trade_fee_vec,
)
.await;
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task22
.send(22)
.expect("The mpsc channel has been closed.");
// send Task#0 a message to notify running on
match result {
Ok(T) => {
tx_task22
.send(22)
.expect("The mpsc channel has been closed.");
}
Err(E) => {}
}
Err(E) => {}
}
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
// sleep as much as the loop recurs per 1 second if all operation finished within 1 second.
elapsed_time = instant.elapsed().as_millis();
if 250 > elapsed_time {
sleep(Duration::from_millis((250 - elapsed_time) as u64)).await;
}
}
}
});
});
}
}
// Task#23: monitoring_filled_sell_order
@ -1417,7 +1385,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.expect("The mpsc channel has been closed.");
}
Err(E) => {
println!("{}", E);
log::error!("{}", E);
}
}
@ -1444,7 +1412,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.expect("The mpsc channel has been closed.");
}
Err(E) => {
println!("{}", E);
log::error!("{}", E);
}
}
@ -1502,118 +1470,50 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
// #![allow(unused)]
// #![allow(warnings)]
fn program_setting() {
let matches = Command::new("Tradingbot")
.arg(arg!(log_level: -l --log <level> "Select log level: trace, debug, info, warn, error").default_value("error"))
.arg(arg!(mode: -m --mode <mode> "Select mode: real, simul, test").required(true))
.get_matches();
// mod assets_managing_team;
// mod database_control;
// mod value_estimation_team;
// mod plotting_team;
// mod request_test;
// set log level
set_up_color_terminal();
if let Some(level) = matches.get_one::<String>("log_level") {
match level.clone().to_ascii_lowercase().as_str() {
"trace" => simple_logger::init_with_level(Level::Trace).unwrap(),
"debug" => simple_logger::init_with_level(Level::Debug).unwrap(),
"info" => simple_logger::init_with_level(Level::Info).unwrap(),
"warn" => simple_logger::init_with_level(Level::Warn).unwrap(),
"error" => simple_logger::init_with_level(Level::Error).unwrap(),
_ => {
simple_logger::init_with_level(Level::Error).unwrap();
log::error!("wrong log level argument.");
std::process::exit(0);
}
// use std::sync::{Arc};
// use reqwest::{Client, ClientBuilder};
// use tokio::{task::*, time::*, sync::watch, join, fs::*};
// use sqlx::{ mysql::*, Executor, Connection, FromRow, Row };
}
}
// pub const DB_URL: &str = "mysql://root:Durtkarovh23!@localhost:3306/tradingbot";
// #[tokio::main]
// async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>>{
// let (tx1, mut rx1) = watch::channel(0);
// let mut rx2 = rx1.clone();
// let mut cnt = 0;
// tokio::task::spawn(async move{
// loop{
// println!("Task #1: {}", cnt);
// tx1.send(cnt).expect("tx1-rx1 channel has been closed.");
// cnt += 1;
// sleep(Duration::from_secs(1)).await;
// }
// });
// tokio::task::spawn(async move{
// loop{
// let tx1_changed = rx1.changed().await;
// match tx1_changed {
// Ok(T) => {
// println!(" Task #2: {:?}", rx1.borrow());
// }
// Err(E) => {
// println!(">>> Failed to fetch tradefee data from endpoint or parse message.");
// }
// }
// }
// });
// tokio::task::spawn(async move{
// loop{
// let tx1_changed = rx2.changed().await;
// match tx1_changed {
// Ok(T) => {
// println!(" Task #3: {:?}", rx2.borrow());
// }
// Err(E) => {
// println!(">>> Failed to fetch tradefee data from endpoint or parse message.");
// }
// }
// println!("what");
// }
// });
// // let client = ClientBuilder::new().connect_timeout(tokio::time::Duration::from_millis(1200)).build().unwrap();
// loop{
// // request_test::request_candlestick_data(&client).await;
// // plotting_team::plot_dp_mean_open_close_candle().await;
// // value_estimation_team::mean_price_for24h_candle_30m().await;
// // let job2 =
// // let job3 =
// // join!(job1);
// // let job4 = tokio::task::spawn(assets_managing_team::request_wallet_info(api_key, secret_key, time.return_from_local_epoch(), time.return_difference_epoch()));
// // tokio::join!(j1, j2, j3, j4, j5);
// println!("main ended!");
// sleep(Duration::from_secs(6)).await;
// }
// Ok(())
// }
// // use plotters::prelude::*;
// // fn main() -> Result<(), Box<dyn std::error::Error>> {
// // let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
// // root.fill(&WHITE)?;
// // let mut chart = ChartBuilder::on(&root)
// // .caption("y=x^2", ("sans-serif", 50).into_font())
// // .margin(5)
// // .x_label_area_size(30)
// // .y_label_area_size(30)
// // .build_cartesian_2d(-1f32..1f32, -0.1f32..1f32)?;
// //
// // chart.configure_mesh().draw()?;
// //
// // chart
// // .draw_series(LineSeries::new(
// // (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
// // &RED,
// // ))?
// // .label("y = x^2")
// // .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], &RED));
// //
// // chart
// // .configure_series_labels()
// // .background_style(&WHITE.mix(0.8))
// // .border_style(&BLACK)
// // .draw()?;
// //
// // Ok(())
// // }
// set mode
let mut mode: String = matches.get_one::<String>("mode").unwrap().clone();
unsafe {
match mode.to_ascii_lowercase().as_str() {
"real" => {
RUNNING_MODE = RunningMode::REAL;
println!("*** REAL MODE ***");
},
"simul" => {
RUNNING_MODE = RunningMode::SIMUL;
println!("*** SIMULATION MODE ***");
},
"test" => {
RUNNING_MODE = RunningMode::TEST;
println!("*** TEST MODE ***");
},
_ => {
log::error!("wrong mode argument.");
std::process::exit(0);
}
}
}
}

View File

@ -7,6 +7,7 @@ use rand::*;
use reqwest::{Client, ClientBuilder, Response};
use tokio::join;
use tokio::time::*;
use log;
#[derive(Debug)]
pub struct ServerHealth {
@ -51,7 +52,10 @@ pub async fn execute_server_health_check(
waiting_time = rng.gen_range(1..=serverhealth.waiting_maximum);
// update_database(&serverhealth).await;
println!(">>> retry connection after {} second(s).", waiting_time);
if waiting_time > 2 {
log::warn!(">>> retry connection after {} second(s).", waiting_time);
}
sleep(Duration::from_secs(waiting_time as u64)).await;
}
}