// pub async fn strategist_001(
//     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: supertrend(ATR period 10, multiplier: 1.3, 30m close price), the area should be in SELL area.
//     // let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new();
//     // let mut filtered_2nd_symbols_arc: Arc<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 mut supertrend_vec: Vec<SupertrendData> = Vec::new();
//     //     let rt_price_30m_vec_c = alldata.rt_price_30m_vec.clone();
//     //     let filtered_2nd_symbols_arc_c = Arc::clone(&filtered_2nd_symbols_arc);
//     //     task_vec.push(tokio::spawn(async move {
//     //         let opclo_30m_option = rt_price_30m_vec_c.iter().position(|x| *x.0 == symbol);
//     //         let supertrend_option_30m =
//     //             supertrend(&symbol, &rt_price_30m_vec_c, 10, 1.3, true).await;

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

//     //             if opclo_30m_vec.len() >= 3 && supertrend_vec.len() >= 3 {
//     //                 let supertrend_search_result = supertrend_vec.binary_search_by_key(
//     //                     &opclo_30m_vec.last().unwrap().close_time,
//     //                     |SupertrendData {
//     //                          band_value,
//     //                          signal,
//     //                          area,
//     //                          close_time,
//     //                      }| *close_time,
//     //                 );
//     //                 if supertrend_search_result.is_ok() {
//     //                     if supertrend_vec[supertrend_search_result.unwrap()]
//     //                         .area
//     //                         .contains("DOWN")
//     //                     {
//     //                         let mut filtered_2nd_symbols_lock =
//     //                             filtered_2nd_symbols_arc_c.lock().await;
//     //                         filtered_2nd_symbols_lock
//     //                             .push((symbol.clone(), opclo_30m_vec.last().unwrap().close_time));
//     //                     }
//     //                 }
//     //             }
//     //         }
//     //     }));
//     // }
//     // try_join_all(task_vec).await?;

//     // 1st filtering: making basic form
//     let mut filtered_2nd_symbols: Vec<(String, i64)> = Vec::new();
//     let mut filtered_2nd_symbols_arc: Arc<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(1.to_string().as_str());
//         // exists_condition_build.push_str("\' AND close_time=");
//         // exists_condition_build.push_str(element.1.to_string().as_str());
//         let exists_condition = Some(exists_condition_build);
//         let exists_condition_c = exists_condition.clone();
//         let inspect_table_name_1_c = inspect_table_name_1.clone();
//         let inspect_table_name_2_c = inspect_table_name_2.clone();
//         let inspect_table_name_3_c = inspect_table_name_3.clone();
//         let inspect_table_name_4_c = inspect_table_name_4.clone();
//         let element_c = element.clone();
//         let filtered_3rd_symbols_arc_c = Arc::clone(&filtered_3rd_symbols_arc);
//         task_vec.push(tokio::spawn(async move {
//             let inspect_result_1 =
//                 exists_record(&inspect_table_name_1_c, &exists_condition_c).await;
//             let inspect_result_2 =
//                 exists_record(&inspect_table_name_2_c, &exists_condition_c).await;
//             let inspect_result_3 =
//                 exists_record(&inspect_table_name_3_c, &exists_condition_c).await;
//             let inspect_result_4 =
//                 exists_record(&inspect_table_name_4_c, &exists_condition_c).await;

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

//     // 3rd filtering: BollingerBand (length 10, stddev: 2.5, 30m close price) the current price should be under the lowerband of BB.
//     let filtered_3rd_symbols_c = filtered_3rd_symbols_arc.lock().await.clone();
//     let sma10_30m_data: Vec<(String, Vec<SmaData>)> = sma(
//         10,
//         &alldata.rt_price_30m_vec,
//         &filtered_3rd_symbols_c,
//     )
//     .await?;

//     let bb10_30m_data: Vec<(String, Vec<BollingerBandData>)> =
//         bollingerband(
//             10,
//             3.0,
//             &sma10_30m_data,
//             &alldata.rt_price_30m_vec,
//             &filtered_3rd_symbols_c,
//         )
//         .await?;

//     let mut task_vec = Vec::new();
//     let mut filtered_4th_symbols: Vec<(String, i64)> = Vec::new();
//     let mut filtered_4th_symbols_arc: Arc<Mutex<Vec<(String, i64)>>> =
//         Arc::new(Mutex::new(filtered_4th_symbols)); // (symbol, closetime)
//     for element in filtered_3rd_symbols_c {
//         let mut bb10_30m_vec: Vec<BollingerBandData> = Vec::new();
//         let bb10_30m_option = bb10_30m_data.iter().position(|x| *x.0 == element.0);
//         let bb10_30m_option_c = bb10_30m_option.clone();
//         let element_c = element.clone();
//         let filtered_4th_symbols_arc_c = Arc::clone(&filtered_4th_symbols_arc);

//         if bb10_30m_option_c.is_some() {
//             bb10_30m_vec = bb10_30m_data[bb10_30m_option_c.unwrap()].1.clone();

//             if bb10_30m_vec.len() >= 3 {
//                 let bb10_30m_vec_c = bb10_30m_vec.clone();
//                 let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec)
//                     .await
//                     .unwrap();
//                 task_vec.push(tokio::spawn(async move {
//                     let bb_search_result = bb10_30m_vec_c.binary_search_by_key(
//                         &element_c.1,
//                         |&BollingerBandData {
//                              sma,
//                              upperband,
//                              lowerband,
//                              close_time,
//                          }| close_time,
//                     );
//                     if bb_search_result.is_ok() {
//                         if bb10_30m_vec_c[bb_search_result.unwrap()].lowerband > current_price {
//                             let mut filtered_4th_symbols_lock =
//                                 filtered_4th_symbols_arc_c.lock().await;
//                             filtered_4th_symbols_lock.push(element_c);
//                         }
//                     }
//                 }));
//             }
//         }
//     }
//     try_join_all(task_vec).await?;

//     // 4th filtering: the current price should be lower than lowest price from the latest 20 candles.
//     let mut task_vec = Vec::new();
//     let filtered_4th_symbols_c = filtered_4th_symbols_arc.lock().await.clone();
//     let mut filtered_5th_symbols: Vec<(String, i64)> = Vec::new();
//     let mut filtered_5th_symbols_arc: Arc<Mutex<Vec<(String, i64)>>> =
//         Arc::new(Mutex::new(filtered_5th_symbols)); // (symbol, closetime)
//     for element in filtered_4th_symbols_c {
//         let rt_price_30m_option = alldata.rt_price_30m_vec.iter().position(|x| *x.0 == element.0);
//         let element_c = element.clone();
//         let filtered_5th_symbols_arc_c = Arc::clone(&filtered_5th_symbols_arc);

//         if rt_price_30m_option.is_some() {
//             let mut rt_price_30m_vec_c = alldata.rt_price_30m_vec[rt_price_30m_option.unwrap()].1.clone();
//             let current_price = get_current_price(&element_c.0, &alldata.rt_price_30m_vec)
//             .await
//             .unwrap();

//             task_vec.push(tokio::spawn(async move {
//                 if rt_price_30m_vec_c.len() >= 21 {
//                     rt_price_30m_vec_c.pop();
//                     rt_price_30m_vec_c.reverse();
//                     rt_price_30m_vec_c.truncate(20);

//                     let lowest_price_option = rt_price_30m_vec_c.iter()
//                                                         .enumerate()
//                                                         .min_by(|(_, a), (_, b)| {
//                                                             a.low_price
//                                                                 .partial_cmp(&b.low_price)
//                                                                 .expect("Nan was forbidden.")
//                                                         })
//                                                         .map(|(index, _)| index);

//                     if lowest_price_option.is_some() {
//                         let lowest_price = rt_price_30m_vec_c[lowest_price_option.unwrap()].low_price;
//                         if lowest_price > current_price {
//                             let mut filtered_5th_symbols_lock =
//                                 filtered_5th_symbols_arc_c.lock().await;
//                             filtered_5th_symbols_lock.push(element_c);
//                         }
//                     }
//                 }
//             }));
//         }
//     }
//     try_join_all(task_vec).await?;

//     // 5th filtering: RSI (length: 10, 30m close price) the current index should be lower than 30.
//     let filtered_5th_symbol_c = filtered_5th_symbols_arc.lock().await.clone();
//     let mut rsi10_30m_data: Vec<(String, Vec<RsiData>)> = rsi(
//         10,
//         &alldata.rt_price_30m_vec,
//         &filtered_5th_symbol_c,
//     )
//     .await?;
//     let mut task_vec = Vec::new();
//     let mut filtered_6th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime)
//     let mut filtered_6th_symbols_arc: Arc<Mutex<Vec<(String, i64)>>> =
//     Arc::new(Mutex::new(filtered_6th_symbols)); // (symbol, closetime)

//     for element in filtered_5th_symbol_c {
//         let rsi10_30m_option = rsi10_30m_data.iter().position(|x| *x.0 == element.0);
//         let filtered_6th_symbols_arc_c = Arc::clone(&filtered_6th_symbols_arc);

//         if rsi10_30m_option.is_some() {
//             let mut rsi10_30m_vec = rsi10_30m_data[rsi10_30m_option.unwrap()].1.clone();

//             if rsi10_30m_vec.len() >= 3 {
//                 let element_c = element.clone();
//                 task_vec.push(tokio::spawn(async move {
//                     let rsi_search_result = rsi10_30m_vec.binary_search_by_key(
//                         &element.1,
//                         |&RsiData {
//                             rsi_value,
//                             close_time,
//                         }| close_time,
//                     );
//                     if rsi_search_result.is_ok() {
//                         if rsi10_30m_vec[rsi_search_result.unwrap()].rsi_value <= 20.0 {
//                             let mut filtered_6th_symbols_lock =
//                                 filtered_6th_symbols_arc_c.lock().await;
//                             filtered_6th_symbols_lock.push(element_c);

//                         }
//                     }
//                 }));
//             }
//         }
//     }
//     try_join_all(task_vec).await?;

//     // 6th filtering: StochRSI (RSI length: 14, Stoch length: 14, smooth k: 3, smooth d: 3) smooth kn <= 10, kn-1 <= 25.0
//     let filtered_6th_symbol_c = filtered_6th_symbols_arc.lock().await.clone();
//     let mut rsi14_30m_data: Vec<(String, Vec<RsiData>)> = rsi(
//         14,
//         &alldata.rt_price_30m_vec,
//         &filtered_6th_symbol_c,
//     )
//     .await?;
//     let stoch_rsi_data = stoch_rsi(&rsi14_30m_data, 14, 3, 3).await?;
//     let mut stoch_rsi14_30m_vec: Vec<StochRsiData> = Vec::new();
//     let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new(); // (symbol, closetime)
//     for element in filtered_6th_symbol_c {
//         let stoch_rsi14_30m_option = stoch_rsi_data.iter().position(|x| *x.0 == element.0);

//         if stoch_rsi14_30m_option.is_some() {
//             stoch_rsi14_30m_vec = stoch_rsi_data[stoch_rsi14_30m_option.unwrap()].1.clone();

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

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

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

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

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

//     try_join_all(task_vec).await?;

//     // 6th filtering condition: MACD
//     // let mut opclo_30m_vec: Vec<RealtimePriceData> = Vec::new();
//     // let mut ema3_1d_vec: &Vec<EmaData> = &Vec::new();
//     // let mut ema10_1d_vec: &Vec<EmaData> = &Vec::new();

//     // let mut filtered_7th_symbols: Vec<(String, i64)> = Vec::new();  // (symbol, closetime)
//     // for element in filtered_6th_symbols {
//     //     let ema3_1d_option = alldata.ema3_1d_data.iter().position(|x| *x.0 == *element.0);
//     //     let ema10_1d_option = alldata.ema10_1d_data.iter().position(|x| *x.0 == *element.0);

//     //     if ema3_1d_option.is_some() && ema10_1d_option.is_some() {
//     //         ema3_1d_vec = &alldata.ema3_1d_data[ema3_1d_option.unwrap()].1;
//     //         ema10_1d_vec = &alldata.ema10_1d_data[ema10_1d_option.unwrap()].1;

//     //         if ema3_1d_vec.len() > 20 && ema10_1d_vec.len() > 20 {
//     //             let macd_vec = ema_macd(&ema3_1d_vec, &ema10_1d_vec, 10).await?;
//     //         //  let macd_search_result = macd_vec.binary_search_by_key(&element.1, |&EmaMacd{macd_value, close_time}|close_time);

//     //             // if macd_search_result.is_ok() {
//     //                 if macd_vec.last().unwrap().macd_value - macd_vec[macd_vec.len() -2].macd_value >= 0.0 {
//     //                     filtered_7th_symbols.push(element);
//     //                 }
//     //             // }
//     //         }
//     //     }
//     // }
//     let a = filtered_symbols_arc.lock().await.clone();
//     insert_pre_suggested_coins(1, false, &a, alldata).await;

//     Ok(())
// }
