chore: deployed JSON retirement
This commit is contained in:
-40644
File diff suppressed because it is too large
Load Diff
@@ -65,11 +65,6 @@ class MoConfig:
|
|||||||
warnings.warn("watchlist_path is deprecated — use mo_data.read_watchlist() for DB data", DeprecationWarning, stacklevel=2)
|
warnings.warn("watchlist_path is deprecated — use mo_data.read_watchlist() for DB data", DeprecationWarning, stacklevel=2)
|
||||||
return Path()
|
return Path()
|
||||||
|
|
||||||
@property
|
|
||||||
def price_events_path(self) -> Path:
|
|
||||||
"""⚠️ 已废弃!数据在 mofin.db price_events 表。"""
|
|
||||||
return self.data_dir / "price_events.json"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def live_prices_path(self) -> Path:
|
def live_prices_path(self) -> Path:
|
||||||
"""⚠️ DEPRECATED: 实时价格已迁移到 mofin_db.live_prices 表。"""
|
"""⚠️ DEPRECATED: 实时价格已迁移到 mofin_db.live_prices 表。"""
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
|
|
||||||
DATA_DIR = Path(__file__).parent / "data"
|
DATA_DIR = Path("/home/hmo/MoFin/data") # 绝对路径:全系统唯一权威数据目录
|
||||||
DB_PATH = DATA_DIR / "mofin.db"
|
DB_PATH = DATA_DIR / "mofin.db"
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════
|
||||||
|
|||||||
@@ -934,29 +934,6 @@ def build_report():
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# price_events 特殊处理:活跃存储是 price_events.json(price_monitor 实时写入),
|
|
||||||
# DB 表是旧遗留。读 JSON 最后一条事件的时间。
|
|
||||||
try:
|
|
||||||
_pe_path = Path("/home/hmo/web-dashboard/data/price_events.json")
|
|
||||||
if _pe_path.exists():
|
|
||||||
_pe = json.loads(_pe_path.read_text(encoding="utf-8"))
|
|
||||||
_items = _pe if isinstance(_pe, list) else _pe.get("events", [])
|
|
||||||
if _items:
|
|
||||||
_last = _items[-1]
|
|
||||||
_ts = _last.get("timestamp") or _last.get("created_at") or ""
|
|
||||||
_dt = datetime.fromisoformat(str(_ts).replace("Z", ""))
|
|
||||||
_age = (now - _dt).total_seconds() / 3600
|
|
||||||
# 替换 db_freshness 里 price_events 那条(DB 旧数据)
|
|
||||||
db_freshness = [f for f in db_freshness if f["table"] != "price_events"]
|
|
||||||
db_freshness.append({
|
|
||||||
"table": "price_events.json", "label": "价格事件",
|
|
||||||
"last_record": _dt.strftime("%m-%d %H:%M"),
|
|
||||||
"age_hours": round(_age, 1),
|
|
||||||
"warn": _age > 24,
|
|
||||||
})
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# ── Tab 3: 流程/cron映射 ──
|
# ── Tab 3: 流程/cron映射 ──
|
||||||
pipelines = []
|
pipelines = []
|
||||||
for j in sorted(cron_jobs, key=lambda x: x.get("name","")):
|
for j in sorted(cron_jobs, key=lambda x: x.get("name","")):
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from mo_data import read_decisions
|
|||||||
|
|
||||||
BREACH_PATH = "/home/hmo/.hermes/zone_breach.json"
|
BREACH_PATH = "/home/hmo/.hermes/zone_breach.json"
|
||||||
STATE_PATH = "/home/hmo/.hermes/price_trigger_state.json"
|
STATE_PATH = "/home/hmo/.hermes/price_trigger_state.json"
|
||||||
EVENTS_PATH = "/home/hmo/web-dashboard/data/price_events.json"
|
|
||||||
|
|
||||||
# DB 模块(同步实时价到 mofin.db)
|
# DB 模块(同步实时价到 mofin.db)
|
||||||
sys.path.insert(0, "/home/hmo/MoFin")
|
sys.path.insert(0, "/home/hmo/MoFin")
|
||||||
@@ -319,27 +318,14 @@ def save_breaches(data):
|
|||||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
|
||||||
def load_events():
|
|
||||||
try:
|
|
||||||
with open(EVENTS_PATH) as f:
|
|
||||||
return json.load(f)
|
|
||||||
except:
|
|
||||||
return {"events": []}
|
|
||||||
|
|
||||||
|
|
||||||
def save_events(events):
|
|
||||||
os.makedirs(os.path.dirname(EVENTS_PATH), exist_ok=True)
|
|
||||||
with open(EVENTS_PATH, 'w') as f:
|
|
||||||
json.dump(events, f, ensure_ascii=False, indent=2)
|
|
||||||
|
|
||||||
|
|
||||||
def record_event(code, name, event_type, price, trigger_value, event_label=""):
|
def record_event(code, name, event_type, price, trigger_value, event_label=""):
|
||||||
"""记录一次价格触发事件 — 双写:DB price_events 表(权威)+ price_events.json(遗留读取方兼容)"""
|
"""记录一次价格触发事件到 DB price_events 表(唯一权威存储,JSON 已退役)。
|
||||||
now = datetime.now().isoformat()
|
|
||||||
date_str = datetime.now().strftime("%Y-%m-%d")
|
price_events.code 有 FK -> stocks(code),未注册的股票(新候选/港股)
|
||||||
|
先注册再写事件,否则 FK 失败事件丢失。
|
||||||
|
"""
|
||||||
|
now = datetime.now().isoformat()
|
||||||
|
|
||||||
# 1. 写 DB 表(权威存储)。price_events.code 有 FK -> stocks(code),
|
|
||||||
# 未注册的股票(新候选/港股)会先注册再写事件,否则 FK 失败事件丢失。
|
|
||||||
if HAS_DB:
|
if HAS_DB:
|
||||||
try:
|
try:
|
||||||
from mofin_db import get_conn, write_price_event
|
from mofin_db import get_conn, write_price_event
|
||||||
@@ -355,22 +341,6 @@ def record_event(code, name, event_type, price, trigger_value, event_label=""):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[price_events DB写入失败] {e}", file=sys.stderr)
|
print(f"[price_events DB写入失败] {e}", file=sys.stderr)
|
||||||
|
|
||||||
# 2. 写 JSON(遗留读取方:mo_config/strategy_feedback/system_health_check 还在读)
|
|
||||||
events = load_events()
|
|
||||||
events["events"].append({
|
|
||||||
"code": code,
|
|
||||||
"name": name,
|
|
||||||
"event_type": event_type, # entry_zone, stop_loss, take_profit, exit_zone
|
|
||||||
"price": round(price, 2),
|
|
||||||
"trigger_value": trigger_value,
|
|
||||||
"event_label": event_label,
|
|
||||||
"timestamp": now,
|
|
||||||
"date": date_str,
|
|
||||||
})
|
|
||||||
# 保留最近10000条
|
|
||||||
events["events"] = events["events"][-10000:]
|
|
||||||
save_events(events)
|
|
||||||
|
|
||||||
|
|
||||||
def get_trigger_zones(trigger):
|
def get_trigger_zones(trigger):
|
||||||
"""返回该trigger所有可监控的区间列表,跳过已执行的batch"""
|
"""返回该trigger所有可监控的区间列表,跳过已执行的batch"""
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ from mo_data import read_decisions
|
|||||||
|
|
||||||
DATA_DIR = Path(__file__).parent.parent / "data"
|
DATA_DIR = Path(__file__).parent.parent / "data"
|
||||||
ACCURACY_PATH = DATA_DIR / "accuracy_stats.json"
|
ACCURACY_PATH = DATA_DIR / "accuracy_stats.json"
|
||||||
EVENTS_PATH = DATA_DIR / "price_events.json"
|
|
||||||
FEEDBACK_PATH = DATA_DIR / "strategy_feedback.json"
|
FEEDBACK_PATH = DATA_DIR / "strategy_feedback.json"
|
||||||
|
|
||||||
|
|
||||||
@@ -174,15 +173,16 @@ def generate_adjustment(decision, phase_check, accuracy_trend):
|
|||||||
|
|
||||||
def run():
|
def run():
|
||||||
decisions = read_decisions()
|
decisions = read_decisions()
|
||||||
# 优先从 SQLite 读取价格事件
|
# 价格事件:只从 DB price_events 表读(JSON 已退役)
|
||||||
try:
|
try:
|
||||||
from mofin_db import get_conn, query_price_events
|
from mofin_db import get_conn, query_price_events
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
pe_rows = query_price_events(conn, limit=50000)
|
pe_rows = query_price_events(conn, limit=50000)
|
||||||
conn.close()
|
conn.close()
|
||||||
events = {"events": pe_rows}
|
events = {"events": pe_rows}
|
||||||
except Exception:
|
except Exception as e:
|
||||||
events = load_json(EVENTS_PATH, {"events": []})
|
print(f"[strategy_feedback] DB价格事件读取失败: {e}", file=sys.stderr)
|
||||||
|
events = {"events": []}
|
||||||
accuracy_stats = load_json(ACCURACY_PATH, {})
|
accuracy_stats = load_json(ACCURACY_PATH, {})
|
||||||
|
|
||||||
accuracy_trend = compute_accuracy_trend(accuracy_stats)
|
accuracy_trend = compute_accuracy_trend(accuracy_stats)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from datetime import datetime, timedelta
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
DATA_DIR = Path("/home/hmo/web-dashboard/data")
|
DATA_DIR = Path("/home/hmo/web-dashboard/data")
|
||||||
EVENTS_PATH = DATA_DIR / "price_events.json"
|
|
||||||
EVALUATION_PATH = DATA_DIR / "evaluation.json"
|
EVALUATION_PATH = DATA_DIR / "evaluation.json"
|
||||||
ACCURACY_PATH = DATA_DIR / "accuracy_stats.json"
|
ACCURACY_PATH = DATA_DIR / "accuracy_stats.json"
|
||||||
CRON_JOBS = "/home/hmo/.hermes/profiles/position-analyst/cron/jobs.json"
|
CRON_JOBS = "/home/hmo/.hermes/profiles/position-analyst/cron/jobs.json"
|
||||||
@@ -104,10 +103,9 @@ def run():
|
|||||||
lines.append(check(False, "MoFin DB 数据读取失败"))
|
lines.append(check(False, "MoFin DB 数据读取失败"))
|
||||||
warn_count += 3
|
warn_count += 3
|
||||||
|
|
||||||
# 仍为 JSON 文件的检查
|
# 仍为 JSON 文件的检查(price_events 已迁移到 DB 表,不在此列)
|
||||||
files = {
|
files = {
|
||||||
"market.json": DATA_DIR / "market.json",
|
"market.json": DATA_DIR / "market.json",
|
||||||
"price_events.json": EVENTS_PATH,
|
|
||||||
"evaluation.json": EVALUATION_PATH,
|
"evaluation.json": EVALUATION_PATH,
|
||||||
"accuracy_stats.json": ACCURACY_PATH,
|
"accuracy_stats.json": ACCURACY_PATH,
|
||||||
}
|
}
|
||||||
@@ -121,7 +119,7 @@ def run():
|
|||||||
else:
|
else:
|
||||||
ok_count += 1
|
ok_count += 1
|
||||||
|
|
||||||
# 4. 价格事件统计
|
# 4. 价格事件统计(只读 DB price_events 表,JSON 已退役)
|
||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append("【价格事件】")
|
lines.append("【价格事件】")
|
||||||
try:
|
try:
|
||||||
@@ -130,10 +128,12 @@ def run():
|
|||||||
ev_list = query_price_events(conn, limit=50000)
|
ev_list = query_price_events(conn, limit=50000)
|
||||||
today_events = query_price_events_by_date(conn, now.strftime("%Y-%m-%d"))
|
today_events = query_price_events_by_date(conn, now.strftime("%Y-%m-%d"))
|
||||||
conn.close()
|
conn.close()
|
||||||
except Exception:
|
except Exception as e:
|
||||||
events = load_json(EVENTS_PATH, {"events": []})
|
ev_list = []
|
||||||
ev_list = events.get("events", [])
|
today_events = []
|
||||||
today_events = [e for e in ev_list if e.get("date") == now.strftime("%Y-%m-%d")]
|
lines.append(check(False, f"DB价格事件读取失败: {str(e)[:60]}"))
|
||||||
|
issues.append(f"price_events DB读取失败: {str(e)[:60]}")
|
||||||
|
warn_count += 1
|
||||||
lines.append(check(len(ev_list) > 0, f"历史事件: {len(ev_list)}条"))
|
lines.append(check(len(ev_list) > 0, f"历史事件: {len(ev_list)}条"))
|
||||||
lines.append(check(len(today_events) > 0, f"今日事件: {len(today_events)}条"))
|
lines.append(check(len(today_events) > 0, f"今日事件: {len(today_events)}条"))
|
||||||
if len(ev_list) == 0:
|
if len(ev_list) == 0:
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
|
|
||||||
DATA_DIR = Path(__file__).parent / "data"
|
DATA_DIR = Path("/home/hmo/MoFin/data") # 绝对路径:全系统唯一权威数据目录
|
||||||
DB_PATH = DATA_DIR / "mofin.db"
|
DB_PATH = DATA_DIR / "mofin.db"
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
|
|
||||||
DATA_DIR = Path(__file__).parent / "data"
|
DATA_DIR = Path("/home/hmo/MoFin/data") # 绝对路径:全系统唯一权威数据目录
|
||||||
DB_PATH = DATA_DIR / "mofin.db"
|
DB_PATH = DATA_DIR / "mofin.db"
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════
|
||||||
|
|||||||
Reference in New Issue
Block a user