refactor(flask_server): 多项优化重构

优化内容:

1. fetch_with_adj → fetch(adj=adj)
   - _fetch_full_data_cached 使用 fetch(adj=adj) 替代 fetch_with_adj

2. 加密货币分支添加 adj 参数
   - fetch_data_with_ttl 中加密货币调用添加 adj='raw'

3. ETF 净值溢价率逻辑抽取
   - 新增 build_premium_result() 函数
   - get_ohlcv 和 get_etf_nav 使用该函数,减少 42 行重复代码

4. SSH 配置信息增强
   - ssh_status 改为 ssh 对象,包含更多详细信息
   - 添加 required_types(需要 SSH 的资产类型列表)

代码行数:减少约 40 行重复代码
This commit is contained in:
2026-05-23 19:03:09 +08:00
parent 67d67b1eea
commit 0f4295a144

View File

@@ -151,8 +151,8 @@ def _fetch_full_data_cached(code: str, today: str, adj: str = 'raw') -> Optional
try: try:
with f: with f:
# 使用 fetch_with_adj 获取数据(支持复权) # 使用 fetch(adj=adj) 获取数据(支持复权)
df = f.fetch_with_adj(code, DEFAULT_START_DATE, today, adj) df = f.fetch(code, DEFAULT_START_DATE, today, adj)
if df is None or len(df) == 0: if df is None or len(df) == 0:
return None return None
@@ -276,7 +276,8 @@ def fetch_data_with_ttl(
f = get_fetcher() f = get_fetcher()
try: try:
with f: with f:
df = f.fetch(code, start, end, timeframe=timeframe) # 加密货币仅支持 adj='raw'
df = f.fetch(code, start, end, adj='raw', timeframe=timeframe)
if df is None or len(df) == 0: if df is None or len(df) == 0:
return None, False return None, False
result = dataframe_to_json(df, asset_type.value) result = dataframe_to_json(df, asset_type.value)
@@ -469,6 +470,43 @@ def get_default_dates() -> Tuple[str, str]:
return start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d') return start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d')
def build_premium_result(premium_series: pd.Series) -> Dict:
"""
构建溢价率返回结果
Args:
premium_series: 溢价率序列(索引为日期)
Returns:
包含 premium_series, latest_premium, premium_date, premium_stats 的字典
"""
if premium_series is None or len(premium_series) == 0:
return {}
# 转换为日期-溢价率列表
premium_data = [
{"date": date.strftime('%Y-%m-%d'), "premium": round(premium, 6)}
for date, premium in premium_series.items()
]
# 最新溢价率
latest_premium = premium_series.iloc[-1]
latest_date = premium_series.index[-1].strftime('%Y-%m-%d')
return {
"premium_series": premium_data,
"latest_premium": round(latest_premium, 6),
"premium_date": latest_date,
"premium_stats": {
"mean": round(premium_series.mean(), 6),
"std": round(premium_series.std(), 6),
"min": round(premium_series.min(), 6),
"max": round(premium_series.max(), 6),
"median": round(premium_series.median(), 6),
},
}
# ============================================================ # ============================================================
# API 路由 # API 路由
# ============================================================ # ============================================================
@@ -524,7 +562,12 @@ def index():
"crypto": ["BTC", "ETH"], "crypto": ["BTC", "ETH"],
}, },
"cache_config": get_cache_info(), "cache_config": get_cache_info(),
"ssh_status": "enabled" if ssh_config and ssh_config.get('enabled') else "disabled", "ssh": {
"status": "enabled" if ssh_config and ssh_config.get('enabled') else "disabled",
"host": ssh_config.get('host', '') if ssh_config else '',
"required_types": [t.value for t in UniversalDataFetcher.SSH_REQUIRED_TYPES],
"description": "港美股/加密货币数据获取需要 SSH 隧道",
},
}) })
@@ -700,28 +743,10 @@ def get_ohlcv():
if nav_df is not None and len(nav_df) > 0: if nav_df is not None and len(nav_df) > 0:
result['nav'] = dataframe_to_json(nav_df) result['nav'] = dataframe_to_json(nav_df)
# 添加溢价率序列 # 添加溢价率数据(使用抽取的函数)
if premium_series is not None and len(premium_series) > 0: premium_result = build_premium_result(premium_series)
premium_data = [ if premium_result:
{"date": date.strftime('%Y-%m-%d'), "premium": round(premium, 6)} result.update(premium_result)
for date, premium in premium_series.items()
]
result['premium_series'] = premium_data
# 最新溢价率
latest_premium = premium_series.iloc[-1]
latest_date = premium_series.index[-1].strftime('%Y-%m-%d')
result['latest_premium'] = round(latest_premium, 6)
result['premium_date'] = latest_date
# 溢价率统计
result['premium_stats'] = {
"mean": round(premium_series.mean(), 6),
"std": round(premium_series.std(), 6),
"min": round(premium_series.min(), 6),
"max": round(premium_series.max(), 6),
"median": round(premium_series.median(), 6),
}
except Exception as e: except Exception as e:
# 净值获取失败不影响主数据返回 # 净值获取失败不影响主数据返回
result['nav_error'] = str(e) result['nav_error'] = str(e)
@@ -840,30 +865,10 @@ def get_etf_nav():
"nav": dataframe_to_json(nav_df) if nav_df else {"data": [], "count": 0}, "nav": dataframe_to_json(nav_df) if nav_df else {"data": [], "count": 0},
} }
# 添加历史溢价率序列 # 添加溢价率数据(使用抽取的函数)
if premium_series is not None and len(premium_series) > 0: premium_result = build_premium_result(premium_series)
# 转换为日期-溢价率列表 if premium_result:
premium_data = [ result.update(premium_result)
{"date": date.strftime('%Y-%m-%d'), "premium": round(premium, 6)}
for date, premium in premium_series.items()
]
result['premium_series'] = premium_data
# 最新溢价率
latest_premium = premium_series.iloc[-1]
latest_date = premium_series.index[-1].strftime('%Y-%m-%d')
result['latest_premium'] = round(latest_premium, 6)
result['premium_date'] = latest_date
# 溢价率统计
result['premium_stats'] = {
"mean": round(premium_series.mean(), 6),
"std": round(premium_series.std(), 6),
"min": round(premium_series.min(), 6),
"max": round(premium_series.max(), 6),
"median": round(premium_series.median(), 6),
}
return jsonify(result) return jsonify(result)