포스트

재무 필터가 우량 은행을 걸러낼 때 — 부채비율 대신 계정 구조로 판별

적자·과다부채 기업을 거르는 재무 필터가 흑자 우량 은행(카카오뱅크)을 부채비율 1072%로 배제했다. 은행은 예수금이 부채라는 회계 구조 차이와, 섹터 하드코딩 없이 계정으로 판별한 방법.

재무 필터가 우량 은행을 걸러낼 때 — 부채비율 대신 계정 구조로 판별

문제

DART 재무로 “과다부채 기업 배제” 필터를 만들었다. 기준은 흔한 부채비율 500% 초과 배제. 그런데 배제 목록에 이상한 종목이 떴다:

1
❌ 카카오뱅크(323410): 과다부채(부채비율 > 1072%)

카카오뱅크는 영업이익 1,576억 흑자의 우량 은행이다. 게다가 하필 그날 봇의 매매 엔진이 진입 신호를 낸 종목이기도 했다. 우량주를 재무 필터가 걸러내고 있었다.

원인

제조업의 잣대를 은행에 들이댄 게 문제였다.

  • 제조업: 부채 = 빌린 돈. 부채비율이 높으면 위험하다.
  • 은행: 부채 = 고객 예수금. 고객이 맡긴 돈이 회계상 부채로 잡힌다. 은행은 예금을 받아 대출로 굴리는 게 본업이라, 부채비율 1,000%대가 정상이다.

즉 필터가 “나쁜 기업”을 잡은 게 아니라 “다른 회계 구조를 가진 정상 기업”을 잡은 것이다. 재무 필터의 첫 오탐은 부실기업이 아니라 업종 특성이었다.

해결 과정

가장 쉬운 해결은 “금융업 종목코드를 하드코딩해서 제외”다. 하지만 그건 유니버스가 바뀔 때마다 손봐야 하고, 새 금융주가 들어오면 또 터진다. 데이터로 판별하는 방법을 찾았다.

은행·금융사의 손익계산서에는 제조업에 없는 계정이 있다 — ‘이자수익’. 이걸로 금융사를 판별해 부채비율 잣대를 면제했다:

1
2
3
4
5
6
7
def is_financial(income_statement_accounts):
    # 손익계산서에 '이자수익' 계정이 있으면 금융사
    return any(acc.startswith("이자수익") for acc in income_statement_accounts)

# 부채비율 필터: 금융사는 면제
if not is_financial(...) and debt_ratio > 5.0:
    veto("과다부채")

부수적으로 계정명 표기 변형도 잡았다. 어떤 회사는 ‘영업이익’, 어떤 회사는 ‘영업이익(손실)’로 표기해서, 전방일치(startswith)로 흡수했다.

교체 후 카카오뱅크는 정상 통과했다 (is_financial=True, 영업이익 1,576억 흑자).

사용한 기술

  • 업종별 회계 구조 차이: 은행의 부채(예수금)는 제조업의 부채(차입금)와 성격이 다르다. 부채비율 지표를 전 업종에 획일 적용하면 안 된다.
  • 하드코딩 대신 데이터 판별: 섹터를 종목코드로 박지 말고, 데이터에 이미 있는 신호(‘이자수익’ 계정)로 판별하면 유니버스가 바뀌어도 안 깨진다.
  • 계정명 전방일치: 공시 계정명은 회사마다 표기가 다르다(‘영업이익’ vs ‘영업이익(손실)’). startswith로 흡수.

정리

  1. 재무 필터의 첫 오탐은 부실기업이 아니라 업종 특성이다 — 은행에 제조업 부채비율을 들이대면 우량 은행부터 걸러진다.
  2. 섹터는 하드코딩하지 말고 데이터로 판별하라 — ‘이자수익’ 계정 유무로 금융사를 가리면 유니버스 변경에 강건하다.
  3. 공시 계정명은 표기가 제각각이다 — 전방일치로 변형을 흡수하라.

이 글은 AI 자동매매 봇 3주 검증 회고의 트러블슈팅 서브클러스터 중 하나입니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.