tradingbot/src/strategy_team/strategy_manager.rs
2023-12-18 04:11:12 +09:00

706 lines
28 KiB
Rust

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 super::strategy_test;
use super::{
exists_record, insert_one_record, try_join_all, try_select_record, AllData, ExchangeInfo,
FilteredData, FromRow, RealtimePriceData, TradeFee,
};
use crate::signal_association::signal_decision::*;
use tokio::time::{sleep, Duration, Instant};
#[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<dyn std::error::Error + Send + Sync>> {
let mut task_vec = Vec::new();
// let all_data_c3 = all_data.clone();
// let all_data_c4 = all_data.clone();
let all_data_c5 = all_data.clone();
let all_data_c6 = all_data.clone();
// strategist_001(all_data).await?;
// strategist_002(all_data).await?;
// task_vec.push(tokio::spawn(async move {
// crate::strategy_team::strategy_003::list_up_for_buy(all_data_c3).await;
// }));
// task_vec.push(tokio::spawn(async move {
// crate::strategy_team::strategy_004::list_up_for_buy(all_data_c4).await;
// }));
task_vec.push(tokio::spawn(async move {
crate::strategy_team::strategy_005::list_up_for_buy(all_data_c5).await;
}));
task_vec.push(tokio::spawn(async move {
crate::strategy_team::strategy_006::list_up_for_buy(all_data_c6).await;
}));
try_join_all(task_vec).await?;
Ok(())
}
pub async fn execute_list_up_for_sell(
all_data: &AllData,
exchange_info_vec: &Vec<ExchangeInfo>,
trade_fee_vec: &Vec<TradeFee>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
crate::strategy_team::strategy_004::list_up_for_sell(
all_data,
exchange_info_vec,
trade_fee_vec,
)
.await?;
crate::strategy_team::strategy_005::list_up_for_sell(
all_data,
exchange_info_vec,
trade_fee_vec,
)
.await?;
crate::strategy_team::strategy_006::list_up_for_sell(
all_data,
exchange_info_vec,
trade_fee_vec,
)
.await?;
Ok(())
}
// useful functions for strategists
pub async fn get_current_price(
symbol: &String,
rt_price_vec: &Vec<(String, Vec<RealtimePriceData>)>,
) -> Option<f64> {
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_coins: &Vec<FilteredData>,
alldata: &AllData,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// 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",
"stoploss",
"target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
for list_element in &ordered_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
for list_element in &pre_suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
for list_element in &ordered_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
for list_element in &pre_suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &ordered_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
for list_element in &pre_suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &ordered_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut is_dupe = false; // initialize
for list_element in &pre_suggested_coin_list {
if (filtered_coin.symbol == list_element.symbol)
&& (filtered_coin.closetime == list_element.close_time)
{
is_dupe = true;
break;
}
}
if is_dupe == false {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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_coin in filtered_coins {
let mut insert_values = vec![
filtered_coin.symbol.clone(), // symbol
filtered_coin.closetime.to_string(), // close_time
filtered_coin.current_price.to_string(), // suggested_price
filtered_coin.current_price.to_string(), // current_price
filtered_coin.stoploss.to_string(), // stoploss
filtered_coin.target_price.to_string(), // target_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(())
}