recipes.sentiment.consensusRevisionPace Recipes Recipe deprecated

컨센서스 revision 속도 (애널리스트 EPS 추정 변화율 z-score)

30/60/90 일 윈도우 별 EPS 추정 변화율 + revision count 의 z-score. 본 신호는 *애널리스트 합의의 변화 속도* 정량화 — 단순 컨센서스 절대값이 아닌 *변화율*. sentiment 페르소나 보조. 트리거 — '컨센서스 revision 속도 (애널리스트 EPS 추정 변화율 z-score)', 'consensus revision pace', 'consensusRevisionPace'.

이 스킬

컨센서스 revision 속도 (애널리스트 EPS 추정 변화율 z-score)

30/60/90 일 윈도우 별 EPS 추정 변화율 + revision count 의 z-score. 본 신호는 *애널리스트 합의의 변화 속도* 정량화 — 단순 컨센서스 절대값이 아닌 *변화율*. sentiment 페르소나 보조. 트리거 — '컨센서스 revision 속도 (애널리스트 EPS 추정 변화율 z-score)', 'consensus revision pace', 'consensusRevisionPace'.

Recipes deprecated recipes.sentiment.consensusRevisionPace

연계 절차

이 절차의 단계

  1. 1

    revision 시점 외인/기관 수급 정합.

  2. 2
    recipes.fundamental.disclosure.event recipes.fundamental.disclosure.event

    실적 공시 직전 revision 패턴.

절차

실행 순서

  1. 1

    애널리스트 < 3 명 종목은 컨센 noise — 한계 명시.

  2. 2

    EPS 부호 전환 (음 → 양) 시 변화율 정의 불안정 — 절대값 표기 병행.

  3. 3

    revision 단독 결론 X — 가격·수급과 결합.

공개 호출 방식

import dartlab
import polars as pl
import statistics
from datetime import datetime, timedelta

target = "005930"
c = dartlab.Company(target)

try:
    con_rows = c.gather("consensus").to_dicts()
except Exception:
    con_rows = []

def parseDate(v):
    if isinstance(v, datetime): return v.date()
    s = str(v)[:10].replace(".","-")
    try: return datetime.strptime(s, "%Y-%m-%d").date()
    except: return None

con_rows = sorted([r for r in con_rows if parseDate(r.get("asOf"))], key=lambda r: parseDate(r.get("asOf")))

eps_series = []
for r in con_rows:
    eps = r.get("epsConsensus") or r.get("avgEps")
    try: eps = float(eps) if eps is not None else None
    except: eps = None
    if eps is not None:
        eps_series.append({"asOf": parseDate(r.get("asOf")), "eps": eps, "analystCount": int(r.get("analystCount") or 0)})

if len(eps_series) < 4:
    table = pl.DataFrame(schema={"window": pl.Utf8, "epsChangePct": pl.Float64, "analystCountDelta": pl.Int64})
    emit_result(table=table, values={"insufficient": True}, date=None, sources=["dartlab://gather/consensus"])
else:
    last = eps_series[-1]
    rows = []
    for window_days in (30, 60, 90):
        past = [x for x in eps_series if x["asOf"] >= last["asOf"] - timedelta(days=window_days)]
        if len(past) >= 2:
            chg = (last["eps"] / past[0]["eps"] - 1) if past[0]["eps"] else None
            analyst_delta = last["analystCount"] - past[0]["analystCount"]
            rows.append({"window": f"{window_days}d", "epsChangePct": chg, "analystCountDelta": analyst_delta})
    table = pl.DataFrame(rows) if rows else pl.DataFrame(schema={"window": pl.Utf8, "epsChangePct": pl.Float64, "analystCountDelta": pl.Int64})
    emit_result(
        table=table,
        values={"epsLatest": last["eps"], "analystLatest": last["analystCount"]},
        date=str(last["asOf"]),
        sources=["dartlab://gather/consensus"],
    )

호출 동작

EPS 컨센서스 시계열 (asOf 별) 정렬 후 30/60/90 일 윈도우 변화율 + 애널리스트 수 변화. 변화율 > +5% = 상향 revision, < -5% = 하향 revision.

대표 반환 형태

column의미
window30d / 60d / 90d
epsChangePctEPS 추정 변화율
analystCountDelta애널리스트 수 변화

연계 절차

  1. recipes.sentiment.flowImbalance - revision 시점 외인/기관 수급 정합.
  2. recipes.fundamental.disclosure.event - 실적 공시 직전 revision 패턴.

기본 검증

  • 애널리스트 < 3 명 종목은 컨센 noise — 한계 명시.
  • EPS 부호 전환 (음 → 양) 시 변화율 정의 불안정 — 절대값 표기 병행.
  • revision 단독 결론 X — 가격·수급과 결합.

런타임

실행 환경별 호환성

환경상태비고 / 제한
Local Python supported·
Server supported·
MCP supported·
Web AI limited·
Pyodide limited·