support get huge volume by different window sizes

This commit is contained in:
blade 2025-07-30 17:28:01 +08:00
parent ca2efb002e
commit 5bc9b2b8c7
6 changed files with 129 additions and 72 deletions

View File

@ -70,6 +70,8 @@ MONITOR_CONFIG = {
}
}
WINDOW_SIZE = {"window_sizes":[50, 80, 100, 120]}
BAR_THRESHOLD = {
"5m": 1000 * 60 * 5,
"15m": 1000 * 60 * 15,

View File

@ -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"""

View File

@ -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,

View File

@ -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)

View File

@ -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;
limit 10;
SHOW VARIABLES LIKE 'max_connections';

View File

@ -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),