feat: eliminate duplicate price fetches — stale_push_wlin + per_stock_reassess now read from DB instead of self-pulling Tencent API
This commit is contained in:
@@ -41,41 +41,35 @@ def main():
|
||||
# Always fetch live price for accurate reassessment
|
||||
price = 0
|
||||
try:
|
||||
import urllib.request
|
||||
# 价格从 DB 读取(price_monitor 每2分钟更新,唯一价格入口)
|
||||
code_raw = entry.get("code", "")
|
||||
# 港股5位代码(含0开头)→ 前缀hk
|
||||
if len(code_raw) == 5 and code_raw[0] in '01':
|
||||
prefix = "hk"
|
||||
price = 0
|
||||
import sqlite3
|
||||
db = sqlite3.connect('/home/hmo/web-dashboard/data/mofin.db')
|
||||
db.row_factory = sqlite3.Row
|
||||
row = db.execute("SELECT price FROM holdings WHERE code=? AND is_active=1", (code_raw,)).fetchone()
|
||||
if not row:
|
||||
row = db.execute("SELECT price FROM watchlist_stocks WHERE code=? AND is_active=1", (code_raw,)).fetchone()
|
||||
if not row:
|
||||
row = db.execute("SELECT price FROM holding_strategies WHERE code=? AND status='active' ORDER BY updated_at DESC LIMIT 1", (code_raw,)).fetchone()
|
||||
if row:
|
||||
price = row['price'] or 0
|
||||
db.close()
|
||||
if price > 0:
|
||||
print(f" 实时价: {price} (来自DB)")
|
||||
else:
|
||||
sym_map = {"6":"sh","5":"sh","0":"sz","3":"sz"}
|
||||
for k, v in sym_map.items():
|
||||
if code_raw.startswith(k):
|
||||
prefix = v
|
||||
break
|
||||
if not prefix:
|
||||
prefix = "sz"
|
||||
url = f"http://qt.gtimg.cn/q={prefix}{code_raw}"
|
||||
resp = urllib.request.urlopen(url, timeout=5)
|
||||
text = resp.read().decode("gbk")
|
||||
fields = text.split('"')[1].split("~")
|
||||
price = float(fields[3]) if fields[3] else 0
|
||||
print(f" 实时价: {price} {'(港股HKD)' if len(code_raw) == 5 and code_raw[0] in '01' else ''}")
|
||||
except Exception as e:
|
||||
print(f" 实时价获取失败: {e}", file=sys.stderr)
|
||||
# Try portfolio.json as fallback (price_monitor keeps live prices)
|
||||
try:
|
||||
# fallback to portfolio.json
|
||||
with open("/home/hmo/web-dashboard/data/portfolio.json") as _pf:
|
||||
_pf_data = json.load(_pf)
|
||||
for _h in _pf_data.get("holdings", []):
|
||||
if _h["code"] == code_raw:
|
||||
price = float(_h.get("price", 0))
|
||||
print(f" 从portfolio.json取实时价: {price}")
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
if price == 0:
|
||||
if price <= 0:
|
||||
price = entry.get("current_price") or entry.get("price") or 0
|
||||
except Exception as e:
|
||||
print(f" 价格获取失败: {e}", file=sys.stderr)
|
||||
price = entry.get("current_price") or entry.get("price") or 0
|
||||
print(f" fallback到存储价: {price}", file=sys.stderr)
|
||||
|
||||
# Price diff debounce: skip reassessment if price changed < 1% since last update
|
||||
last_price = entry.get("last_reassessed_price", 0)
|
||||
|
||||
@@ -74,18 +74,30 @@ from stock_scorer import score_future_outlook, is_hk_stock, settlement_delay_not
|
||||
|
||||
# ── 趋势检查 ────────────────────────────────────────────────────
|
||||
def fetch_trend_data(code):
|
||||
"""取均线数据判断趋势状态。返回 (current_price, ma5, trend_label) 或 None"""
|
||||
"""取均线数据判断趋势状态。价格从 DB 读取(price_monitor 唯一入口)。返回 (current_price, ma5, trend_label) 或 None"""
|
||||
# 价格从 DB 读取,不再自拉腾讯 API
|
||||
current = 0
|
||||
try:
|
||||
prefix = "sh" if code.startswith(('60','68','51','56','50')) else "sz" if code.startswith(('00','30','15')) else "hk"
|
||||
url = f"http://qt.gtimg.cn/q={prefix}{code}"
|
||||
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
|
||||
resp = urlopen(req, timeout=5).read().decode('gbk')
|
||||
fld = resp.split('=')[1].strip().strip('"').strip(';').split('~')
|
||||
current = float(fld[3]) if len(fld) > 3 else 0
|
||||
except:
|
||||
import sqlite3
|
||||
db = sqlite3.connect('/home/hmo/web-dashboard/data/mofin.db')
|
||||
db.row_factory = sqlite3.Row
|
||||
row = db.execute("SELECT price FROM holdings WHERE code=? AND is_active=1", (code,)).fetchone()
|
||||
if not row:
|
||||
row = db.execute("SELECT price FROM watchlist_stocks WHERE code=? AND is_active=1", (code,)).fetchone()
|
||||
if not row:
|
||||
row = db.execute("SELECT price FROM holding_strategies WHERE code=? AND status='active' ORDER BY updated_at DESC LIMIT 1", (code,)).fetchone()
|
||||
if row:
|
||||
current = row['price'] or 0
|
||||
db.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if current <= 0:
|
||||
return None
|
||||
|
||||
# K线数据仍从腾讯取(均线计算需要历史K线,DB 里 stock_daily 表有但不一定有最新数据)
|
||||
try:
|
||||
prefix = "sh" if code.startswith(('60','68','51','56','50')) else "sz" if code.startswith(('00','30','15')) else "hk"
|
||||
url = f"http://ifzq.gtimg.cn/appstock/app/fqkline/get?param={prefix}{code},day,,,30,qfq"
|
||||
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
|
||||
resp = urlopen(req, timeout=5).read().decode('utf-8')
|
||||
|
||||
Reference in New Issue
Block a user