fix: TradingView K线图表并修复品种推荐为空。

- 行情页改用 Lightweight Charts 标准蜡烛图(红跌绿涨)
- 修复 fee_rates 缺 source 列导致推荐刷新失败
- 空缓存自动重试,持仓页实时兜底计算推荐列表

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-25 12:33:49 +08:00
parent 074551490f
commit 32f1fa2c66
8 changed files with 458 additions and 527 deletions
+32 -5
View File
@@ -2,12 +2,16 @@
from __future__ import annotations
import json
import logging
import math
from datetime import datetime
from typing import Callable, Optional
from fee_specs import ensure_fee_rates_schema
from product_recommend import list_product_recommendations
logger = logging.getLogger(__name__)
RECOMMEND_CACHE_SQL = """
CREATE TABLE IF NOT EXISTS product_recommend_cache (
id INTEGER PRIMARY KEY CHECK (id = 1),
@@ -34,6 +38,22 @@ def rows_missing_max_lots(rows: list[dict]) -> bool:
return any("max_lots" not in r for r in rows)
def recommend_cache_needs_refresh(
cached: dict,
*,
capital: float = 0.0,
) -> bool:
"""是否需要重新拉行情计算推荐列表。"""
if recommend_cache_stale(cached.get("updated_at")):
return True
rows = cached.get("rows") or []
if rows_missing_max_lots(rows):
return True
if float(capital or 0) > 0 and not rows:
return True
return False
def enrich_recommend_rows(
rows: list[dict],
capital: float,
@@ -81,10 +101,19 @@ def refresh_recommend_cache(
) -> list[dict]:
"""后台拉行情、筛选并写入数据库。"""
ensure_recommend_tables(conn)
ensure_fee_rates_schema(conn)
all_rows = list_product_recommendations(
capital, quote_fn, max_margin_pct=max_margin_pct, trading_mode=trading_mode,
)
rows = filter_affordable_recommendations(all_rows)
if not rows and float(capital or 0) > 0:
logger.warning(
"recommend refresh: 0 affordable rows capital=%.2f total=%d no_price=%d blocked=%d",
float(capital or 0),
len(all_rows),
sum(1 for r in all_rows if r.get("status") == "no_price"),
sum(1 for r in all_rows if r.get("status") == "blocked"),
)
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
conn.execute(
"""INSERT INTO product_recommend_cache (id, capital, rows_json, updated_at)
@@ -142,9 +171,7 @@ def recommend_payload(
pct = max(1.0, min(100.0, float(max_margin_pct or 30.0)))
payload["capital"] = cap
payload["max_margin_pct"] = pct
payload["rows"] = enrich_recommend_rows(
payload.get("rows") or [],
cap,
max_margin_pct=pct,
)
rows = payload.get("rows") or []
payload["rows"] = enrich_recommend_rows(rows, cap, max_margin_pct=pct)
payload["needs_refresh"] = recommend_cache_needs_refresh(payload, capital=cap)
return payload