diff --git a/config.py b/config.py index 67d0747..265790b 100644 --- a/config.py +++ b/config.py @@ -70,6 +70,8 @@ MONITOR_CONFIG = { } } +WINDOW_SIZE = {"window_sizes":[50, 80, 100, 120]} + BAR_THRESHOLD = { "5m": 1000 * 60 * 5, "15m": 1000 * 60 * 15, diff --git a/core/db_huge_volume_data.py b/core/db_huge_volume_data.py index ec8ad98..1e6e56b 100644 --- a/core/db_huge_volume_data.py +++ b/core/db_huge_volume_data.py @@ -17,6 +17,7 @@ class DBHugeVolumeData: self.columns = [ "symbol", "bar", + "window_size", "timestamp", "date_time", "open", @@ -73,7 +74,8 @@ class DBHugeVolumeData: def _build_query_conditions( self, symbol: Optional[str] = None, - bar: Optional[str] = None, + bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None, additional_conditions: Optional[List[str]] = None @@ -82,6 +84,7 @@ class DBHugeVolumeData: 构建查询条件 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :param additional_conditions: 额外的查询条件 @@ -96,7 +99,9 @@ class DBHugeVolumeData: if bar: conditions.append("bar = :bar") condition_dict["bar"] = bar - + if window_size: + conditions.append("window_size = :window_size") + condition_dict["window_size"] = window_size # 处理时间参数 start_timestamp = self._process_time_parameter(start) end_timestamp = self._process_time_parameter(end) @@ -166,53 +171,57 @@ class DBHugeVolumeData: self.db_manager.insert_data_to_mysql_simple(df) - def query_latest_data(self, symbol: str, bar: str) -> Optional[Dict[str, Any]]: + def query_latest_data(self, symbol: str, bar: str, window_size: int) -> Optional[Dict[str, Any]]: """ 查询最新巨量交易数据 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :return: 最新数据记录或None """ sql = """ SELECT * FROM crypto_huge_volume - WHERE symbol = :symbol AND bar = :bar + WHERE symbol = :symbol AND bar = :bar AND window_size = :window_size ORDER BY timestamp DESC LIMIT 1 """ - condition_dict = {"symbol": symbol, "bar": bar} + condition_dict = {"symbol": symbol, "bar": bar, "window_size": window_size} return self.db_manager.query_data(sql, condition_dict, return_multi=False) - def query_data_by_symbol_bar_timestamp(self, symbol: str, bar: str, timestamp: int) -> Optional[Dict[str, Any]]: + def query_data_by_symbol_bar_window_size_timestamp(self, symbol: str, bar: str, window_size: int, timestamp: int) -> Optional[Dict[str, Any]]: """ - 根据交易对、K线周期和时间戳查询巨量交易数据 + 根据交易对、K线周期, 窗口大小和时间戳查询巨量交易数据 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param timestamp: 时间戳 :return: 数据记录或None """ sql = """ SELECT * FROM crypto_huge_volume - WHERE symbol = :symbol AND bar = :bar AND timestamp = :timestamp + WHERE symbol = :symbol AND bar = :bar AND window_size = :window_size AND timestamp = :timestamp """ - condition_dict = {"symbol": symbol, "bar": bar, "timestamp": timestamp} + condition_dict = {"symbol": symbol, "bar": bar, "window_size": window_size, "timestamp": timestamp} return self.db_manager.query_data(sql, condition_dict, return_multi=False) - def query_huge_volume_data_by_symbol_bar( + def query_huge_volume_data_by_symbol_bar_window_size( self, symbol: str, bar: str, + window_size: int, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: """ - 根据交易对和K线周期查询巨量交易数据 + 根据交易对、K线周期和窗口大小查询巨量交易数据 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 数据记录列表或None """ - conditions, condition_dict = self._build_query_conditions(symbol, bar, start, end) + conditions, condition_dict = self._build_query_conditions(symbol, bar, window_size, start, end) where_clause = " AND ".join(conditions) if conditions else "1=1" sql = f""" @@ -227,6 +236,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -234,12 +244,13 @@ class DBHugeVolumeData: 查询巨量交易记录(只返回huge_volume=1的记录) :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 巨量交易记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["huge_volume = 1"] + symbol, bar, window_size, start, end, additional_conditions=["huge_volume = 1"] ) where_clause = " AND ".join(conditions) @@ -255,6 +266,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -262,12 +274,13 @@ class DBHugeVolumeData: 查询80/20量价尖峰记录(只返回volume_80_20_price_spike=1的记录) :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 80/20量价尖峰记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["volume_80_20_price_spike = 1"] + symbol, bar, window_size, start, end, additional_conditions=["volume_80_20_price_spike = 1"] ) where_clause = " AND ".join(conditions) @@ -283,6 +296,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -290,12 +304,13 @@ class DBHugeVolumeData: 查询90/10量价尖峰记录(只返回volume_90_10_price_spike=1的记录) :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 90/10量价尖峰记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["volume_90_10_price_spike = 1"] + symbol, bar, window_size, start, end, additional_conditions=["volume_90_10_price_spike = 1"] ) where_clause = " AND ".join(conditions) @@ -311,6 +326,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -318,12 +334,13 @@ class DBHugeVolumeData: 查询价格达到80%分位数高点的记录(只返回price_80_high=1的记录) :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 价格80%分位数高点记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["price_80_high = 1"] + symbol, bar, window_size, start, end, additional_conditions=["price_80_high = 1"] ) where_clause = " AND ".join(conditions) @@ -339,6 +356,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -351,7 +369,7 @@ class DBHugeVolumeData: :return: 价格20%分位数低点记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["price_20_low = 1"] + symbol, bar, window_size, start, end, additional_conditions=["price_20_low = 1"] ) where_clause = " AND ".join(conditions) @@ -367,6 +385,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -379,7 +398,7 @@ class DBHugeVolumeData: :return: 价格90%分位数高点记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["price_90_high = 1"] + symbol, bar, window_size, start, end, additional_conditions=["price_90_high = 1"] ) where_clause = " AND ".join(conditions) @@ -395,6 +414,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[List[Dict[str, Any]]]: @@ -407,7 +427,7 @@ class DBHugeVolumeData: :return: 价格10%分位数低点记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, start, end, additional_conditions=["price_10_low = 1"] + symbol, bar, window_size, start, end, additional_conditions=["price_10_low = 1"] ) where_clause = " AND ".join(conditions) @@ -423,6 +443,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[Dict[str, Any]]: @@ -430,11 +451,12 @@ class DBHugeVolumeData: 获取巨量交易统计摘要 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 统计摘要或None """ - conditions, condition_dict = self._build_query_conditions(symbol, bar, start, end) + conditions, condition_dict = self._build_query_conditions(symbol, bar, window_size, start, end) where_clause = " AND ".join(conditions) if conditions else "1=1" sql = f""" @@ -461,17 +483,19 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, limit: int = 10 ) -> Optional[List[Dict[str, Any]]]: """ 获取成交量尖峰最高的记录 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param limit: 返回记录数量 :return: 成交量尖峰记录列表或None """ conditions, condition_dict = self._build_query_conditions( - symbol, bar, additional_conditions=["huge_volume = 1"] + symbol, bar, window_size, additional_conditions=["huge_volume = 1"] ) where_clause = " AND ".join(conditions) @@ -489,6 +513,7 @@ class DBHugeVolumeData: self, symbol: Optional[str] = None, bar: Optional[str] = None, + window_size: Optional[int] = None, start: Optional[Union[str, int]] = None, end: Optional[Union[str, int]] = None ) -> Optional[Dict[str, Any]]: @@ -496,11 +521,12 @@ class DBHugeVolumeData: 获取分位数统计信息 :param symbol: 交易对 :param bar: K线周期 + :param window_size: 窗口大小 :param start: 开始时间 :param end: 结束时间 :return: 分位数统计信息或None """ - conditions, condition_dict = self._build_query_conditions(symbol, bar, start, end) + conditions, condition_dict = self._build_query_conditions(symbol, bar, window_size, start, end) where_clause = " AND ".join(conditions) if conditions else "1=1" sql = f""" diff --git a/core/huge_volume.py b/core/huge_volume.py index b957b67..fd5f6a2 100644 --- a/core/huge_volume.py +++ b/core/huge_volume.py @@ -108,6 +108,7 @@ class HugeVolume: # 按时间戳排序 data = data.sort_values(by="timestamp", ascending=True).copy() + data["window_size"] = window_size # 计算移动窗口的成交量均值和标准差 data["volume_ma"] = ( @@ -159,7 +160,7 @@ class HugeVolume: end_date = re.sub(r"[\:\-\s]", "", str(end_date)) symbol = data["symbol"].iloc[0] bar = data["bar"].iloc[0] - file_name = f"volume_spike_{symbol}_{bar}_{start_date}_{end_date}.xlsx" + file_name = f"volume_spike_{symbol}_{bar}_{window_size}_{start_date}_{end_date}.xlsx" try: with pd.ExcelWriter( os.path.join(self.output_folder, file_name) @@ -173,6 +174,7 @@ class HugeVolume: def next_periods_rise_or_fall( self, data: pd.DataFrame, + window_size: int = 50, periods: List[int] = [3, 5], output_excel: bool = False ) -> Tuple[pd.DataFrame, pd.DataFrame]: @@ -280,6 +282,7 @@ class HugeVolume: { "symbol": data["symbol"].iloc[0] if len(data) > 0 else "", "bar": data["bar"].iloc[0] if len(data) > 0 else "", + "window_size": window_size, "huge_volume": 1, "price_type": price_type, "next_period": period, diff --git a/huge_volume_main.py b/huge_volume_main.py index 4a3ae5f..c744bf4 100644 --- a/huge_volume_main.py +++ b/huge_volume_main.py @@ -4,7 +4,7 @@ from core.db_huge_volume_data import DBHugeVolumeData from core.utils import timestamp_to_datetime from market_data_main import MarketDataMain import logging -from config import MONITOR_CONFIG, MYSQL_CONFIG +from config import MONITOR_CONFIG, MYSQL_CONFIG, WINDOW_SIZE from datetime import datetime import pandas as pd import os @@ -16,7 +16,7 @@ logging.basicConfig( class HugeVolumeMain: - def __init__(self, window_size: int = 50, threshold: float = 2.0): + def __init__(self, threshold: float = 2.0): mysql_user = MYSQL_CONFIG.get("user", "xch") mysql_password = MYSQL_CONFIG.get("password", "") if not mysql_password: @@ -29,22 +29,21 @@ class HugeVolumeMain: self.huge_volume = HugeVolume() self.db_market_data = DBMarketData(self.db_url) self.db_huge_volume_data = DBHugeVolumeData(self.db_url) - self.monitor_main = MarketDataMain() - self.window_size = window_size + self.market_data_main = MarketDataMain() self.threshold = threshold self.output_folder = "./output/huge_volume_statistics/" os.makedirs(self.output_folder, exist_ok=True) - def batch_initial_detect_volume_spike(self, start: str = None): - for symbol in self.monitor_main.symbols: - for bar in self.monitor_main.bars: + def batch_initial_detect_volume_spike(self, window_size: int = 50, start: str = None): + for symbol in self.market_data_main.symbols: + for bar in self.market_data_main.bars: if start is None: start = MONITOR_CONFIG.get("volume_monitor", {}).get( "initial_date", "2025-05-01 00:00:00" ) data = self.detect_volume_spike( - symbol, bar, start, only_output_huge_volume=True, is_update=False + symbol, bar, window_size, start, only_output_huge_volume=True, is_update=False ) if data is not None and len(data) > 0: logging.info(f"此次初始化巨量交易数据: {len(data)}条") @@ -55,6 +54,7 @@ class HugeVolumeMain: self, symbol: str = "XCH-USDT", bar: str = "5m", + window_size: int = 50, start: str = "2025-05-01 00:00:00", end: str = None, only_output_huge_volume: bool = False, @@ -66,16 +66,16 @@ class HugeVolumeMain: ) if end is None: end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - logging.info(f"开始处理巨量交易数据: {symbol} {bar} {start} {end}") + logging.info(f"开始处理巨量交易数据: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}") data = self.db_market_data.query_market_data_by_symbol_bar( symbol, bar, start, end ) if data is None: - logging.warning(f"获取行情数据失败: {symbol} {bar} {start} {end}") + logging.warning(f"获取行情数据失败: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}") return None else: if len(data) == 0: - logging.warning(f"获取行情数据为空: {symbol} {bar} {start} {end}") + logging.warning(f"获取行情数据为空: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}") return None else: if isinstance(data, list): @@ -84,7 +84,7 @@ class HugeVolumeMain: data = pd.DataFrame([data]) data = self.huge_volume.detect_huge_volume( data=data, - window_size=self.window_size, + window_size=window_size, threshold=self.threshold, check_price=True, only_output_huge_volume=only_output_huge_volume, @@ -94,8 +94,8 @@ class HugeVolumeMain: if is_update: for index, row in data.iterrows(): exist_huge_volume_data = ( - self.db_huge_volume_data.query_data_by_symbol_bar_timestamp( - symbol, bar, row["timestamp"] + self.db_huge_volume_data.query_data_by_symbol_bar_window_size_timestamp( + symbol, bar, window_size, row["timestamp"] ) ) if exist_huge_volume_data is not None: @@ -113,16 +113,16 @@ class HugeVolumeMain: else: return None - def batch_update_volume_spike(self): - for symbol in self.monitor_main.symbols: - for bar in self.monitor_main.bars: - self.update_volume_spike(symbol, bar) + def batch_update_volume_spike(self, window_size: int = 50): + for symbol in self.market_data_main.symbols: + for bar in self.market_data_main.bars: + self.update_volume_spike(symbol, bar, window_size) - def update_volume_spike(self, symbol: str, bar: str): + def update_volume_spike(self, symbol: str, bar: str, window_size: int = 50): try: - self.monitor_main.update_data(symbol, bar) + self.market_data_main.update_data(symbol, bar) latest_huge_volume_data = self.db_huge_volume_data.query_latest_data( - symbol, bar + symbol, bar, window_size ) if latest_huge_volume_data is None or len(latest_huge_volume_data) == 0: self.detect_volume_spike(symbol, bar, only_output_huge_volume=True) @@ -132,26 +132,27 @@ class HugeVolumeMain: earliest_timestamp = latest_huge_volume_data["timestamp"] seconds = self.get_seconds_by_bar(bar) earliest_timestamp = earliest_timestamp - ( - (self.window_size - 1) * seconds * 1000 + (window_size - 1) * seconds * 1000 ) earliest_date_time = timestamp_to_datetime(earliest_timestamp) data = self.detect_volume_spike( symbol=symbol, bar=bar, + window_size=window_size, start=earliest_date_time, only_output_huge_volume=True, is_update=True, ) logging.info( - f"更新巨量交易数据: {symbol} {bar} from {earliest_date_time}" + f"更新巨量交易数据: {symbol} {bar} 窗口大小: {window_size} 从 {earliest_date_time} 到 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" ) if data is not None and len(data) > 0: logging.info(f"此次更新巨量交易数据: {len(data)}条") else: logging.info(f"此次更新巨量交易数据为空") except Exception as e: - logging.error(f"更新巨量交易数据失败: {symbol} {bar} {e}") + logging.error(f"更新巨量交易数据失败: {symbol} {bar} 窗口大小: {window_size} 从 {earliest_date_time} 到 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: {e}") def get_seconds_by_bar(self, bar: str): """ @@ -201,6 +202,7 @@ class HugeVolumeMain: self, symbol: str, bar: str, + window_size: int = 50, start: str = None, end: str = None, periods: list = [3, 5], @@ -212,14 +214,14 @@ class HugeVolumeMain: ) if end is None: end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - logging.info(f"开始计算巨量出现后,之后3或5个周期,上涨或下跌的比例: {symbol} {bar} {start} {end}") + logging.info(f"开始计算巨量出现后,之后3或5个周期,上涨或下跌的比例: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}") huge_volume_data = ( - self.db_huge_volume_data.query_huge_volume_data_by_symbol_bar( - symbol, bar, start, end + self.db_huge_volume_data.query_huge_volume_data_by_symbol_bar_window_size( + symbol, bar, window_size, start, end ) ) if huge_volume_data is None or len(huge_volume_data) == 0: - logging.warning(f"获取巨量交易数据为空: {symbol} {bar} {start} {end}") + logging.warning(f"获取巨量交易数据为空: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}") return None else: if isinstance(huge_volume_data, list): @@ -230,7 +232,7 @@ class HugeVolumeMain: symbol, bar, start, end ) if market_data is None or len(market_data) == 0: - logging.warning(f"获取行情数据为空: {symbol} {bar} {start} {end}") + logging.warning(f"获取行情数据为空: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}") return None else: if isinstance(market_data, list): @@ -282,10 +284,12 @@ class HugeVolumeMain: ) # 根据timestamp排序 data = data.sort_values(by="timestamp", ascending=True) + data["window_size"] = window_size data = data[ [ "symbol", "bar", + "window_size", "timestamp", "date_time", "open", @@ -303,12 +307,13 @@ class HugeVolumeMain: data = data.dropna() data = data.reset_index(drop=True) data, result_data = self.huge_volume.next_periods_rise_or_fall( - data=data, periods=periods, output_excel=output_excel + data=data, window_size=window_size, periods=periods, output_excel=output_excel ) return data, result_data def batch_next_periods_rise_or_fall( self, + window_size: int = 50, start: str = None, end: str = None, periods: list = [3, 5], @@ -322,10 +327,10 @@ class HugeVolumeMain: end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") data_list = [] result_data_list = [] - for symbol in self.monitor_main.symbols: - for bar in self.monitor_main.bars: + for symbol in self.market_data_main.symbols: + for bar in self.market_data_main.bars: data, result_data = self.next_periods_rise_or_fall( - symbol, bar, start, end, periods, output_excel + symbol, bar, window_size, start, end, periods, output_excel ) data_list.append(data) result_data_list.append(result_data) @@ -351,13 +356,27 @@ class HugeVolumeMain: return data, result_data +def batch_initial_detect_volume_spike(threshold: float = 2.0): + window_sizes = WINDOW_SIZE.get("window_sizes", None) + if window_sizes is None or not isinstance(window_sizes, list) or len(window_sizes) == 0: + window_sizes = [50, 80, 100, 120] + huge_volume_main = HugeVolumeMain(threshold) + for window_size in window_sizes: + huge_volume_main.batch_initial_detect_volume_spike( + window_size=window_size, + start="2025-05-01 00:00:00", + ) + + +def batch_update_volume_spike(threshold: float = 2.0): + window_sizes = WINDOW_SIZE.get("window_sizes", None) + if window_sizes is None or not isinstance(window_sizes, list) or len(window_sizes) == 0: + window_sizes = [50, 80, 100, 120] + huge_volume_main = HugeVolumeMain(threshold) + for window_size in window_sizes: + huge_volume_main.batch_update_volume_spike(window_size=window_size) + + if __name__ == "__main__": - huge_volume_main = HugeVolumeMain() - # statistics_main.batch_initial_detect_volume_spike( - # start="2025-05-01 00:00:00", - # ) - huge_volume_main.batch_update_volume_spike() - # huge_volume_main.batch_next_periods_rise_or_fall( - # periods=[3, 5], - # output_excel=True, - # ) + # batch_initial_detect_volume_spike(threshold=2.0) + batch_update_volume_spike(threshold=2.0) diff --git a/sql/query/sql_playground.sql b/sql/query/sql_playground.sql index 2e77d55..60c5878 100644 --- a/sql/query/sql_playground.sql +++ b/sql/query/sql_playground.sql @@ -1,10 +1,14 @@ select * from crypto_market_data -WHERE symbol='XCH-USDT' and bar='5m' #and date_time > '2025-07-26' -order by timestamp desc; +WHERE symbol='DOGE-USDT-SWAP' and bar='1D' #and date_time > '2025-07-01' +order by timestamp; + +delete FROM crypto_market_data where symbol != 'XCH-USDT'; select * from crypto_trade_data -where date_time > '2025-05-03' -order by ts, tradeId asc; +where symbol='BTC-USDT' +order by ts desc; + +select count(1) from crypto_trade_data; select * from crypto_huge_volume WHERE symbol='XCH-USDT' and bar='5m' and date_time > '2025-07-26' @@ -17,4 +21,6 @@ order by timestamp desc; select * from crypto_huge_volume WHERE symbol='BTC-USDT' and bar='5m' order by timestamp desc -limit 10; \ No newline at end of file +limit 10; + +SHOW VARIABLES LIKE 'max_connections'; \ No newline at end of file diff --git a/sql/table/crypto_huge_volume.sql b/sql/table/crypto_huge_volume.sql index 17b479c..b3192ae 100644 --- a/sql/table/crypto_huge_volume.sql +++ b/sql/table/crypto_huge_volume.sql @@ -2,6 +2,7 @@ CREATE TABLE IF NOT EXISTS crypto_huge_volume ( id BIGINT AUTO_INCREMENT PRIMARY KEY, symbol VARCHAR(50) NOT NULL COMMENT '交易对', bar VARCHAR(20) NOT NULL COMMENT 'K线周期', + window_size INT NOT NULL COMMENT '窗口大小, 50, 80, 100, 120', timestamp BIGINT NOT NULL COMMENT '时间戳', date_time VARCHAR(50) NOT NULL COMMENT '日期时间', open DECIMAL(20,5) NOT NULL COMMENT '开盘价', @@ -28,8 +29,8 @@ CREATE TABLE IF NOT EXISTS crypto_huge_volume ( price_10_low TINYINT NOT NULL DEFAULT 0 COMMENT '价格是否达到10%分位数低点(0:否,1:是)', volume_90_10_price_spike TINYINT NOT NULL DEFAULT 0 COMMENT '是否出现90/10量价尖峰(0:否,1:是)', create_time VARCHAR(50) NOT NULL COMMENT '创建时间', - UNIQUE KEY uniq_symbol_bar_timestamp (symbol, bar, timestamp), - INDEX idx_symbol_bar (symbol, bar), + UNIQUE KEY uniq_symbol_bar_window_size_timestamp (symbol, bar, window_size, timestamp), + INDEX idx_symbol_bar_window_size (symbol, bar, window_size), INDEX idx_timestamp (timestamp), INDEX idx_huge_volume (huge_volume), INDEX idx_volume_80_20_price_spike (volume_80_20_price_spike),