파이썬으로 재무제표 분석하기 — 코드 한 줄로 2,700개 기업을 비교한다
Quick Summary

파이썬으로 상장기업 재무제표를 분석하는 방법을 처음부터 끝까지 정리한다. 데이터 수집, 계정 표준화, 분기별 시계열, 재무비율, 섹터 분류, 인사이트 등급, 기업 간 비교까지 — 엑셀로는 며칠 걸릴 작업을 코드 몇 줄로 끝내는 방법.

파이썬으로 재무제표 분석하기

엑셀에서 재무제표를 정리해본 사람이라면 안다. 종목 하나 분석하는 데 반나절, 비교 대상 5개를 추가하면 이틀, 분기별 시계열을 만들려면 일주일이다.

파이썬은 이 과정을 근본적으로 바꾼다. “데이터 수집 → 정리 → 분석 → 비교”의 전체 파이프라인을 코드로 만들면, 한 번 만든 분석을 2,700개 상장기업 전체에 동시에 적용할 수 있다.

분석 파이프라인

이 글에서는 파이썬으로 재무제표 분석을 시작하는 방법을 처음부터 끝까지 정리한다. “파이썬을 모르는 투자자”보다는 “파이썬은 조금 할 줄 아는데, 재무 데이터를 어떻게 다뤄야 할지 모르겠는” 사람을 위한 글이다.


재무 데이터, 어디서 가져오나

한국 상장기업의 재무 데이터 소스는 크게 세 가지다.

소스데이터 형태장점단점
OpenDART APIJSON, XBRL공식, 무료, 실시간호출 제한, 계정명 비표준
네이버/KRXHTML 크롤링이미 정리된 요약원본 아님, 항목 제한적
유료 데이터CSV/API깨끗하고 표준화비용 (월 수십~수백만원)

OpenDART가 가장 정확하고 포괄적이다. 금융감독원이 직접 운영하며, 상장기업이 법적 의무로 제출한 원본 데이터를 제공한다 (OpenDART의 장단점은 OpenDART, 솔직한 리뷰에서 자세히 다룬다). 문제는 데이터가 날것 그대로라는 것이다.


날것 데이터의 현실

OpenDART에서 삼성전자의 매출을 가져오면 이렇게 나온다.

account_id: ifrs-full_Revenue
account_nm: 수익(매출액)
thstrm_amount: 258,935,498,000,000

SK하이닉스의 매출은?

account_id: dart_OperatingRevenue
account_nm: 영업수익
thstrm_amount: 66,321,456,000,000

현대차는?

account_id: ifrs-full_Revenue
account_nm: 매출액
thstrm_amount: 162,663,620,000,000

같은 “매출”인데 account_id도 다르고, account_nm도 다르다. ifrs-full_Revenue, dart_OperatingRevenue, 그리고 이름은 “수익(매출액)”, “영업수익”, “매출액”으로 제각각이다.

이건 삼성전자, SK하이닉스, 현대차 세 개만 비교한 것이다. 2,700개 상장기업 전체로 확대하면 같은 경제적 개념에 대해 수십 가지 변형이 존재한다.


계정 표준화 — 가장 어려운 문제

재무 분석에서 가장 어려운 단계는 “분석”이 아니라 “같은 것을 같다고 인식하는 것”이다.

Account Mapping Pipeline

계정 표준화

매출 하나만 해도 이렇다.

ifrs-full_Revenue          → revenue
dart_OperatingRevenue      → revenue
dart_Revenue               → revenue
dart_ConstructionRevenue   → revenue (건설업)
ifrs_Revenue               → revenue
수익(매출액)                → revenue
영업수익                    → revenue
매출액                      → revenue

DartLab은 이 문제를 7단계 매핑 파이프라인으로 해결한다 (매핑 파이프라인의 기술적 배경은 XBRL 파싱과 계정 매핑은 왜 어렵고 어떻게 풀어야 하나에서 깊이 있게 다룬다). 34,000개 이상의 학습된 동의어를 기반으로, 2,700개 기업의 XBRL 계정을 하나의 표준 스키마로 통합했다.

from dartlab import Company

samsung = Company("삼성전자")
hyundai = Company("현대차")

series_s, periods_s = samsung.timeseries
series_h, periods_h = hyundai.timeseries

# 원본이 ifrs-full_Revenue든 dart_OperatingRevenue든
# 동일한 키로 접근 가능
samsung_revenue = series_s["IS"]["revenue"]
hyundai_revenue = series_h["IS"]["revenue"]

revenue라는 하나의 키로 어떤 기업이든 매출에 접근할 수 있다. 이 표준화의 정확도는 98.7%다. 2,700개 기업의 1,580만 행을 테스트한 결과이며, 재무상태표 등식(자산 = 부채 + 자본) 검증은 99.7% 통과한다.


분기별 시계열 — 누적에서 독립으로

DART 재무 데이터의 또 다른 난관은 누적 구조다.

반기보고서에 적힌 매출 1,000억은 “상반기 매출이 1,000억”이라는 뜻이다. 1분기가 400억이었다면 2분기는 600억인데, 보고서에는 “1,000억”으로만 나온다.

연간보고서의 매출 3,000억도 마찬가지다. 이건 “4분기 매출”이 아니라 “1~4분기 합계”다. 4분기 매출만 알고 싶다면 3분기 보고서(1~3분기 누적)를 빼야 한다.

누적에서 독립 분기로

DartLab은 이 역산을 자동으로 처리한다. 손익계산서(IS)와 현금흐름표(CF)는 누적에서 독립 분기로 변환하고, 재무상태표(BS)는 시점 잔액이므로 그대로 둔다.

c = Company("005930")
series, periods = c.timeseries

# periods = ["2016_Q1", "2016_Q2", ..., "2024_Q4"]
# 36개 분기 × 3개 재무제표 × 수십 개 계정 = 독립 분기 시계열

이걸 수작업으로 하면? 한 기업당 반나절이다. 2,700개 기업이면 계산해보시라.


재무비율 — 숫자에서 의미로

시계열이 있으면 재무비율 계산은 간단하다.

r = Company("삼성전자").ratios

r.roe               # 8.29 (%)
r.operatingMargin   # 9.51 (%)
r.debtRatio         # 27.4 (%)
r.currentRatio      # 258.6 (%)
r.fcf               # Free Cash Flow (원)

이 비율들은 TTM(Trailing Twelve Months) 기준으로 계산된다. 최근 4개 분기의 합산이므로 계절성 효과가 제거된 가장 최신 수치다.

수익성, 안정성, 성장성, 현금흐름 — 이 네 가지 축으로 기업의 재무 상태를 한눈에 파악할 수 있다.

영역지표삼성전자 예시
수익성영업이익률, ROE, ROA9.5%, 8.3%, 6.5%
안정성부채비율, 유동비율27%, 259%
성장성매출성장률, 영업이익성장률YoY 기준
현금흐름FCF, 영업CF/매출잉여현금흐름

기업 간 비교 — 코드 한 줄의 힘

엑셀에서 삼성전자와 SK하이닉스의 매출 추이를 비교하려면 각각 시트를 만들고, 분기별 데이터를 일일이 입력하고, 누적→독립 변환을 하고, 차트를 그려야 한다.

파이썬에서는 이렇게 한다.

from dartlab import Company

codes = ["005930", "000660", "035420", "035720", "051910"]
names = []
revenues = []

for code in codes:
    c = Company(code)
    names.append(c.corpName)
    r = c.ratios
    revenues.append(r.revenueTTM)

# names = ["삼성전자", "SK하이닉스", "NAVER", "카카오", "LG화학"]
# revenues = [TTM 매출 리스트]

5개 기업의 TTM 매출을 가져오는 데 코드 10줄이다. 이걸 50개로 늘리면? codes 리스트만 바꾸면 된다. 500개로 늘려도 같다.


엑셀 vs 파이썬 — 무엇이 다른가

“그냥 엑셀 쓰면 안 되나?”

종목 한두 개를 들여다보는 데는 엑셀이 더 빠를 수 있다. 하지만 분석의 규모반복성이 달라지면 상황이 뒤집힌다.

엑셀파이썬
종목 1개 분석빠르다비슷하다
종목 10개 비교반나절1분
종목 2,700개 스크리닝불가능수 분
분기 데이터 업데이트수작업 반복코드 재실행
분석 로직 변경시트 전체 수정함수 하나 수정
재현 가능성낮다코드가 문서다

파이썬의 진짜 장점은 속도가 아니라 재현 가능성이다. “이 분석을 다시 해봐”라고 했을 때 코드를 실행하면 끝이다. 엑셀은 “어디서 복사한 값이지?”, “이 수식 왜 깨졌지?” 같은 문제가 생긴다.


DartLab이 자동화하는 영역

DartLab은 “DART 원본 데이터를 분석 가능한 형태로 바꾸는” 전체 과정을 자동화한다.

DartLab 엔진 레이어

데이터 수집과 정규화

기능설명
자동 다운로드GitHub Releases에서 2,700+ 기업 데이터 자동 수집
계정 표준화34,000+ 동의어 기반 7단계 매핑 (98.7% 커버리지)
분기 시계열누적→독립 변환, 연결/별도 자동 판별
재무비율ROE, 영업이익률, 부채비율, FCF 등 TTM 자동 계산

40개 파싱 모듈

재무제표만이 아니다. 사업보고서의 모든 정형 섹션을 구조화된 DataFrame으로 추출한다.

c = Company("005930")

# 재무제표
c.BS    # 재무상태표
c.IS    # 손익계산서
c.CF    # 현금흐름표

# 공시 텍스트
c.business       # 사업의 내용
c.mdna           # 경영진 토의 (MD&A)

# 지배구조
c.majorHolder    # 최대주주 지분 시계열
c.executive      # 임원 현황
c.executivePay   # 임원 보수

# 리스크
c.contingentLiability  # 우발부채/소송
c.audit                # 감사의견

# 기타 40개 모듈...

분석 엔진

원본 데이터 위에 3개의 분석 엔진이 동작한다.

섹터 분류 — 2,700개 기업을 WICS 11개 섹터로 자동 분류한다. “반도체”와 “은행”의 재무 구조가 다르니, 섹터별로 다른 기준을 적용해야 한다.

from dartlab.engines.sector import classify

result = classify("005930")
# sector="정보기술", subSector="반도체", confidence=0.95

인사이트 등급 — 실적, 수익성, 재무건전성, 현금흐름, 성장성, 지배구조, 밸류에이션 7개 영역에 A~F 등급을 부여한다. 30개 이상의 재무 지표에서 이상치도 자동 탐지한다.

from dartlab.engines.insight import analyze

result = analyze("005930")
# grades = {"performance": "B", "profitability": "B", "health": "A", ...}
# anomalies = [{"metric": "inventoryTurnover", "zscore": -2.8, ...}]

시장 순위 — 매출, 자산, 성장률 기준으로 전체 시장 순위와 섹터 내 순위를 계산한다.

from dartlab.engines.rank import getRank

result = getRank("005930")
# revenueRank=1, assetRank=2, sectorRevenueRank=1

지금은 없지만, 앞으로 추가될 것

DartLab은 아직 완성되지 않았다. 현재 구현된 것과 앞으로 추가될 것을 명확히 구분한다.

구현 완료

  • 40개 파싱 모듈 (재무제표, 주석, 배당, 감사, 임원, 지배구조, 리스크 등)
  • 계정 표준화 엔진 (98.7% 커버리지)
  • 분기별 독립 시계열 + 재무비율
  • 섹터 분류, 인사이트 등급, 시장 순위
  • AI 분석 웹 인터페이스 (Ollama 로컬 LLM)

개발 예정

클라우드 LLM 지원 — 현재 Ollama(로컬)만 지원하는 AI 분석에 OpenAI, Anthropic 등 클라우드 LLM을 추가한다. 더 강력한 모델로 분석의 깊이를 높인다.

EDGAR 통합 — 미국 SEC 전자공시 데이터를 같은 표준 스키마로 통합한다. 한국 기업과 미국 기업을 동일한 코드로 비교 분석할 수 있게 된다.

텍스트 분석 모듈 — 사업보고서 서술형 텍스트의 변화를 자동 감지한다. 전기와 당기의 “사업의 내용”을 비교해서 새로 추가된 리스크 문구, 삭제된 사업 영역, 어조 변화를 포착한다.

정량 + 정성 교차 검증 — 숫자와 텍스트를 교차 검증한다. 매출은 늘었는데 “사업의 내용”에서 해당 사업 관련 서술이 축소되었다면 경고 신호다. 감사의견은 “적정”인데 핵심감사사항에 계속기업 불확실성이 언급되었다면 주의가 필요하다.

시각화 — 재무 데이터 시각화 도구를 통합한다. 시계열 차트, 기업 간 비교 차트, 섹터 히트맵 등을 코드 한 줄로 생성한다.

tradix/vectrix 연동 — DartLab의 재무 데이터를 tradix(백테스팅)와 vectrix(시계열 예측)에 직접 연결한다. DartLab이 “과거에 무슨 일이 있었는가”를 정리하면, tradix는 “그 패턴으로 어떤 전략이 유효했는가”를, vectrix는 “앞으로 어떤 시나리오가 가능한가”를 보여준다. 세 도구가 하나의 분석 파이프라인으로 연결되면 과거 분석 → 전략 검증 → 미래 시나리오라는 완전한 흐름이 만들어진다.


파이썬이 할 수 있는 것, 할 수 없는 것

파이썬은 만능이 아니다. 재무 분석에서 파이썬이 잘하는 영역과 한계를 명확히 알아야 한다.

파이썬의 역할

파이썬이 잘하는 것

대규모 데이터 처리 — 2,700개 기업 × 36분기 × 수십 개 계정 = 수백만 행의 데이터를 몇 초 안에 처리한다. DartLab은 Polars를 사용하는데, pandas보다 10~100배 빠르다.

패턴 탐지 — “부채비율이 급격히 상승한 기업”, “3분기 연속 영업적자인 기업”, “FCF가 마이너스인데 배당을 늘린 기업” 같은 조건을 전 종목에서 스크리닝할 수 있다.

자동화와 재현 — 분기 실적이 발표될 때마다 같은 분석을 자동으로 반복할 수 있다. “매번 같은 방법으로” 분석하므로 시점 간 비교가 정확하다.

기업 간 비교 — 표준화된 스키마 덕분에 어떤 두 기업이든 동일한 기준으로 비교할 수 있다. “반도체 섹터에서 ROE가 가장 높은 기업 5개”를 1초 안에 뽑을 수 있다.

파이썬이 못하는 것

경영진의 진의 파악 — MD&A에 “지속적인 수익성 개선을 위해 노력하겠습니다”라고 적혀 있을 때, 이게 진짜 의지인지 형식적 문구인지는 코드로 판단할 수 없다.

미래 예측 — 과거 데이터에서 패턴은 찾을 수 있지만, “다음 분기 매출이 얼마일까”는 근본적으로 불확실하다. 코드는 가정을 바꿔가며 시나리오를 빠르게 돌릴 수 있을 뿐이다. 다만 통계적 시계열 예측은 가이드를 제공할 수 있다 — vectrix는 13개 이상의 모델(AutoETS, AutoARIMA, Theta, GARCH 등)을 자동 선택하고, 65개 통계 특성으로 데이터를 프로파일링한 뒤 예측하는 시계열 예측 엔진이다. “정답”은 아니지만, 데이터 기반의 출발점을 제공한다.

과거 전략 검증 — “이 전략이 과거에 통했을까?”를 체계적으로 검증하는 것도 DartLab 단독으로는 어렵다. tradix는 33개 전략과 60개 이상의 기술 지표를 제공하는 백테스팅 엔진으로, 1,000개 파라미터 최적화를 1초 이내에 수행한다. 한국 시장(KRX 거래세, 수수료)도 기본 지원한다.

맥락 이해 — “이 회사의 부채비율 200%는 위험한가?”는 업종, 사업 모델, 부채의 성격에 따라 답이 다르다. 건설업의 200%와 IT업의 200%는 전혀 다른 의미다.

투자 판단 — 분석 도구는 판단 재료를 제공할 뿐이다. 매수/매도 결정은 사람의 몫이다.

요약하면, 파이썬은 “무엇이 일어났는가”를 빠르게 정리하는 도구이고, “그래서 어떻게 할 것인가”는 여전히 사람의 영역이다. 다만 그 사이를 메우는 도구들이 이미 존재한다 — DartLab이 과거 데이터를 정리하고, tradix가 전략을 검증하고, vectrix가 미래 시나리오를 제시하는 조합이다.


시작하는 방법

# 1. uv 설치
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. 프로젝트 생성
uv init my-analysis && cd my-analysis

# 3. DartLab 설치
uv add dartlab

# 4. 첫 분석
uv run python -c "
from dartlab import Company
c = Company('005930')
print(c.corpName)
print(c.ratios)
"

데이터는 처음 실행할 때 GitHub Releases에서 자동 다운로드된다. API 키도, 유료 구독도 필요 없다.

# 한 줄로 전체 데이터 다운로드
from dartlab.core.dataLoader import downloadAll
downloadAll("finance")   # 2,700+ 기업 재무 데이터
downloadAll("docs")      # 260+ 기업 공시 문서
downloadAll("report")    # 2,700+ 기업 정기보고서

10분 체크리스트

  • 원본 데이터를 분석 가능한 형태로 바꾸는 비용이 어디서 발생하는지 이해했는가
  • 계정 표준화와 누적값 처리의 필요성을 설명할 수 있는가
  • 엑셀과 파이썬의 역할 차이를 구분하고 있는가
  • DartLab이 자동화하는 영역과 사람이 해석해야 하는 영역을 나눠서 보고 있는가
  • 첫 실험 코드를 바로 실행할 수 있는 상태인가

FAQ

파이썬을 꼭 잘해야 시작할 수 있나

아니다. 몇 줄의 기본 코드만으로도 재무제표 조회와 비교는 시작할 수 있다.

엑셀보다 항상 낫나

반복 작업, 대량 비교, 재현성에서는 훨씬 강하지만 최종 해석과 간단한 검토는 엑셀이 더 빠를 때도 있다.

가장 어려운 문제는 무엇인가

원본 데이터 수집보다 계정 표준화, 누적값 처리, 텍스트 구조 차이를 흡수하는 일이 더 어렵다.

파이썬이 투자 판단까지 대신해주나

아니다. 파이썬은 데이터를 정리하고 패턴을 찾는 도구이고, 최종 판단은 여전히 사람의 몫이다.


관련 글

마무리

재무 분석의 80%는 “데이터를 분석 가능한 형태로 만드는 것”이다. 원본 데이터를 다운로드하고, 계정명을 통합하고, 누적을 독립으로 바꾸고, 재무비율을 계산하는 — 이 지루하고 반복적인 과정이 전체 시간의 대부분을 차지한다.

파이썬은 이 80%를 자동화한다. 남은 20% — 숫자의 의미를 해석하고, 텍스트에서 맥락을 읽고, 최종 판단을 내리는 것 — 는 여전히 사람의 몫이다.

하지만 그 20%에 집중할 수 있게 해주는 것 자체가 파이썬의 가치다. 엑셀 시트와 씨름하느라 정작 중요한 질문을 던질 시간이 없었다면, 이제 코드가 그 시간을 돌려줄 것이다.

같은 시리즈에서 이어 읽기
DartLab

같은 카테고리에서 더 읽기

DartLab은 데이터 자동화 카테고리 안에서 글이 서로 이어지도록 설계합니다. 다음 글로 넘어가며 구조와 맥락을 같이 쌓는 방식입니다.

DartLab Product

이 글의 판단을 실제 데이터 흐름으로 옮기기

DartLab은 전자공시를 읽는 법을 코드와 데이터로 연결하기 위해 만든 제품입니다. 사업보고서 텍스트, 재무 시계열, 정기보고서 데이터를 한 흐름에서 다루도록 설계했습니다.