Update filtering

This commit is contained in:
Sik Yoon 2024-06-23 16:50:23 +09:00
parent 6dfdc719c3
commit 8b8cbb0dce
2 changed files with 358 additions and 54 deletions

View File

@ -1,3 +1,5 @@
use rust_decimal::prelude::Signed;
use crate::value_estimation_team::{datapoints::price_data::CandleType, indicators::wiliams_percent_r};
use super::{
@ -9,7 +11,7 @@ use super::{
FilteredDataValue, HashMap, HashSet, HeatMapLevel, HeatmapVolumeData, MacdData, Mutex,
RealtimePriceData, RoundingStrategy, RsiData, StochRsiData, SuperTrendArea, SuperTrendSignal,
SupertrendData, TemaData, ToPrimitive, TradeFee, WiliamsPercentR, future_duplicate_filter, insert_future_coins, get_current_price_decimal,
sma, sma_open, LrData, linear_regression
sma, sma_open, LrData, linear_regression, bollingerband
};
use crate::future::{Position, FuturesExchangeInfo};
@ -35,19 +37,21 @@ pub async fn list_up_for_buy(
// current lr > prev lr, current r_squared <= 0.01
let mut keys_to_remove: HashSet<String> = HashSet::new();
let lr_map = linear_regression(10, 0, &alldata.rt_price_30m_vec, &filtered_data).await?;
let sma_map = sma(10, &alldata.rt_price_30m_vec, &filtered_data).await?;
let lr_map = linear_regression(30, 0, &alldata.rt_price_30m_vec, &filtered_data).await?;
let lr50_map = linear_regression(50, 0, &alldata.rt_price_30m_vec, &filtered_data).await?;
let sma_map = sma(30, &alldata.rt_price_30m_vec, &filtered_data).await?;
for (symbol, values) in &mut filtered_data {
let mut do_buy = false;
if let (Some(lr_vec), Some(sma_vec), Some(current_info)) = (lr_map.get(symbol), sma_map.get(symbol), get_current_price_decimal(&symbol, &alldata.rt_price_30m_vec).await) {
if let (Some(lr_vec), Some(lr50_vec), Some(sma_vec), Some(current_info)) = (lr_map.get(symbol), lr50_map.get(symbol), sma_map.get(symbol), get_current_price_decimal(&symbol, &alldata.rt_price_30m_vec).await) {
if lr_vec.len() > 10
&& lr50_vec.len() > 10
&& sma_vec.len() > 10
&& lr_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& sma_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& lr_vec[lr_vec.len()-1].lr_value > lr_vec[lr_vec.len()-2].lr_value
&& lr_vec[lr_vec.len()-2].lr_value > lr_vec[lr_vec.len()-3].lr_value
&& lr_vec.last().unwrap().r_squared <= 0.15
&& lr_vec[lr_vec.len()-1].lr_value >= sma_vec[sma_vec.len()-1].sma_value
&& lr_vec.last().unwrap().r_squared <= 0.02
&& lr_vec[lr_vec.len()-1].lr_value > sma_vec[sma_vec.len()-1].sma_value
&& lr_vec[lr_vec.len()-2].lr_value <= sma_vec[sma_vec.len()-2].sma_value
{
values.closetime = current_info.1;
@ -116,7 +120,7 @@ pub async fn list_up_for_buy(
// supertrend(ATR period 30, multiplier: 2.0, 30m close price)
let mut keys_to_remove: HashSet<String> = HashSet::new();
let supertrend_1m_map =
supertrend(100, 2.5, true, &alldata.rt_price_1m_vec, &filtered_data).await?;
supertrend(10, 1.5, true, &alldata.rt_price_30m_vec, &filtered_data).await?;
for (symbol, values) in &mut filtered_data {
let mut do_buy = false;
if let Some(supertrend_vec) = supertrend_1m_map.get(symbol)
@ -135,6 +139,46 @@ pub async fn list_up_for_buy(
}
remove_keys(&mut filtered_data, keys_to_remove).await;
// BollingerBand (len:30, multiplier 3) 5 previous high price < BB upper
let mut keys_to_remove: HashSet<String> = HashSet::new();
let bollingerband_map =
bollingerband(30, 3.0, &alldata.rt_price_30m_vec, &filtered_data).await?;
for (symbol, filtered_data) in &mut filtered_data {
let mut do_buy = false;
if let (Some(bb_vec), Some(rt_30m_vec)) = (
bollingerband_map.get(symbol),
alldata.rt_price_30m_vec.get(symbol),
) {
if rt_30m_vec.len() >= 10
&& bb_vec.len() >= 10
&& rt_30m_vec.last().unwrap().close_time > server_epoch
{
if let Ok(bb_search_result) = bb_vec.binary_search_by_key(
&rt_30m_vec.last().unwrap().close_time,
|BollingerBandData {
sma,
upperband,
lowerband,
close_time,
}| *close_time,
) {
if bb_vec[bb_search_result].upperband > rt_30m_vec[rt_30m_vec.len() - 1].high_price
&& bb_vec[bb_search_result-1].upperband > rt_30m_vec[rt_30m_vec.len() - 2].high_price
&& bb_vec[bb_search_result-2].upperband > rt_30m_vec[rt_30m_vec.len() - 3].high_price
&& bb_vec[bb_search_result-3].upperband > rt_30m_vec[rt_30m_vec.len() - 4].high_price
&& bb_vec[bb_search_result-4].upperband > rt_30m_vec[rt_30m_vec.len() - 5].high_price
{
do_buy = true;
}
}
}
}
if do_buy == false {
keys_to_remove.insert(symbol.clone());
}
}
remove_keys(&mut filtered_data, keys_to_remove).await;
// set target_price and stop_loss
// let mut keys_to_remove: HashSet<String> = HashSet::new();
// for (symbol, values) in &mut filtered_data {
@ -176,7 +220,7 @@ pub async fn list_up_for_buy(
if let Some(wpr100_vec) = wpr100_map.get(symbol) {
if wpr100_vec.len() > 15
&& wpr100_vec.last().unwrap().close_time > server_epoch
&& wpr100_vec.last().unwrap().r_value < -70.0 {
&& wpr100_vec.last().unwrap().r_value < -80.0 {
do_buy = true;
}
}
@ -265,7 +309,12 @@ pub async fn list_up_for_buy(
|| (heatmap_volume_vec[heatmap_volume_vec.len()-2].heatmap_level == HeatMapLevel::ExtraHigh && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-2].close_time).is_some_and(|x| x.candle_type == CandleType::UP))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-3].heatmap_level == HeatMapLevel::ExtraHigh && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-3].close_time).is_some_and(|x| x.candle_type == CandleType::UP))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-4].heatmap_level == HeatMapLevel::ExtraHigh && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-4].close_time).is_some_and(|x| x.candle_type == CandleType::UP))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-5].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-5].close_time).is_some_and(|x| x.candle_type == CandleType::UP))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-5].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-5].close_time).is_some_and(|x| x.candle_type == CandleType::UP)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-6].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-6].close_time).is_some_and(|x| x.candle_type == CandleType::UP)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-7].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-7].close_time).is_some_and(|x| x.candle_type == CandleType::UP)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-8].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-8].close_time).is_some_and(|x| x.candle_type == CandleType::UP)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-9].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-9].close_time).is_some_and(|x| x.candle_type == CandleType::UP)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-10].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-10].close_time).is_some_and(|x| x.candle_type == CandleType::UP))
{
do_buy = false;
}
@ -384,15 +433,74 @@ pub async fn list_up_for_sell(all_data: &AllData, futures_exchange_info_map: &Ha
for element in &filled_positions {
filtered_symbols.insert(element.symbol.clone(), FilteredDataValue::new());
}
let lr_map = linear_regression(10, 0, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
// let supertrend_30m_map =
// supertrend(100, 1.5, true, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let lr_map = linear_regression(30, 0, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let sma_map = sma(30, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let heatmap_30m_map = heatmap_volume(
30,
30,
4.0,
1.5,
0.5,
-0.5,
&filtered_symbols,
&all_data.rt_price_30m_vec,
)
.await?;
let heatmap_1m_map = heatmap_volume(
100,
100,
5.0,
1.5,
0.5,
-0.5,
&filtered_symbols,
&all_data.rt_price_1m_vec,
)
.await?;
let bollingerband_30m_map = bollingerband(30, 3.0, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let bollingerband_1m_map = bollingerband(30, 4.5, &all_data.rt_price_1m_vec, &filtered_symbols).await?;
let supertrend_30m_map =
supertrend(10, 1.5, true, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
// let adx_vec = adx(15, 15, &all_data.rt_price_1m_vec, &filtered_symbols).await?;
for element in filled_positions {
let mut is_sell = false;
if let Some(lr_vec) = lr_map.get(&element.symbol) {
if !element.current_price.is_zero() && lr_vec.len() > 10 && lr_vec.last().is_some_and(|x| x.close_time > server_epoch) {
if let (Some(lr_vec),
Some(sma_vec),
Some(heatmap_30m_vec),
Some(heatmap_1m_vec),
Some(bb_30m_vec),
Some(bb_1m_vec),
Some(rt_price_30m_vec),
Some(rt_price_1m_vec),
Some(supertrend_vec))
= (lr_map.get(&element.symbol),
sma_map.get(&element.symbol),
heatmap_30m_map.get(&element.symbol),
heatmap_1m_map.get(&element.symbol),
bollingerband_30m_map.get(&element.symbol),
bollingerband_1m_map.get(&element.symbol),
all_data.rt_price_30m_vec.get(&element.symbol),
all_data.rt_price_1m_vec.get(&element.symbol),
supertrend_30m_map.get(&element.symbol)) {
if !element.current_price.is_zero()
&& lr_vec.len() > 10
&& heatmap_30m_vec.len() > 10
&& heatmap_1m_vec.len() > 10
&& rt_price_30m_vec.len() > 10
&& rt_price_1m_vec.len() > 10
&& bb_30m_vec.len() > 10
&& bb_1m_vec.len() > 10
&& sma_vec.len() > 10
&& supertrend_vec.len() > 10
&& lr_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& sma_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& heatmap_30m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& heatmap_1m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& bb_30m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& bb_1m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& rt_price_30m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& rt_price_1m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& supertrend_vec.last().is_some_and(|x| x.close_time > server_epoch) {
// if element.pure_profit_percent >= element.target_percent {
// is_sell = true;
@ -400,24 +508,73 @@ pub async fn list_up_for_sell(all_data: &AllData, futures_exchange_info_map: &Ha
// is_sell = true;
// } else
if element.pure_profit_percent.is_sign_positive() && lr_vec[lr_vec.len()-2].r_squared >= 0.60 {
is_sell = true;
} else if server_epoch - element.close_time > 900_000
&& lr_vec[lr_vec.len()-1].lr_value < lr_vec[lr_vec.len()-2].lr_value {
if element.pure_profit_percent.is_sign_positive() && lr_vec.last().is_some_and(|x| x.r_squared >= 0.6) {
is_sell = true;
} else if server_epoch - element.close_time > 900_000
&& lr_vec[lr_vec.len()-1].r_squared < lr_vec[lr_vec.len()-2].r_squared
&& lr_vec[lr_vec.len()-2].r_squared > lr_vec[lr_vec.len()-3].r_squared
&& lr_vec[lr_vec.len()-3].r_squared > lr_vec[lr_vec.len()-4].r_squared {
is_sell = true;
} else if element.pure_profit_percent <= -0.8 {
} else if server_epoch - element.close_time > 1_800_000
&& lr_vec.last().unwrap().close_time == sma_vec.last().unwrap().close_time
&& lr_vec[lr_vec.len()-1].lr_value < sma_vec[sma_vec.len()-1].sma_value
&& lr_vec[lr_vec.len()-2].lr_value > sma_vec[sma_vec.len()-2].sma_value {
is_sell = true;
} else if element.pure_profit_percent >= 2.0 {
} else if element.pure_profit_percent.is_sign_positive() && heatmap_30m_vec.last().is_some_and(|x| x.heatmap_level == HeatMapLevel::ExtraHigh) {
is_sell = true;
} else if element.pure_profit_percent.is_sign_positive()
&& (heatmap_1m_vec.last().is_some_and(|x| x.heatmap_level == HeatMapLevel::ExtraHigh)
|| heatmap_1m_vec[heatmap_1m_vec.len()-2].heatmap_level == HeatMapLevel::ExtraHigh) {
is_sell = true;
} else if element.pure_profit_percent.is_sign_negative() && element.pure_profit_percent <= -5.0 {
is_sell = true;
} else if supertrend_vec.last().is_some_and(|x| x.signal.as_ref().is_some_and(|a| *a == SuperTrendSignal::SELL)) {
is_sell = true;
}
if is_sell == false {
if let Ok(bb_search_result) = bb_30m_vec.binary_search_by_key(
&rt_price_30m_vec.last().unwrap().close_time,
|BollingerBandData {
sma,
upperband,
lowerband,
close_time,
}| *close_time,
) {
if element.pure_profit_percent.is_sign_positive()
&& bb_30m_vec[bb_search_result].upperband <= rt_price_30m_vec[rt_price_30m_vec.len() - 1].high_price
&& bb_30m_vec[bb_search_result-1].upperband <= rt_price_30m_vec[rt_price_30m_vec.len() - 2].high_price
{
is_sell = true;
}
}
if let Ok(bb_search_result) = bb_1m_vec.binary_search_by_key(
&rt_price_1m_vec.last().unwrap().close_time,
|BollingerBandData {
sma,
upperband,
lowerband,
close_time,
}| *close_time,
) {
if element.pure_profit_percent.is_sign_positive()
&& bb_1m_vec[bb_search_result].upperband <= rt_price_1m_vec[rt_price_1m_vec.len() - 1].high_price
&& bb_1m_vec[bb_search_result-1].upperband <= rt_price_1m_vec[rt_price_1m_vec.len() - 2].high_price
{
is_sell = true;
}
}
let minimum_candles = 5;
let maximum_candles = 20;
let maximum_candles = 30;
if server_epoch - element.close_time > 1_800_000 * maximum_candles {
is_sell = true;
}
}
// for count_candles in minimum_candles..=maximum_candles {
// if count_candles < maximum_candles
// && server_epoch - element.transact_time
@ -442,9 +599,7 @@ pub async fn list_up_for_sell(all_data: &AllData, futures_exchange_info_map: &Ha
// }
// }
if server_epoch - element.close_time > 1_800_000 * maximum_candles {
is_sell = true;
}
//} else if server_epoch - element.close_time > 300_000
// && adx_vec.get(&element.symbol).is_some_and(|a| a.len() > 10 && a.last().is_some_and(|b| b.close_time > server_epoch && b.adx < 15.0)) {

View File

@ -9,7 +9,7 @@ use super::{
FilteredDataValue, HashMap, HashSet, HeatMapLevel, HeatmapVolumeData, MacdData, Mutex,
RealtimePriceData, RoundingStrategy, RsiData, StochRsiData, SuperTrendArea, SuperTrendSignal,
SupertrendData, TemaData, ToPrimitive, TradeFee, WiliamsPercentR, future_duplicate_filter, insert_future_coins, get_current_price_decimal,
sma, sma_open, LrData, linear_regression
sma, sma_open, LrData, linear_regression, bollingerband
};
use crate::future::{Position, FuturesExchangeInfo};
@ -35,21 +35,22 @@ pub async fn list_up_for_buy(
// current lr < prev lr, current r_squared <= 0.01
let mut keys_to_remove: HashSet<String> = HashSet::new();
let lr_map = linear_regression(10, 0, &alldata.rt_price_30m_vec, &filtered_data).await?;
let sma10_map = sma(10, &alldata.rt_price_30m_vec, &filtered_data).await?;
let lr_map = linear_regression(30, 0, &alldata.rt_price_30m_vec, &filtered_data).await?;
let lr50_map = linear_regression(50, 0, &alldata.rt_price_30m_vec, &filtered_data).await?;
let sma10_map = sma(30, &alldata.rt_price_30m_vec, &filtered_data).await?;
for (symbol, values) in &mut filtered_data {
let mut do_buy = false;
if let (Some(lr_vec), Some(sma_vec), Some(current_info)) = (lr_map.get(symbol), sma10_map.get(symbol), get_current_price_decimal(&symbol, &alldata.rt_price_30m_vec).await) {
if let (Some(lr_vec), Some(lr50_vec), Some(sma_vec), Some(current_info)) = (lr_map.get(symbol), lr50_map.get(symbol), sma10_map.get(symbol), get_current_price_decimal(&symbol, &alldata.rt_price_30m_vec).await) {
if lr_vec.len() > 10
&& lr50_vec.len() > 10
&& sma_vec.len() > 10
&& lr_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& sma_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& lr_vec[lr_vec.len()-1].lr_value < lr_vec[lr_vec.len()-2].lr_value
&& lr_vec[lr_vec.len()-2].lr_value < lr_vec[lr_vec.len()-3].lr_value
&& lr_vec.last().unwrap().r_squared <= 0.15
&& lr_vec[lr_vec.len()-1].lr_value <= sma_vec[sma_vec.len()-1].sma_value
&& lr_vec.last().unwrap().r_squared <= 0.02
&& lr_vec[lr_vec.len()-1].lr_value < sma_vec[sma_vec.len()-1].sma_value
&& lr_vec[lr_vec.len()-2].lr_value >= sma_vec[sma_vec.len()-2].sma_value
{
values.closetime = current_info.1;
do_buy = true;
@ -115,7 +116,7 @@ pub async fn list_up_for_buy(
// supertrend(ATR period 30, multiplier: 2.0, 30m close price)
let mut keys_to_remove: HashSet<String> = HashSet::new();
let supertrend_1m_map =
supertrend(100, 2.5, true, &alldata.rt_price_1m_vec, &filtered_data).await?;
supertrend(10, 1.5, true, &alldata.rt_price_30m_vec, &filtered_data).await?;
for (symbol, values) in &mut filtered_data {
let mut do_buy = false;
if let Some(supertrend_vec) = supertrend_1m_map.get(symbol)
@ -134,6 +135,46 @@ pub async fn list_up_for_buy(
}
remove_keys(&mut filtered_data, keys_to_remove).await;
// BollingerBand (len:30, multiplier 3) 5 previous high price < BB upper
let mut keys_to_remove: HashSet<String> = HashSet::new();
let bollingerband_map =
bollingerband(30, 3.0, &alldata.rt_price_30m_vec, &filtered_data).await?;
for (symbol, filtered_data) in &mut filtered_data {
let mut do_buy = false;
if let (Some(bb_vec), Some(rt_30m_vec)) = (
bollingerband_map.get(symbol),
alldata.rt_price_30m_vec.get(symbol),
) {
if rt_30m_vec.len() >= 10
&& bb_vec.len() >= 10
&& rt_30m_vec.last().unwrap().close_time > server_epoch
{
if let Ok(bb_search_result) = bb_vec.binary_search_by_key(
&rt_30m_vec.last().unwrap().close_time,
|BollingerBandData {
sma,
upperband,
lowerband,
close_time,
}| *close_time,
) {
if bb_vec[bb_search_result].lowerband < rt_30m_vec[rt_30m_vec.len() - 1].low_price
&& bb_vec[bb_search_result-1].lowerband < rt_30m_vec[rt_30m_vec.len() - 2].low_price
&& bb_vec[bb_search_result-2].lowerband < rt_30m_vec[rt_30m_vec.len() - 3].low_price
&& bb_vec[bb_search_result-3].lowerband < rt_30m_vec[rt_30m_vec.len() - 4].low_price
&& bb_vec[bb_search_result-4].lowerband < rt_30m_vec[rt_30m_vec.len() - 5].low_price
{
do_buy = true;
}
}
}
}
if do_buy == false {
keys_to_remove.insert(symbol.clone());
}
}
remove_keys(&mut filtered_data, keys_to_remove).await;
// set target_price and stop_loss
// let mut keys_to_remove: HashSet<String> = HashSet::new();
// for (symbol, values) in &mut filtered_data {
@ -175,7 +216,7 @@ pub async fn list_up_for_buy(
if let Some(wpr100_vec) = wpr100_map.get(symbol) {
if wpr100_vec.len() > 15
&& wpr100_vec.last().unwrap().close_time > server_epoch
&& wpr100_vec.last().unwrap().r_value > -30.0 {
&& wpr100_vec.last().unwrap().r_value > -20.0 {
do_buy = true;
}
}
@ -264,7 +305,12 @@ pub async fn list_up_for_buy(
|| (heatmap_volume_vec[heatmap_volume_vec.len()-2].heatmap_level == HeatMapLevel::ExtraHigh && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-2].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-3].heatmap_level == HeatMapLevel::ExtraHigh && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-3].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-4].heatmap_level == HeatMapLevel::ExtraHigh && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-4].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-5].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-5].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN))
|| (heatmap_volume_vec[heatmap_volume_vec.len()-5].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-5].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-6].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-6].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-7].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-7].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-8].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-8].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-9].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-9].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN)
|| (heatmap_volume_vec[heatmap_volume_vec.len()-10].heatmap_level == HeatMapLevel::ExtraHigh) && rt_price_vec.iter().find(|x| x.close_time == heatmap_volume_vec[heatmap_volume_vec.len()-10].close_time).is_some_and(|x| x.candle_type == CandleType::DOWN))
{
do_buy = false;
}
@ -382,9 +428,33 @@ pub async fn list_up_for_sell(all_data: &AllData, futures_exchange_info_map: &Ha
for element in &filled_positions {
filtered_symbols.insert(element.symbol.clone(), FilteredDataValue::new());
}
let lr_map = linear_regression(10, 0, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
// let supertrend_30m_map =
// supertrend(100, 1.5, true, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let lr_map = linear_regression(30, 0, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let sma_map: HashMap<String, Vec<crate::value_estimation_team::indicators::sma::SmaData>> = sma(30, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let heatmap_30m_map = heatmap_volume(
30,
30,
4.0,
1.5,
0.5,
-0.5,
&filtered_symbols,
&all_data.rt_price_30m_vec,
)
.await?;
let heatmap_1m_map = heatmap_volume(
100,
100,
5.0,
1.5,
0.5,
-0.5,
&filtered_symbols,
&all_data.rt_price_1m_vec,
)
.await?;
let bollingerband_30m_map = bollingerband(30, 3.0, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
let bollingerband_1m_map = bollingerband(30, 4.5, &all_data.rt_price_1m_vec, &filtered_symbols).await?;
let supertrend_30m_map = supertrend(10, 1.5, true, &all_data.rt_price_30m_vec, &filtered_symbols).await?;
// let adx_vec = adx(15, 15, &all_data.rt_price_1m_vec, &filtered_symbols).await?;
for element in filled_positions {
let mut is_sell = false;
@ -396,33 +466,115 @@ pub async fn list_up_for_sell(all_data: &AllData, futures_exchange_info_map: &Ha
// RoundingStrategy::ToZero,
// );
// TODO: BNB 코인이 없으면
if let Some(lr_vec) = lr_map.get(&element.symbol) {
if !element.current_price.is_zero() && lr_vec.len() > 10 && lr_vec.last().is_some_and(|x| x.close_time > server_epoch) {
if let (Some(lr_vec),
Some(sma_vec),
Some(heatmap_30m_vec),
Some(heatmap_1m_vec),
Some(bb_30m_vec),
Some(bb_1m_vec),
Some(rt_price_30m_vec),
Some(rt_price_1m_vec),
Some(supertrend_vec))
= (lr_map.get(&element.symbol),
sma_map.get(&element.symbol),
heatmap_30m_map.get(&element.symbol),
heatmap_1m_map.get(&element.symbol),
bollingerband_30m_map.get(&element.symbol),
bollingerband_1m_map.get(&element.symbol),
all_data.rt_price_30m_vec.get(&element.symbol),
all_data.rt_price_1m_vec.get(&element.symbol),
supertrend_30m_map.get(&element.symbol)) {
if !element.current_price.is_zero()
&& lr_vec.len() > 10
&& heatmap_30m_vec.len() > 10
&& heatmap_1m_vec.len() > 10
&& rt_price_30m_vec.len() > 10
&& rt_price_1m_vec.len() > 10
&& bb_30m_vec.len() > 10
&& bb_1m_vec.len() > 10
&& sma_vec.len() > 10
&& supertrend_vec.len() > 10
&& lr_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& sma_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& heatmap_30m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& heatmap_1m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& bb_30m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& bb_1m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& rt_price_30m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& rt_price_1m_vec.last().is_some_and(|x| x.close_time > server_epoch)
&& supertrend_vec.last().is_some_and(|x| x.close_time > server_epoch) {
// if element.pure_profit_percent >= element.target_percent {
// is_sell = true;
// } else if element.pure_profit_percent <= element.stoploss_percent {
// is_sell = true;
// } else
if element.pure_profit_percent.is_sign_positive() && lr_vec[lr_vec.len()-2].r_squared >= 0.60 {
is_sell = true;
} else if server_epoch - element.close_time > 900_000
&& lr_vec[lr_vec.len()-1].lr_value > lr_vec[lr_vec.len()-2].lr_value {
if element.pure_profit_percent.is_sign_positive() && lr_vec.last().is_some_and(|x| x.r_squared >= 0.6) {
is_sell = true;
} else if server_epoch - element.close_time > 900_000
&& lr_vec[lr_vec.len()-1].r_squared < lr_vec[lr_vec.len()-2].r_squared
&& lr_vec[lr_vec.len()-2].r_squared > lr_vec[lr_vec.len()-3].r_squared
&& lr_vec[lr_vec.len()-3].r_squared > lr_vec[lr_vec.len()-4].r_squared {
is_sell = true;
} else if element.pure_profit_percent <= -0.8 {
} else if server_epoch - element.close_time > 1_800_000
&& lr_vec.last().unwrap().close_time == sma_vec.last().unwrap().close_time
&& lr_vec[lr_vec.len()-1].lr_value > sma_vec[sma_vec.len()-1].sma_value
&& lr_vec[lr_vec.len()-2].lr_value < sma_vec[sma_vec.len()-2].sma_value {
is_sell = true;
} else if element.pure_profit_percent >= 2.0 {
} else if element.pure_profit_percent.is_sign_positive() && heatmap_30m_vec.last().is_some_and(|x| x.heatmap_level == HeatMapLevel::ExtraHigh) {
is_sell = true;
} else if element.pure_profit_percent.is_sign_positive()
&& (heatmap_1m_vec.last().is_some_and(|x| x.heatmap_level == HeatMapLevel::ExtraHigh)
|| heatmap_1m_vec[heatmap_1m_vec.len()-2].heatmap_level == HeatMapLevel::ExtraHigh) {
is_sell = true;
} else if element.pure_profit_percent.is_sign_negative() && element.pure_profit_percent <= -5.0 {
is_sell = true;
} else if supertrend_vec.last().is_some_and(|x| x.signal.as_ref().is_some_and(|a| *a == SuperTrendSignal::BUY)) {
is_sell = true;
}
if is_sell == false {
if let Ok(bb_search_result) = bb_30m_vec.binary_search_by_key(
&rt_price_30m_vec.last().unwrap().close_time,
|BollingerBandData {
sma,
upperband,
lowerband,
close_time,
}| *close_time,
) {
if element.pure_profit_percent.is_sign_positive()
&& bb_30m_vec[bb_search_result].lowerband >= rt_price_30m_vec[rt_price_30m_vec.len() - 1].low_price
&& bb_30m_vec[bb_search_result-1].lowerband >= rt_price_30m_vec[rt_price_30m_vec.len() - 2].low_price
{
is_sell = true;
}
}
if let Ok(bb_search_result) = bb_1m_vec.binary_search_by_key(
&rt_price_1m_vec.last().unwrap().close_time,
|BollingerBandData {
sma,
upperband,
lowerband,
close_time,
}| *close_time,
) {
if element.pure_profit_percent.is_sign_positive()
&& bb_1m_vec[bb_search_result].lowerband >= rt_price_1m_vec[rt_price_1m_vec.len() - 1].low_price
&& bb_1m_vec[bb_search_result-1].lowerband >= rt_price_1m_vec[rt_price_1m_vec.len() - 2].low_price
{
is_sell = true;
}
}
let minimum_candles = 5;
let maximum_candles = 20;
let maximum_candles = 30;
if server_epoch - element.close_time > 1_800_000 * maximum_candles {
is_sell = true;
}
}
// for count_candles in minimum_candles..=maximum_candles {
// if count_candles < maximum_candles
// && server_epoch - element.transact_time
@ -447,9 +599,6 @@ pub async fn list_up_for_sell(all_data: &AllData, futures_exchange_info_map: &Ha
// }
// }
if server_epoch - element.close_time > 1_800_000 * maximum_candles {
is_sell = true;
}
//} else if server_epoch - element.close_time > 300_000
// && adx_vec.get(&element.symbol).is_some_and(|a| a.len() > 10 && a.last().is_some_and(|b| b.close_time > server_epoch && b.adx < 15.0)) {