분기 실적을 더했더니 두 배가 되는 이유, DART 누적값 바로잡기

반기 매출과 3분기보고서 매출을 더하면 실제 연간 매출보다 큰 숫자가 나올 수 있습니다. 반기와 3분기보고서의 손익 열에는 연초부터 해당 분기까지 누적된 값이 함께 들어 있기 때문입니다.

이 글의 핵심

  • 재무상태표는 시점 잔액이므로 분기끼리 빼서 단일 분기를 만들지 않습니다.
  • 손익계산서의 thstrm_add_amount는 누적값입니다.
  • 2~4분기 단독값은 현재 누적값에서 직전 누적값을 뺍니다.
  • 네 단일 분기의 합이 연간 값과 일치하는지 검산합니다.
누적 분기값을 단일 분기값으로 바꾸는 검산

삼성전자 2025년 매출로 확인합니다

구간 보고서에서 만든 누적 매출 단일 분기 매출
1분기 79.14조원 79.14조원
2분기 153.71조원 74.57조원
3분기 239.77조원 86.06조원
4분기 333.61조원 93.84조원

2분기 단독 매출은 반기 누적에서 1분기 누적을 뺀 74.57조원입니다. 4분기는 연간 333.61조원에서 3분기 누적 239.77조원을 뺀 93.84조원입니다. 네 단일 분기의 합은 연간 매출과 정확히 일치합니다.

TEXT
2분기 = 반기 누적 - 1분기 누적
3분기 = 3분기 누적 - 반기 누적
4분기 = 연간 - 3분기 누적

실행 코드

PYTHON
#!/usr/bin/env python3
"""OpenDART 누적 손익을 단일 분기 값으로 변환하고 합계를 검산한다."""

from __future__ import annotations

import os

from dotenv import load_dotenv
import pandas as pd
import requests


ENDPOINT = "https://opendart.fss.or.kr/api/fnlttSinglAcntAll.json"
REPORT_CODES = ("11013", "11012", "11014", "11011")


def fetch_revenue(api_key: str, report_code: str) -> tuple[int, int]:
    response = requests.get(
        ENDPOINT,
        params={
            "crtfc_key": api_key,
            "corp_code": "00126380",
            "bsns_year": "2025",
            "reprt_code": report_code,
            "fs_div": "CFS",
        },
        timeout=30,
    )
    payload = response.json()
    if response.status_code != 200 or payload.get("status") != "000":
        raise RuntimeError(f"OpenDART 조회 실패: {payload.get('status', response.status_code)}")
    row = next(
        item
        for item in payload["list"]
        if item.get("account_id") == "ifrs-full_Revenue" and item.get("sj_div") in {"IS", "CIS"}
    )
    quarter = int(str(row.get("thstrm_amount") or "0").replace(",", ""))
    cumulative = int(str(row.get("thstrm_add_amount") or quarter).replace(",", ""))
    return quarter, cumulative


def main() -> None:
    load_dotenv()
    api_key = os.getenv("DART_KEY")
    if not api_key:
        raise SystemExit(".env에 DART_KEY를 입력해야 합니다.")

    raw = [fetch_revenue(api_key, code) for code in REPORT_CODES]
    cumulative = [raw[0][1], raw[1][1], raw[2][1], raw[3][0]]
    standalone = [cumulative[0], *(cumulative[index] - cumulative[index - 1] for index in range(1, 4))]
    result = pd.DataFrame(
        {"quarter": ["1Q", "2Q", "3Q", "4Q"], "cumulative": cumulative, "standalone": standalone}
    )
    if int(result["standalone"].sum()) != cumulative[-1]:
        raise ValueError("단일 분기 합계와 연간 값이 일치하지 않습니다.")
    print(result.to_string(index=False))


if __name__ == "__main__":
    main()

계정 ID와 재무제표 구분을 먼저 고정한 뒤 누적 열을 숫자로 변환합니다. 회사가 단일 분기 열을 함께 제공하더라도 누적값의 차이와 일치하는지 확인하면 열 선택 오류를 빨리 찾을 수 있습니다.

자주 생기는 오류

  1. 반기 누적과 3분기 누적을 더해 같은 1·2분기를 중복합니다.
  2. 재무상태표 자산·부채를 누적 손익처럼 차감합니다.
  3. 연결과 별도를 섞은 뒤 차이를 단일 분기 실적으로 오해합니다.
  4. 정정공시 뒤 과거 누적값만 바꾸고 이후 단일 분기를 다시 계산하지 않습니다.

OpenDART 전체 재무제표 개발가이드의 누적·당기 필드를 기준으로 작성했습니다. 이 글은 데이터 정제 방법을 설명하며 특정 기업의 실적 전망을 다루지 않습니다.