From ceb9b8565dea023519161a53e00615fad0eb3b86 Mon Sep 17 00:00:00 2001 From: hyowons Date: Mon, 8 Jun 2026 15:55:19 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20ADR=20=EC=B6=94=EC=84=B8=20=EC=B0=A8?= =?UTF-8?q?=ED=8A=B8=2020=EC=9D=BC=20=EB=AF=B8=EB=A7=8C=20=EB=88=84?= =?UTF-8?q?=EC=A0=81=20=EA=B5=AC=EA=B0=84=EB=8F=84=20=ED=91=9C=EC=8B=9C(?= =?UTF-8?q?=ED=99=95=EC=9E=A5=20=EC=9C=88=EB=8F=84=EC=9A=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _compute_adr_ma_series를 확장 윈도우로 — window 미만 구간은 가용한 만큼의 평균으로 1일차부터 점 생성. 누적이 20일 도달하면 정식 trailing-20 이평과 동일(steady-state 불변, 검증됨). 누적 중엔 제목에 '누적 N/20일' 표시. Co-Authored-By: Claude Opus 4.8 --- agents/stock/workspace/scripts/behive_web.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/agents/stock/workspace/scripts/behive_web.py b/agents/stock/workspace/scripts/behive_web.py index 81956c6..3c4a707 100644 --- a/agents/stock/workspace/scripts/behive_web.py +++ b/agents/stock/workspace/scripts/behive_web.py @@ -5116,12 +5116,13 @@ def _compute_adr_ma_latest(symbol: str, today_raw_adr: float | None, today_date: def _compute_adr_ma_series(rows: list[dict], window: int = ADR_MA_WINDOW) -> list[tuple[str, float, bool]]: """rows(오래된 순, {date,adr,is_live}) → 각 시점 trailing window 평균 시리즈. - [(date, ma, is_live), ...]. window 채워지지 않은 앞쪽은 skip. - is_live는 그 시점 윈도우에 라이브 점이 포함됐는지 (= 마지막 평균만 라이브일 가능성).""" + [(date, ma, is_live), ...]. + 확장 윈도우: window 미만 누적 구간은 '가용한 만큼'(최대 window일)의 평균으로 점을 만든다 → + 1일차부터 그려지고 누적이 window에 도달하면 정상 trailing-window 평균과 동일(steady-state 동작 불변).""" series: list[tuple[str, float, bool]] = [] - for i in range(window - 1, len(rows)): - win = rows[i + 1 - window : i + 1] - avg = sum(r['adr'] for r in win) / window + for i in range(len(rows)): + win = rows[max(0, i + 1 - window) : i + 1] + avg = sum(r['adr'] for r in win) / len(win) is_live = any(r.get('is_live') for r in win) series.append((rows[i]['date'], avg, is_live)) return series @@ -5577,10 +5578,12 @@ def _render_adr_trend_card(days: int = ADR_TREND_DAYS) -> str: f'' ) + # 누적 < window 면 아직 정식 20일 이평이 아니라 '가용한 만큼'의 평균 → 제목에 명시. + accum_note = f' · 누적 {raw_count_max}/{ADR_MA_WINDOW}일' if raw_count_max < ADR_MA_WINDOW else '' return ( '
' f'
ADR 추세 {ADR_MA_WINDOW}일 이평 · ' - + html.escape(sel_label) + '
' + + html.escape(sel_label) + accum_note + '
' + summary_block + f'
{ADR_MA_WINDOW}일 이동평균 ADR · 회색점선=100(균형) · 파란점선=75(침체) · 빨간점선=125(과열) · *=오늘(라이브 포함)
' + _render_adr_trend_controls(days)