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

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

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

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

![분석 파이프라인](/blog/assets/005-analysis-pipeline.svg)

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

---

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

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

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

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개 상장기업 전체로 확대하면 **같은 경제적 개념에 대해 수십 가지 변형**이 존재한다.

---

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

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

![계정 표준화](/blog/assets/005-account-mapping.svg)

매출 하나만 해도 이렇다.

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

DartLab은 이 문제를 7단계 매핑 파이프라인으로 해결한다. 34,000개 이상의 학습된 동의어를 기반으로, 2,700개 기업의 XBRL 계정을 하나의 표준 스키마로 통합했다.

```python
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분기 누적)를 빼야 한다.

![누적에서 독립 분기로](/blog/assets/005-quarterly-conversion.svg)

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

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

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

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

---

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

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

```python
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, ROA | 9.5%, 8.3%, 6.5% |
| 안정성 | 부채비율, 유동비율 | 27%, 259% |
| 성장성 | 매출성장률, 영업이익성장률 | YoY 기준 |
| 현금흐름 | FCF, 영업CF/매출 | 잉여현금흐름 |

---

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

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

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

```python
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 엔진 레이어](/blog/assets/005-dartlab-layers.svg)

### 데이터 수집과 정규화

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

### 40개 파싱 모듈

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

```python
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개 섹터로 자동 분류한다. "반도체"와 "은행"의 재무 구조가 다르니, 섹터별로 다른 기준을 적용해야 한다.

```python
from dartlab.engines.sector import classify

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

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

```python
from dartlab.engines.insight import analyze

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

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

```python
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](https://github.com/eddmpython/tradix)(백테스팅)와 [vectrix](https://github.com/eddmpython/vectrix)(시계열 예측)에 직접 연결한다. DartLab이 "과거에 무슨 일이 있었는가"를 정리하면, tradix는 "그 패턴으로 어떤 전략이 유효했는가"를, vectrix는 "앞으로 어떤 시나리오가 가능한가"를 보여준다. 세 도구가 하나의 분석 파이프라인으로 연결되면 과거 분석 → 전략 검증 → 미래 시나리오라는 완전한 흐름이 만들어진다.

---

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

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

![파이썬의 역할](/blog/assets/005-python-capabilities.svg)

### 파이썬이 잘하는 것

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

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

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

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

### 파이썬이 못하는 것

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

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

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

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

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

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

---

## 시작하는 방법

```bash
# 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 키도, 유료 구독도 필요 없다.

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

---

## 마무리

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

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

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