Engines Recipe unverified

Altman-lite 부도 위험 회피 필터 (역방향 블랙리스트)

Altman Z-Score (1968) 5 변수 중 dartlab 으로 가능한 4 변수 + 음수 영업CF 게이트 를 결합해 부도 위험 종목을 횡단으로 식별하고 다른 스크리너 결과의 블랙리스트로 사용하는 회피 절차.

engines.recipe.distressFilter GitHub 원본

이어 가기

절차

실행 순서

  1. 1

    Z > 2.99 = 안전 (Safe Zone)

  2. 2

    1.81 ≤ Z ≤ 2.99 = 회색 (Grey Zone)

  3. 3

    Z < 1.81 = 위험 (Distress Zone)

  4. 4

    `stockCode`, `corpName`

  5. 5

    `finance.ratio.debtRatio : float` (≥ 200%)

  6. 6

    `finance.ratio.currentRatio : float` (≤ 1.0)

  7. 7

    `finance.ratio.operatingCfMargin : float` (음수)

  8. 8

    `stockCode`, 3 기간 net_income (모두 음수)

  9. 9

    **X₄ 부재 (시총/총부채)** — 정확한 Z-Score 직접 X. 본 recipe 는 4/5 변수 근사 + CFO 추가.

  10. 10

    **금융업 부적합** — 은행·보험 부채비율 자연히 높음 (수신·보험금). 본 recipe 결과에서 금융업 별도 제외 필요 (`scan("fields")` 의 industry 필터 활용).

  11. 11

    **사이클 산업 일시 적자** — 조선·반도체 다운사이클 1-2 년 적자 정상. 3 년 연속 적자만 가져와서 일시 적자 회피.

  12. 12

    **임계값 (200% / 1.0 / 음수) 은 보수적 절대치** — 산업별 분포 차이 큼. 산업 percentile 기반 게이트 확장 가능.

학술 근거

Edward Altman, “Financial Ratios, Discriminant Analysis and the Prediction of Corporate Bankruptcy” (Journal of Finance, 1968): 5 변수 가중 합 Z-Score 모델. 1946-1965 미국 제조업 부도 1 년 전 80-90% 적중.

Z = 1.2·X₁ + 1.4·X₂ + 3.3·X₃ + 0.6·X₄ + 1.0·X₅

변수정의dartlab 가능?
X₁working capital / total assets◯ (account 직접)
X₂retained earnings / total assets◯ (account 직접)
X₃EBIT / total assets◯ (operating_profit / total_assets)
X₄market value of equity / book value of total liabilities✗ (시총 시계열 결합 어려움)
X₅sales / total assets◯ (totalAssetTurnover)

본 recipe 는 X₄ 제외 + 음수 영업CF 게이트 추가. 정확한 Z-Score 계산 대신 회피용 블랙리스트 (역방향 스크리너) 로 사용.

해석:

  • Z > 2.99 = 안전 (Safe Zone)
  • 1.81 ≤ Z ≤ 2.99 = 회색 (Grey Zone)
  • Z < 1.81 = 위험 (Distress Zone)

본 recipe 는 다른 스크리너 (qualityValue, garp, graham) 결과에서 distress 종목을 빼는 데 우선. 단독 사용 시 부도 위험 종목 식별 가능.

공개 호출 방식

import dartlab
import polars as pl

# 1) 부도 위험 게이트 — 부채 200% 이상 + 유동성 1.0 이하 + CFO 음수
distress = dartlab.scan("screen", spec={"where": [
    {"field": "finance.ratio.debtRatio", "op": ">=", "value": 200},
    {"field": "finance.ratio.currentRatio", "op": "<=", "value": 1.0},
    {"field": "finance.ratio.operatingCfMargin", "op": "<", "value": 0},
]})

# 2) 추가 시그널 — 3 년 연속 순이익 적자 (Altman X₂ retained earnings 약화 신호)
ni = dartlab.scanAccount("net_income", freq="Y").select(
    ["stockCode", "2025", "2024", "2023"]
)
loss3y = ni.with_columns(
    pl.all_horizontal([pl.col(y) < 0 for y in ["2025","2024","2023"]]).alias("loss3y")
).filter(pl.col("loss3y"))

# 3) 블랙리스트 = 게이트 OR 3 년 적자
blacklist = pl.concat([
    distress.select("stockCode"),
    loss3y.select("stockCode"),
]).unique()

# 4) 다른 스크리너 결과에서 빼기
def excludeDistress(df: pl.DataFrame, blacklist: pl.DataFrame) -> pl.DataFrame:
    return df.join(blacklist.with_columns(pl.lit(True).alias("_distress")), on="stockCode", how="left").filter(pl.col("_distress").is_null()).drop("_distress")

호출 동작

  1. scan("screen", spec=...) — 부채 200% + 유동성 1.0 이하 + CFO 음수 (3 게이트 동시 통과 = 위험).
  2. scanAccount("net_income", freq="Y") — 3 기간 (2023-2025) 컬럼.
  3. pl.all_horizontal — 3 년 모두 음수만 필터.
  4. union — 게이트 OR 3 년 적자 = 블랙리스트.
  5. excludeDistress() 헬퍼 — 다른 스크리너 결과에서 anti-join.

대표 반환 형태

distress : pl.DataFrame — 부도 위험 후보:

  • stockCode, corpName
  • finance.ratio.debtRatio : float (≥ 200%)
  • finance.ratio.currentRatio : float (≤ 1.0)
  • finance.ratio.operatingCfMargin : float (음수)

loss3y : pl.DataFrame — 3 년 연속 적자:

  • stockCode, 3 기간 net_income (모두 음수)

blacklist : pl.DataFramestockCode 단일 컬럼.

한계

  • X₄ 부재 (시총/총부채) — 정확한 Z-Score 직접 X. 본 recipe 는 4/5 변수 근사 + CFO 추가.
  • 금융업 부적합 — 은행·보험 부채비율 자연히 높음 (수신·보험금). 본 recipe 결과에서 금융업 별도 제외 필요 (scan("fields") 의 industry 필터 활용).
  • 사이클 산업 일시 적자 — 조선·반도체 다운사이클 1-2 년 적자 정상. 3 년 연속 적자만 가져와서 일시 적자 회피.
  • 임계값 (200% / 1.0 / 음수) 은 보수적 절대치 — 산업별 분포 차이 큼. 산업 percentile 기반 게이트 확장 가능.
  • Altman Z 자체 한계 — 1968 미국 제조업 모델. 한국 KOSPI 적용 검증 적음. 본 recipe 는 회피 신호 강도만 신뢰, 점수 절대값 X.

한국 / 미국 시장 차이

  • 한국: chaebol 계열사 상호지급보증·연결 회계로 단순 부채비율 200% 가 항상 위험 X. 단 비계열 중소 제조업에서는 강한 시그널.
  • 미국: 원전 검증 시장. 부채비율 평균 낮음 (S&P 500 약 80%). 200% 임계는 한국 보다 강한 시그널.

연계 절차

  1. 본 recipe 로 블랙리스트 생성 — blacklist DataFrame.
  2. 다른 스크리너 (qualityValueScreen, garpScreen, grahamDeepValue, piotroskiLite) 결과에서 excludeDistress() 호출.
  3. 단독 사용 시 — 위험 종목 명단 자체로 engines.credit 신용 위험 심층 분석 input.
  4. engines.analysis.cashflow — CFO·FCF·이자보상배율 시계열로 위험 강도 정량화.
  5. engines.story 로 위험 narrative — 단순 “위험” X, 어떤 사이클·산업 구조·자본정책 으로 부도 시나리오 까지.

기본 검증

  • 블랙리스트 종목 수 — 30-100 개가 정상 (KOSPI 1-4%). 200 개 초과 = 게이트 너무 강함 (200% → 250% 등 완화).
  • 외부 신용평가 비교 — KIS·NICE 등급 BB 이하 종목과 본 블랙리스트 교집합 80% 이상이어야 검증.
  • 게이트 통과 (3 게이트) 와 3 년 적자 후보가 분리될 수 있음 — union 시 두 집합 합집합.
  • 일시 충격 (코로나·금융위기 등 매크로 사이클) 영향 종목은 본 recipe 통과 시 별도 회복 시나리오 검토.
  • “Altman Z 0.5 = 부도 확정” 단정 X — 위험 신호이지 부도 예측 X.

런타임

실행 환경별 호환성

환경상태비고 / 제한
Local Python supported
Server supported
MCPunknown
Web AIunknown
Pyodide limited
  • 브라우저 안에서는 다년 시계열 일부 한정