fix(lotto-signals): pstdev→stdev (ddof=1 sample) + z=None contract 문서화

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 02:41:09 +09:00
parent 21d46d95dd
commit e5465ad136

View File

@@ -7,7 +7,7 @@ signal_runner.py에서 DB 연동 + cron 진입점 담당.
from __future__ import annotations
import math
from dataclasses import dataclass, field
from statistics import mean, pstdev
from statistics import mean, stdev
from typing import Any, Dict, List, Optional, Tuple
@@ -92,7 +92,7 @@ class AdaptiveBaseline:
@property
def sigma(self) -> float:
return pstdev(self.window) if len(self.window) >= 2 else 0.0
return stdev(self.window) if len(self.window) >= 2 else 0.0
def push(self, value: float, draw_no: Optional[int] = None) -> None:
"""FIFO push. window_max 초과 시 가장 오래된 값 제거."""
@@ -108,6 +108,10 @@ class AdaptiveBaseline:
Returns:
(z_score, fire_level) — z_score는 cold start/warmup이면 None.
fire_level ∈ {'warmup', 'noop', 'normal', 'urgent'}
NOTE: z_score is None when sigma==0 (degenerate window) or warmup.
Callers must treat None as "signal present but unquantified" — do not
compare None with thresholds directly.
"""
if self.size < 4:
return None, "warmup"