fix: MA排序bug(用日期代替价格)+量价历史存储+deep_vol接入full_analysis+DB路径统一

This commit is contained in:
知微
2026-07-08 12:36:10 +08:00
parent 2762ddf3ae
commit 258b8871ef
3 changed files with 58 additions and 23 deletions
+24 -4
View File
@@ -223,8 +223,18 @@ def calc_moving_averages(klines: list, windows: list = [5, 10, 20, 60]) -> dict:
# 确保按时间正序(旧的在前)
closes = [k["close"] for k in klines]
# 检查是否倒序(最新的在前
if len(closes) >= 2 and closes[0] > closes[-1]:
# 使用日期判断顺序(不能用价格:下跌趋势下closes[0]>closes[-1]也会触发反转
is_reversed = False
if len(klines) >= 2:
d0 = klines[0].get("date", "")
d1 = klines[-1].get("date", "")
if d0 and d1:
from datetime import datetime
try:
is_reversed = datetime.strptime(d0, "%Y-%m-%d") > datetime.strptime(d1, "%Y-%m-%d")
except:
is_reversed = (closes[0] > closes[-1] * 1.5) if len(closes) >= 2 else False
if is_reversed:
closes = list(reversed(closes))
result = {}
@@ -314,8 +324,18 @@ def assess_trend(klines: list) -> dict:
return {"trend": "unknown", "strength": 0, "description": "数据不足"}
closes = [k["close"] for k in klines]
# 确保正序
if len(closes) >= 2 and closes[0] > closes[-1]:
# 确保正序(使用日期不用价格,避免下跌趋势中错误反转)
is_reversed = False
if len(klines) >= 2:
d0 = klines[0].get("date", "")
d1 = klines[-1].get("date", "")
if d0 and d1:
from datetime import datetime
try:
is_reversed = datetime.strptime(d0, "%Y-%m-%d") > datetime.strptime(d1, "%Y-%m-%d")
except:
is_reversed = (closes[0] > closes[-1] * 1.5) if len(closes) >= 2 else False
if is_reversed:
closes = list(reversed(closes))
n = len(closes)
+18 -10
View File
@@ -17,7 +17,9 @@ import urllib.error
from datetime import datetime, date, timedelta
from typing import Optional
DATA_DIR = "/home/hmo/MoFin/data"
from mofin_db import get_conn
DATA_DIR = "/home/hmo/web-dashboard/data"
HISTORY_PATH = os.path.join(DATA_DIR, "price_history.json")
# multi_tf_cache.json 已迁移到 DB (mtf_cache 表)
@@ -91,8 +93,7 @@ def _load_mtf_cache():
if _MTF_CACHE_DATA is not None:
return _MTF_CACHE_DATA
try:
import sqlite3
db = sqlite3.connect('/home/hmo/MoFin/data/mofin.db')
db = get_conn()
rows = db.execute("SELECT code, cache_json FROM mtf_cache").fetchall()
_MTF_CACHE_DATA = {}
for code, json_str in rows:
@@ -112,8 +113,7 @@ def _save_mtf_cache():
if _MTF_CACHE_DATA is None:
return
try:
import sqlite3
db = sqlite3.connect('/home/hmo/MoFin/data/mofin.db')
db = get_conn()
for code, data in _MTF_CACHE_DATA.items():
db.execute(
"INSERT OR REPLACE INTO mtf_cache (code, cache_json, updated_at) VALUES (?,?,datetime('now','localtime'))",
@@ -222,8 +222,8 @@ def calc_moving_averages(klines: list, windows: list = [5, 10, 20, 60]) -> dict:
return {f"ma{w}": None for w in windows}
# 确保按时间正序(旧的在前)
# 使用日期判断顺序(不能用价格:下跌趋势下closes[0]>closes[-1]也会触发反转)
closes = [k["close"] for k in klines]
# 使用日期判断顺序(不能用价格:下跌趋势下closes[0]>closes[-1]也会触发反转)
is_reversed = False
if len(klines) >= 2:
d0 = klines[0].get("date", "")
@@ -233,9 +233,7 @@ def calc_moving_averages(klines: list, windows: list = [5, 10, 20, 60]) -> dict:
try:
is_reversed = datetime.strptime(d0, "%Y-%m-%d") > datetime.strptime(d1, "%Y-%m-%d")
except:
# 日期格式不对时的fallback: 仅当首价显著高于末价才判定倒序(50%阈值)
is_reversed = (closes[0] > closes[-1] * 1.5) if len(closes) >= 2 else False
if is_reversed:
closes = list(reversed(closes))
@@ -326,8 +324,18 @@ def assess_trend(klines: list) -> dict:
return {"trend": "unknown", "strength": 0, "description": "数据不足"}
closes = [k["close"] for k in klines]
# 确保正序
if len(closes) >= 2 and closes[0] > closes[-1]:
# 确保正序(使用日期不用价格,避免下跌趋势中错误反转)
is_reversed = False
if len(klines) >= 2:
d0 = klines[0].get("date", "")
d1 = klines[-1].get("date", "")
if d0 and d1:
from datetime import datetime
try:
is_reversed = datetime.strptime(d0, "%Y-%m-%d") > datetime.strptime(d1, "%Y-%m-%d")
except:
is_reversed = (closes[0] > closes[-1] * 1.5) if len(closes) >= 2 else False
if is_reversed:
closes = list(reversed(closes))
n = len(closes)
+16 -9
View File
@@ -55,14 +55,7 @@ def _market_prefix(code):
def get_quote(code):
"""获取行情数据。DB 优先(price_monitor 维护),腾讯 API fallback"""
# DB 优先
try:
from mofin_db import get_price_from_db
p, chg = get_price_from_db(code)
if p: return {"code": code, "price": p, "change_pct": chg or 0}
except: pass
# Fallback: 腾讯 API
"""获取行情数据。先拿DB的价格和涨跌幅,再调腾讯API拿HLC全量数据"""
import time
_cache = get_quote.__dict__.get("_cache", {})
now = time.time()
@@ -70,6 +63,18 @@ def get_quote(code):
if cached and (now - cached["ts"]) < 60:
return cached["data"]
# 先从DB拿基础价格(快速,不阻塞)
db_price = None
db_chg = None
try:
from mofin_db import get_price_from_db
p, chg = get_price_from_db(code)
if p:
db_price, db_chg = p, chg
except:
pass
# 腾讯API获取全量HLC数据
raw = str(code).split("_")[0]
prefix = _market_prefix(code)
url = f"http://qt.gtimg.cn/q={prefix}{raw}"
@@ -77,6 +82,8 @@ def get_quote(code):
r = urllib.request.urlopen(url, timeout=5)
fields = r.read().decode("gbk").split('"')[1].split("~")
except Exception as e:
if db_price:
return {"code": code, "price": db_price, "change_pct": db_chg or 0}
return {"code": code, "error": str(e)}
def get(i):
@@ -465,7 +472,7 @@ def analyze_volume_deep(code):
import sqlite3
from pathlib import Path
DATA_DIR = Path(__file__).parent / "data"
DATA_DIR = Path(__file__).parent.parent / "data"
try:
conn = sqlite3.connect(str(DATA_DIR / "mofin.db"))
row = conn.execute("SELECT cache_json FROM mtf_cache WHERE code=?", (code,)).fetchone()