feat: 量化模型迁移——K线获取(日/分钟)+多因子打分+IC自适应微调+推荐卡推送/REST/前端

This commit is contained in:
lookt
2026-09-15 21:18:11 +08:00
parent d178653c89
commit 419b0af1f8
6 changed files with 804 additions and 2 deletions
+35 -1
View File
@@ -7,6 +7,8 @@ Linux 服务器常驻运行: python -m src.web.server (或 systemd,见
import asyncio
import json
import os
import threading
import time
from collections import deque
from pathlib import Path
@@ -17,6 +19,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
from src.realtime.collector import TimelineCollector # noqa: E402
from src.analysis.event_impact import EventImpactService # noqa: E402
from src.quant.engine import QuantEngine # noqa: E402
PORT = int(os.environ.get('PORT', '8100'))
ROOT = Path(__file__).resolve().parent.parent.parent
@@ -58,7 +61,25 @@ async def collector_task(_app):
await asyncio.sleep(60)
task = asyncio.create_task(poll())
_app['impact'] = collector.impact
# 量化引擎:K线刷新 + 自适应打分 + 推荐卡推送
quant = QuantEngine(emit=lambda rec: loop.call_soon_threadsafe(
asyncio.ensure_future, broadcast(rec)), db_path=str(ROOT / 'data' / 'a_stock.db'))
_app['quant'] = quant
quant.start()
def _quant_loops():
while True:
try:
time.sleep(SCORING_INTERVAL_S)
quant.run_scoring_and_push()
except Exception as e:
print('[quant-loop]', e, flush=True)
time.sleep(60)
threading.Thread(target=_quant_loops, daemon=True, name='quant-scoring').start()
task = asyncio.create_task(poll())
# 启动即推最近历史(从 jsonl 恢复)
feed = ROOT / 'data' / 'realtime_feed.jsonl'
if feed.exists():
@@ -83,6 +104,17 @@ async def recent_events(_request):
return web.json_response({'events': list(recent)})
async def quant_recommendations(_request):
q = _request.app['quant']
return web.json_response({'ts': q.last_scored_at,
'list': (q.last_ranking or [])[:50]})
async def quant_weights(_request):
q = _request.app['quant']
return web.json_response(q.weights_store.load())
async def impact_history(_request):
collector = _request.app['impact']
return web.json_response({'events': collector.history(20)})
@@ -114,6 +146,8 @@ def build_app():
app.router.add_get('/api/recent', recent_events)
app.router.add_get('/api/stats', stats)
app.router.add_get('/api/impact', impact_history)
app.router.add_get('/api/quant/recommendations', quant_recommendations)
app.router.add_get('/api/quant/weights', quant_weights)
app.router.add_get('/ws', ws_handler)
app.cleanup_ctx.append(collector_task)
return app