레디스 및 구조 수정중

This commit is contained in:
2026-02-25 16:56:34 +09:00
parent 89f54bae55
commit ec02f27200
10 changed files with 428 additions and 131 deletions

View File

@@ -4,10 +4,11 @@
아침 배치(batch_daily_analysis)와 장중 배치(batch_intraday_analysis)가 공유하는
초기화 함수. 각 배치 스크립트가 자신의 AsyncSession을 전달해 사용한다.
[승률 개선]
- scanner_tickers가 제공되면 해당 종목을 워치리스트 앞쪽에 우선 배치
- 나머지 슬롯은 score 상위 순으로 채움
- added_reason: "scanner_signal" | "morning_batch" 로 구분되어 UI 에서도 식별 가능
[.env 설정]
WATCHLIST_INIT_SIZE (아침 배치 초기화 종목 수)
WATCHLIST_MAX_SIZE (최대 관리 종목 수)
WATCHLIST_ENTRY_SCORE (장중 신규 진입 기준 점수)
WATCHLIST_EXIT_SCORE (장중 제거 기준 점수)
"""
from datetime import datetime, date
from typing import Optional
@@ -17,17 +18,12 @@ import pytz
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.config import settings
from app.models.models import WatchlistStock, StockAnalysis
logger = logging.getLogger(__name__)
# 분석종목 관련 상수
WATCHLIST_INIT_SIZE: int = 50 # 아침 배치 초기화 종목 수
WATCHLIST_MAX_SIZE: int = 100 # 최대 관리 종목 수
WATCHLIST_ENTRY_SCORE: int = 60 # 장중 신규 진입 기준 점수
WATCHLIST_EXIT_SCORE: int = 20 # 장중 제거 기준 점수
# 스캐너 신호 종목에 배정하는 최대 슬롯 수 (WATCHLIST_INIT_SIZE 중 이 수만큼 우선)
# 스캐너 신호 종목에 배정하는 최대 슬롯 수 (settings.WATCHLIST_INIT_SIZE 중 이 수만큼 우선)
SCANNER_PRIORITY_SLOTS: int = 20
@@ -68,7 +64,7 @@ async def initialize_watchlist(
select(StockAnalysis.stock_code, StockAnalysis.stock_name, StockAnalysis.score)
.where(StockAnalysis.analysis_date == analysis_date)
.order_by(StockAnalysis.score.desc())
.limit(WATCHLIST_INIT_SIZE)
.limit(settings.WATCHLIST_INIT_SIZE)
)
top_stocks = result.all()
top_codes = {row.stock_code for row in top_stocks}
@@ -119,7 +115,7 @@ async def initialize_watchlist(
scanner_added += 1
# --- 3순위: 나머지 슬롯 — score 상위 순 ---
remaining = WATCHLIST_INIT_SIZE - added
remaining = settings.WATCHLIST_INIT_SIZE - added
for row in top_stocks:
if remaining <= 0:
break