39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
"""
|
|
data/universe.py - 종목 풀 갱신 (08:30)
|
|
"""
|
|
import json, os, logging
|
|
from app.config import MAX_UNIVERSE
|
|
|
|
logger = logging.getLogger(__name__)
|
|
CACHE_PATH = "data/universe_cache.json"
|
|
|
|
|
|
async def update_universe(kis_client, ai_context: dict) -> list:
|
|
"""거래량 순위 기반 유니버스 갱신 + AI 필터"""
|
|
try:
|
|
rank = await kis_client.get_volume_rank(top_n=MAX_UNIVERSE * 2)
|
|
tickers = [r["ticker"] for r in rank]
|
|
|
|
blacklist = ai_context.get("blacklist_tickers", [])
|
|
tickers = [t for t in tickers if t not in blacklist]
|
|
|
|
boosted = ai_context.get("boosted_tickers", [])
|
|
tickers = (
|
|
[t for t in boosted if t in tickers] +
|
|
[t for t in tickers if t not in boosted]
|
|
)[:MAX_UNIVERSE]
|
|
|
|
os.makedirs(os.path.dirname(CACHE_PATH), exist_ok=True)
|
|
with open(CACHE_PATH, "w") as f:
|
|
json.dump({"tickers": tickers, "boosted": boosted}, f)
|
|
|
|
logger.info(f"유니버스 갱신: {len(tickers)}종목 (부스트: {len(boosted)})")
|
|
return tickers
|
|
|
|
except Exception as e:
|
|
logger.error(f"유니버스 갱신 실패: {e}")
|
|
if os.path.exists(CACHE_PATH):
|
|
with open(CACHE_PATH) as f:
|
|
return json.load(f).get("tickers", [])
|
|
return []
|