배치 수정
This commit is contained in:
@@ -331,6 +331,72 @@ async def day_trade_scheduler():
|
||||
raise
|
||||
|
||||
|
||||
async def krx_data_collector_scheduler():
|
||||
"""장 종료 후 KRX 일봉 데이터 자동 수집 스케줄러.
|
||||
|
||||
매일 15:40 KST 이후 collect_all(update_mode=True) 를 1회 실행.
|
||||
이미 오늘 수집 완료된 경우 다음 날까지 스킵.
|
||||
"""
|
||||
import pytz as _pytz
|
||||
from datetime import datetime as _dt, date as _date
|
||||
|
||||
_KST = _pytz.timezone("Asia/Seoul")
|
||||
_last_collected: _date | None = None
|
||||
|
||||
await asyncio.sleep(30) # 부팅 안정화
|
||||
logger.info("📅 KRX data collector scheduler started (daily after 15:40 KST)")
|
||||
|
||||
try:
|
||||
while True:
|
||||
now_kst = _dt.now(_KST)
|
||||
today = now_kst.date()
|
||||
|
||||
# 오늘 이미 수집했으면 자정까지 대기
|
||||
if _last_collected == today:
|
||||
# 다음 날 16:00까지 남은 초 계산
|
||||
from datetime import timedelta as _td
|
||||
tomorrow_16 = _KST.localize(
|
||||
_dt(today.year, today.month, today.day, 16, 0, 0)
|
||||
) + _td(days=1)
|
||||
sleep_sec = (tomorrow_16 - now_kst).total_seconds()
|
||||
logger.info(f"📅 KRX 오늘 수집 완료. 다음 수집까지 {sleep_sec/3600:.1f}시간 대기")
|
||||
await asyncio.sleep(max(sleep_sec, 60))
|
||||
continue
|
||||
|
||||
# 15:40 이전이면 대기
|
||||
collect_hour, collect_min = 15, 40
|
||||
if (now_kst.hour, now_kst.minute) < (collect_hour, collect_min):
|
||||
# 오늘 15:40까지 남은 초
|
||||
target = _KST.localize(
|
||||
_dt(today.year, today.month, today.day, collect_hour, collect_min, 0)
|
||||
)
|
||||
sleep_sec = (target - now_kst).total_seconds()
|
||||
if sleep_sec > 0:
|
||||
logger.info(f"📅 KRX 수집 대기 중... 15:40까지 {sleep_sec/60:.0f}분 남음")
|
||||
await asyncio.sleep(min(sleep_sec, 1800)) # 최대 30분마다 재확인
|
||||
continue
|
||||
|
||||
# 주말(토/일)은 스킵하고 다음 날 재확인
|
||||
if today.weekday() >= 5:
|
||||
await asyncio.sleep(3600)
|
||||
continue
|
||||
|
||||
# 수집 실행
|
||||
try:
|
||||
logger.info("📥 [KRX] 일봉 데이터 증분 수집 시작 (update mode)...")
|
||||
from collect_krx_data import collect_all
|
||||
await collect_all(update_mode=True)
|
||||
_last_collected = today
|
||||
logger.info("✅ [KRX] 일봉 데이터 수집 완료")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ [KRX] 데이터 수집 실패: {e}", exc_info=True)
|
||||
await asyncio.sleep(1800) # 실패 시 30분 후 재시도
|
||||
|
||||
except asyncio.CancelledError:
|
||||
logger.info("⏹️ KRX data collector scheduler stopped")
|
||||
raise
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""애플리케이션 시작/종료 시 실행될 코드"""
|
||||
@@ -428,6 +494,7 @@ async def lifespan(app: FastAPI):
|
||||
app.state.auto_trade_task = asyncio.create_task(auto_trade_scheduler())
|
||||
app.state.batch_analysis_task = asyncio.create_task(batch_analysis_scheduler())
|
||||
app.state.day_trade_task = asyncio.create_task(day_trade_scheduler())
|
||||
app.state.krx_collector_task = asyncio.create_task(krx_data_collector_scheduler())
|
||||
|
||||
# KIS 실시간 스트림 시작 (설정으로 제어 가능)
|
||||
if settings.KIS_WS_ENABLED:
|
||||
@@ -445,6 +512,7 @@ async def lifespan(app: FastAPI):
|
||||
"auto_trade_task",
|
||||
"batch_analysis_task",
|
||||
"day_trade_task",
|
||||
"krx_collector_task",
|
||||
"db_worker_task",
|
||||
"kis_stream_task",
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user