"""거래량 급증 — log1p(recent/baseline).""" import numpy as np import pandas as pd from .base import ScoreNode, percentile_rank class VolumeSurge(ScoreNode): name = "volume_surge" label = "거래량 급증" default_params = {"baseline_days": 20, "eval_days": 3} param_schema = { "type": "object", "properties": { "baseline_days": {"type": "integer", "minimum": 5, "maximum": 60, "default": 20}, "eval_days": {"type": "integer", "minimum": 1, "maximum": 10, "default": 3}, }, } def compute(self, ctx, params: dict) -> pd.Series: baseline = int(params.get("baseline_days", 20)) eval_d = int(params.get("eval_days", 3)) prices = ctx.prices if prices.empty: return pd.Series(dtype=float) ordered = prices.sort_values("date") last_recent = ordered.groupby("ticker").tail(eval_d).groupby("ticker")["volume"].mean() last_baseline = ( ordered.groupby("ticker") .tail(baseline + eval_d) .groupby("ticker") .head(baseline) .groupby("ticker")["volume"] .mean() ) ratio = last_recent / last_baseline.replace(0, pd.NA) raw = np.log1p(ratio.astype(float)) return percentile_rank(raw).fillna(50.0)