feat(datasource): 加密货币数据支持分钟级时间精度

- flask_server.py: dataframe_to_json 增加 asset_type 参数,crypto 使用 '%Y-%m-%d %H:%M:%S' 格式
- ccxt_source.py: 移除 normalize() 调用,保留完整时间精度
- ETF/指数数据保持天级精度 '%Y-%m-%d' 不变
This commit is contained in:
2026-05-15 21:25:08 +08:00
parent a49002f622
commit 18ef2a1704
2 changed files with 21 additions and 7 deletions

View File

@@ -250,10 +250,14 @@ class CCXTSource:
return None
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
# 转换时间戳为日期索引UTC -> 北京时间)
# 注意:保留完整时间精度(包括分钟),用于分钟级 K 线数据
df['date'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True).dt.tz_convert('Asia/Shanghai')
df = df.set_index('date')
df = df[['open', 'high', 'low', 'close', 'volume']]
df.index = df.index.normalize()
# 注意:不再使用 normalize(),保留完整时间精度
return df

View File

@@ -266,7 +266,7 @@ def fetch_data_with_ttl(
df = f.fetch(code, start, end, timeframe=timeframe)
if df is None or len(df) == 0:
return None, False
result = dataframe_to_json(df)
result = dataframe_to_json(df, asset_type.value)
result['code'] = code
result['asset_type'] = asset_type.value
result['cache_strategy'] = 'no_cache_crypto'
@@ -369,9 +369,15 @@ class JSONEncoder(json.JSONEncoder):
return super().default(obj)
def dataframe_to_json(df: pd.DataFrame) -> Dict:
def dataframe_to_json(df: pd.DataFrame, asset_type: Optional[str] = None) -> Dict:
"""将 DataFrame 转换为 JSON 可序列化的字典
Args:
df: DataFrame 数据
asset_type: 资产类型,用于决定日期格式精度
- crypto: 使用分钟级格式 '%Y-%m-%d %H:%M:%S'
- 其他: 使用天级格式 '%Y-%m-%d'
如果 df.attrs 中有 info 字段,会放到最外层返回
"""
if df is None or len(df) == 0:
@@ -384,12 +390,16 @@ def dataframe_to_json(df: pd.DataFrame) -> Dict:
# 重置索引
df_reset = df.reset_index()
# 处理日期列
# 处理日期列 - 根据资产类型决定格式精度
date_columns = ['date', 'Date', 'index', 'trade_date', 'datetime']
# 加密货币使用分钟级格式,其他使用天级格式
date_format = '%Y-%m-%d %H:%M:%S' if asset_type == 'crypto' else '%Y-%m-%d'
for col in date_columns:
if col in df_reset.columns:
try:
df_reset[col] = pd.to_datetime(df_reset[col]).dt.strftime('%Y-%m-%d')
df_reset[col] = pd.to_datetime(df_reset[col]).dt.strftime(date_format)
if col != 'date':
df_reset = df_reset.rename(columns={col: 'date'})
break
@@ -412,8 +422,8 @@ def dataframe_to_json(df: pd.DataFrame) -> Dict:
"count": len(records),
"columns": list(df_clean.columns),
"date_range": {
"start": df.index.min().strftime('%Y-%m-%d') if len(df) > 0 else None,
"end": df.index.max().strftime('%Y-%m-%d') if len(df) > 0 else None,
"start": df.index.min().strftime(date_format) if len(df) > 0 else None,
"end": df.index.max().strftime(date_format) if len(df) > 0 else None,
}
}