feat(stock-lab): /run mode=auto 공휴일·주말 skipped_holiday 처리

This commit is contained in:
2026-05-12 13:49:45 +09:00
parent 50e811c5dd
commit c4cb18a25c
2 changed files with 42 additions and 0 deletions

View File

@@ -17,6 +17,29 @@ from .registry import NODE_REGISTRY, GATE_REGISTRY
router = APIRouter(prefix="/api/stock/screener") router = APIRouter(prefix="/api/stock/screener")
import json as _json
import pathlib as _pathlib
_HOLIDAYS_CACHE = None
def _holidays():
global _HOLIDAYS_CACHE
if _HOLIDAYS_CACHE is None:
path = _pathlib.Path(__file__).resolve().parent.parent / "holidays.json"
try:
with path.open(encoding="utf-8") as f:
data = _json.load(f)
_HOLIDAYS_CACHE = set(data) if isinstance(data, list) else set(data.keys())
except FileNotFoundError:
_HOLIDAYS_CACHE = set()
return _HOLIDAYS_CACHE
def _is_holiday(d: dt.date) -> bool:
return d.weekday() >= 5 or d.isoformat() in _holidays()
def _db_path() -> str: def _db_path() -> str:
return os.environ.get("STOCK_DB_PATH", "/app/data/stock.db") return os.environ.get("STOCK_DB_PATH", "/app/data/stock.db")
@@ -147,6 +170,17 @@ def post_run(body: schemas.RunRequest):
started_at = dt.datetime.utcnow().isoformat() started_at = dt.datetime.utcnow().isoformat()
with _conn() as c: with _conn() as c:
asof = _resolve_asof(body.asof, c) asof = _resolve_asof(body.asof, c)
# Skipped holiday handling for mode='auto'
if body.mode == "auto" and _is_holiday(asof):
return schemas.RunResponse(
asof=asof.isoformat(), mode="auto", status="skipped_holiday",
run_id=None, survivors_count=None,
weights={}, top_n=0,
results=[], telegram_payload=None,
warnings=[f"{asof.isoformat()} is a holiday — skipped"],
)
defaults = _load_settings(c) defaults = _load_settings(c)
if body.mode == "auto": if body.mode == "auto":

View File

@@ -144,3 +144,11 @@ def test_runs_list_and_detail(client):
assert detail.status_code == 200 assert detail.status_code == 200
assert detail.json()["meta"]["id"] == run_id assert detail.json()["meta"]["id"] == run_id
assert isinstance(detail.json()["results"], list) assert isinstance(detail.json()["results"], list)
def test_run_holiday_returns_skipped(client):
# 2026-05-09는 토요일 (주말). _is_holiday 가 weekday>=5를 잡음.
r = client.post("/api/stock/screener/run",
json={"mode": "auto", "asof": "2026-05-09"})
assert r.status_code == 200
assert r.json()["status"] == "skipped_holiday"