// pub async fn strategist_002(
//     alldata: &AllData,
// ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
//     // print rt_price for debugging
//     // let a = alldata.rt_price_30m_vec.iter().position(|a| a.0 == "BTCUSDT");
//     // println!("BTCUSDT: {:?}", alldata.rt_price_30m_vec[a.unwrap()].1.last().unwrap());

//     // 1st filtering: making basic form
//     let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new();
//     let mut filtered_2nd_symbols_arc: Arc<Mutex<Vec<(String, i64)>>> =
//         Arc::new(Mutex::new(filtered_2nd_symbols)); // (symbol, closetime)
//     let mut task_vec = Vec::new();
//     let valid_symbol_vec_c = alldata.valid_symbol_vec.clone();
//     for symbol in valid_symbol_vec_c {
//         let mut opclo_30m_vec: Vec<RealtimePriceData> = Vec::new();

//         let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone();
//         let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc);
//         task_vec.push(tokio::spawn(async move {
//             let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol);

//             if opclo_30m_option.is_some() {
//                 opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone();

//                 if opclo_30m_vec.len() >= 3  {
//                     let mut filtered_2nd_symbols_lock =
//                         filtered_2nd_symbols_arc_c.lock().await;
//                     filtered_2nd_symbols_lock
//                         .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time));
//                 }
//             }
//         }));
//     }
//     try_join_all(task_vec).await?;

//     // 2nd filtering: lookup tables if the tradepair is already there
//     let inspect_table_name_1 = String::from("buy_ordered_coin_list");
//     let inspect_table_name_2 = String::from("sell_ordered_coin_list");
//     let inspect_table_name_3 = String::from("pre_suggested_coin_list");
//     let inspect_table_name_4 = String::from("suggested_coin_list");

//     let mut filtered_3rd_symbols: Vec<(String, i64)> = Vec::new();
//     let mut filtered_3rd_symbols_arc: Arc<Mutex<Vec<(String, i64)>>> =
//         Arc::new(Mutex::new(filtered_3rd_symbols)); // (symbol, closetime)
//     let mut task_vec = Vec::new();

//     let filtered_2nd_iter = filtered_2nd_symbols_arc.lock().await.clone().into_iter();
//     for element in filtered_2nd_iter {
//         let mut exists_condition_build = String::from("symbol=\'");
//         exists_condition_build.push_str(element.0.as_str());
//         exists_condition_build.push_str("\' AND registerer=");
//         exists_condition_build.push_str(2.to_string().as_str());
//         // exists_condition_build.push_str("\' AND close_time=");
//         // exists_condition_build.push_str(element.1.to_string().as_str());

//         let exists_condition = Some(exists_condition_build);
//         let exists_condition_c = exists_condition.clone();
//         let inspect_table_name_1_c = inspect_table_name_1.clone();
//         let inspect_table_name_2_c = inspect_table_name_2.clone();
//         let inspect_table_name_3_c = inspect_table_name_3.clone();
//         let inspect_table_name_4_c = inspect_table_name_4.clone();
//         let element_c = element.clone();
//         let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc);
//         task_vec.push(tokio::spawn(async move {
//             let inspect_result_1 =
//                 exists_record(&inspect_table_name_1_c, &exists_condition_c).await;
//             let inspect_result_2 =
//                 exists_record(&inspect_table_name_2_c, &exists_condition_c).await;
//             let inspect_result_3 =
//                 exists_record(&inspect_table_name_3_c, &exists_condition_c).await;
//             let inspect_result_4 =
//                 exists_record(&inspect_table_name_4_c, &exists_condition_c).await;

//             if inspect_result_1 == false
//                 && inspect_result_2 == false
//                 && inspect_result_3 == false
//                 && inspect_result_4 == false
//             {
//                 let mut filtered_3rd_symbols_lock = filtered_3rd_symbols_arc_c.lock().await;
//                 filtered_3rd_symbols_lock.push(element_c);
//             }
//         }));
//     }
//     try_join_all(task_vec).await?;

//     // 3rd filtering: EMA30 > EMA 150
//     let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone();
//     let ema30_30m_data: Vec<(String, Vec<EmaData>)> = ema(
//         30,
//         &alldata.rt_price_30m_vec,
//         &filtered_3rd_symbols_c,
//     )
//     .await?;
//     let ema150_30m_data: Vec<(String, Vec<EmaData>)> = ema(
//         150,
//         &alldata.rt_price_30m_vec,
//         &filtered_3rd_symbols_c,
//     )
//     .await?;

//     let mut task_vec = Vec::new();
//     let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new();
//     let mut filtered_4th_symbols_arc: Arc<Mutex<Vec<(String, i64)>>> =
//         Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime)
//     for element in filtered_3rd_symbols_c {
//         let mut ema30_30m_vec: Vec<EmaData> = Vec::new();
//         let mut ema150_30m_vec: Vec<EmaData> = Vec::new();
//         let ema30_30m_option = ema30_30m_data.iter().position(|x| *x.0 == element.0);
//         let ema30_30m_option_c = ema30_30m_option.clone();
//         let ema150_30m_option = ema150_30m_data.iter().position(|x| *x.0 == element.0);
//         let ema150_30m_option_c = ema150_30m_option.clone();
//         let element_c = element.clone();
//         let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc);

//         if ema30_30m_option_c.is_some() && ema150_30m_option_c.is_some() {
//             ema30_30m_vec = ema30_30m_data[ema30_30m_option.unwrap()].1.clone();
//             ema150_30m_vec = ema150_30m_data[ema150_30m_option.unwrap()].1.clone();

//             if ema30_30m_vec.len() >= 10 && ema150_30m_vec.len() >= 10 {
//                 let ema30_30m_vec_c = ema30_30m_vec.clone();
//                 let ema150_30m_vec_c = ema150_30m_vec.clone();

//                 task_vec.push(tokio::spawn(async move {
//                     let ema30_search_result = ema30_30m_vec_c.binary_search_by_key(
//                         &element_c.1,
//                         |&EmaData {
//                             ema_value,
//                             close_time,
//                          }| close_time,
//                     );
//                     let ema150_search_result = ema150_30m_vec_c.binary_search_by_key(
//                         &element_c.1,
//                         |&EmaData {
//                             ema_value,
//                             close_time,
//                          }| close_time,
//                     );

//                     if ema30_search_result.is_ok() && ema150_search_result.is_ok() {
//                         if ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-3].ema_value &&
//                         ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-2].ema_value &&
//                         ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()-1].ema_value &&
//                         ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema150_30m_vec_c[ema150_search_result.unwrap()].ema_value &&
//                         ema30_30m_vec_c[ema30_search_result.unwrap()].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value &&
//                         ema30_30m_vec_c[ema30_search_result.unwrap()-1].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value &&
//                         ema30_30m_vec_c[ema30_search_result.unwrap()-2].ema_value > ema30_30m_vec_c[ema30_search_result.unwrap()-3].ema_value
//                         {
//                             let mut filtered_4th_symbols_lock =
//                                 filtered_4th_symbols_arc_c.lock().await;
//                             filtered_4th_symbols_lock.push(element_c);
//                         }
//                     }
//                 }));
//             }
//         }
//     }
//     try_join_all(task_vec).await?;

//     // 6th filtering: StochRSI (RSI length: 10, Stoch length: 10, smooth k: 3, smooth d: 3) smooth dn == 0, kn == 0, kn-1 < 5
//     let filtered_4th_symbol_c = filtered_4th_symbols_arc.lock().await.clone();
//     let mut rsi10_30m_data: Vec<(String, Vec<RsiData>)> = rsi(
//         10,
//         &alldata.rt_price_30m_vec,
//         &filtered_4th_symbol_c,
//     )
//     .await?;
//     let stoch_rsi_data = stoch_rsi(&rsi10_30m_data, 10, 3, 3).await?;
//     let mut stoch_rsi10_30m_vec: Vec<StochRsiData> = Vec::new();
//     let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime)
//     for element in filtered_4th_symbol_c {
//         let stoch_rsi10_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0);

//         if stoch_rsi10_30m_option.is_some() {
//             stoch_rsi10_30m_vec = stoch_rsi_data[stoch_rsi10_30m_option.unwrap()].1.clone();

//             if stoch_rsi10_30m_vec.len() >= 3 {
//                 let stoch_rsi_search_result = stoch_rsi10_30m_vec.binary_search_by_key(
//                     &element.1,
//                     |&StochRsiData {
//                          k,
//                          d,
//                          close_time,
//                      }| close_time,
//                 );
//                 if stoch_rsi_search_result.is_ok() {
//                     if stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].k <= 5.0 &&
//                         stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()].d <= 5.0 &&
//                         stoch_rsi10_30m_vec[stoch_rsi_search_result.unwrap()-1].k <= 5.0 {
//                         filtered_5th_symbols.push(element);
//                     }
//                 }
//             }
//         }
//     }

//     // 7th filtering: heatmap volume(MA length 10, std length 10, 30m close price), the current candle should be over than high at least.
//     let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime)
//     for element in filtered_5th_symbols {
//         let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone();
//         let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0);
//         if opclo_30m_option.is_some() {
//             let opclo_30m_vec = rt_price_30m_vec_c[opclo_30m_option.unwrap()].1.clone();

//             if opclo_30m_vec.len() >= 3 {
//                 let heatmap_volume_option =
//                     heatmap_volume(&element.0, &rt_price_30m_vec_c, 10, 10, 4.0, 2.5, 1.0, -0.5)
//                         .await;
//                 if heatmap_volume_option.is_some() {
//                     let heatmap_volume_vec = heatmap_volume_option.unwrap();
//                     let heatmap_search_result = heatmap_volume_vec.binary_search_by_key(
//                         &element.1,
//                         |HeatmapVolumeData {
//                              heatmap_value,
//                              heatmap_level,
//                              close_time,
//                          }| *close_time,
//                     );
//                     if heatmap_search_result.is_ok() {
//                         if
//                         // heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level
//                         //     == HeatMapLevel::Medium
//                         //     ||
//                             heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level
//                                 == HeatMapLevel::High
//                             || heatmap_volume_vec[heatmap_search_result.unwrap()].heatmap_level
//                                 == HeatMapLevel::ExtraHigh
//                         {
//                             filtered_6th_symbols.push(element);
//                         }
//                     }
//                 }
//             }
//         }
//     }

//     // final job: adding price information to filtered results
//     let mut filtered_symbols: Vec<(String, i64, f64)> = Vec::new(); // (symbol, closetime, current price)
//     let mut filtered_symbols_arc = Arc::new(Mutex::new(filtered_symbols));
//     let mut task_vec = Vec::new();
//     for element in filtered_6th_symbols {
//         let mut filtered_symbols_arc_c = Arc::clone(&filtered_symbols_arc);
//         let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone();

//         let elememt_c = element.clone();
//         task_vec.push(tokio::spawn(async move {
//             let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == element.0);
//             if opclo_30m_option.is_some() {
//                 if rt_price_30m_vec_c[opclo_30m_option.unwrap()]
//                     .1
//                     .last()
//                     .is_some()
//                 {
//                     let mut filtered_symbols_lock: tokio::sync::MutexGuard<
//                         '_,
//                         Vec<(String, i64, f64)>,
//                     > = filtered_symbols_arc_c.lock().await;
//                     filtered_symbols_lock.push((
//                         elememt_c.0,
//                         elememt_c.1,
//                         rt_price_30m_vec_c[opclo_30m_option.unwrap()]
//                             .1
//                             .last()
//                             .unwrap()
//                             .close_price,
//                     ));
//                 }
//             }
//         }));
//     }

//     try_join_all(task_vec).await?;

//     let a = filtered_symbols_arc.lock().await.clone();
//     insert_pre_suggested_coins(2, false, &a, alldata).await;

//     Ok(())
// }
