feat: 量化模型迁移——K线获取(日/分钟)+多因子打分+IC自适应微调+推荐卡推送/REST/前端
This commit is contained in:
+35
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user