v1.9.0: ①自动化开关即时保存(切换即生效不回落) ②持仓跟踪推送方式(聚合一起发默认/分散发) ③行情数据增量延续到最新交易日(每小时自动+手动按钮)
This commit is contained in:
@@ -619,6 +619,8 @@ def api_settings_save():
|
||||
set_setting("tracking_enabled", _bool_str(track["tracking_enabled"]))
|
||||
if "tracking_notify" in track:
|
||||
set_setting("tracking_notify", _bool_str(track["tracking_notify"]))
|
||||
if "tracking_push_mode" in track:
|
||||
set_setting("tracking_push_mode", str(track["tracking_push_mode"]).strip().lower())
|
||||
# 静默期(各自动化任务独立配置)
|
||||
quiet = body.get("quiet") or {}
|
||||
for prefix in ("monitor", "tracking", "report"):
|
||||
@@ -786,6 +788,8 @@ def api_admin_stats():
|
||||
tables = ("stocks", "stock_daily", "news", "institutions", "inst_ratings",
|
||||
"fund_holdings", "watchlist", "analysis_cache", "analysis_history",
|
||||
"strategy_backtests", "market_index")
|
||||
latest_daily = query_one("SELECT MAX(date) d FROM stock_daily")
|
||||
latest_news = query_one("SELECT MAX(publish_date) d FROM news")
|
||||
return jsonify({
|
||||
"tables": {t: table_count(t) for t in tables},
|
||||
"vector": {
|
||||
@@ -794,6 +798,8 @@ def api_admin_stats():
|
||||
},
|
||||
"is_mock": IS_MOCK,
|
||||
"db": "stock_advisor.db",
|
||||
"latest_daily": (latest_daily or {}).get("d"),
|
||||
"latest_news": (latest_news or {}).get("d"),
|
||||
})
|
||||
|
||||
|
||||
@@ -814,6 +820,29 @@ def api_admin_reseed():
|
||||
return jsonify({"ok": True, "msg": "重灌任务已启动,可在数据管理页刷新查看进度"})
|
||||
|
||||
|
||||
@app.route("/api/admin/update-data", methods=["POST"])
|
||||
def api_admin_update_data():
|
||||
"""把行情/新闻/指数增量扩展到最新交易日(模拟数据延续),后台执行"""
|
||||
import threading
|
||||
|
||||
def run():
|
||||
try:
|
||||
from seed_data import extend_daily
|
||||
with open(os.path.join(LOG_DIR, "data_update.log"), "a") as f:
|
||||
f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 开始更新数据\n")
|
||||
res = extend_daily()
|
||||
with open(os.path.join(LOG_DIR, "data_update.log"), "a") as f:
|
||||
f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 完成: {res}\n")
|
||||
log.info("data extend done: %s", res)
|
||||
except Exception as e:
|
||||
log.exception("data extend fail")
|
||||
with open(os.path.join(LOG_DIR, "data_update.log"), "a") as f:
|
||||
f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 失败: {e}\n")
|
||||
|
||||
threading.Thread(target=run, daemon=True).start()
|
||||
return jsonify({"ok": True, "msg": "行情更新已启动(增量扩展到最新交易日),稍后刷新数据管理页查看"})
|
||||
|
||||
|
||||
@app.route("/api/admin/healthcheck")
|
||||
def api_admin_healthcheck():
|
||||
"""外部依赖连通性检查"""
|
||||
@@ -835,10 +864,35 @@ def api_admin_healthcheck():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import threading
|
||||
init_db()
|
||||
from engine.notifier import start_monitor
|
||||
from engine.agent import start_tracking
|
||||
start_monitor()
|
||||
start_tracking()
|
||||
# 行情自动更新器:每小时检查,若行情最新日期落后于最新交易日则增量扩展(模拟数据延续)
|
||||
class DataUpdater(threading.Thread):
|
||||
def __init__(self):
|
||||
super().__init__(daemon=True, name="data-updater")
|
||||
self._stop = threading.Event()
|
||||
|
||||
def run(self):
|
||||
log.info("行情自动更新器启动(每小时检查)")
|
||||
while not self._stop.is_set():
|
||||
try:
|
||||
import datetime as _dt
|
||||
last = query_one("SELECT MAX(date) d FROM stock_daily")
|
||||
today = _dt.date.today()
|
||||
while today.weekday() >= 5:
|
||||
today -= _dt.timedelta(days=1)
|
||||
if not last or last["d"] < today.isoformat():
|
||||
from seed_data import extend_daily
|
||||
res = extend_daily()
|
||||
log.info("行情自动扩展: %s", res)
|
||||
except Exception as e:
|
||||
log.warning("data updater error: %s", e)
|
||||
self._stop.wait(3600)
|
||||
|
||||
DataUpdater().start()
|
||||
print(f"✅ {SERVICE_NAME} 启动: http://0.0.0.0:{SERVICE_PORT}")
|
||||
app.run(host=SERVICE_HOST, port=SERVICE_PORT, threaded=True)
|
||||
Reference in New Issue
Block a user