세 회사를 5년치 비교하면 브라우저 창이 15개다
전자공시 사이트(DART)에서 회사 셋을 5년치 나란히 보려고 하면 브라우저 창이 열다섯 개가 된다. 회사 하나에 사업보고서 하나, 사업보고서 하나에 연도 하나. PDF는 백 페이지가 넘고, 재무제표가 어디 있는지 스크롤로 찾아 눈으로 표를 읽고, 작년과 비교하려면 작년 보고서를 또 연다. dartlab에서는 같은 일이 코드 한 줄이다. 게다가 이 글의 코드는 설치 없이 바로 이 브라우저 안에서 파이썬으로 돈다.
문제는 공시가 부실해서가 아니다. 공시는 충분히 자세하다. 문제는 공시가 사람이 한 번 읽으라고 만든 문서라는 데 있다. 비교하고, 잇고, 계산하려면 그 문서를 표로 바꿔야 한다. 그 변환을 매번 손으로 하면 분석은 시작도 못 한다.

dartlab은 그 표 만들기를 대신 해 두는 도구다. 한국의 DART와 미국의 EDGAR에 올라온 공시를 미리 읽어서, 회사별 재무제표를 큰 표로 만들어 둔다. 왼쪽에는 계정 이름이 있고, 오른쪽에는 기간별 숫자가 있다. 그래서 “작년보다 매출이 늘었나”, “5년 동안 영업이익이 좋아졌나”를 손으로 옮겨 적지 않고 바로 볼 수 있다.
이 글은 dartlab을 설치하라는 글이 아니다. 아래 코드 칸은 지금 이 브라우저 안에서 그대로 돈다. 실행 버튼을 누르면 파이썬이 이 페이지 안에서 켜지고, 공시 데이터를 내려받아 계산한다. 서버로 보내는 것이 없으니 회원가입도 없다. 브라우저에서 파이썬이 도는 원리는 Pyodide로 만든 브라우저 dartlab에 따로 적어 두었다.
첫 줄, 회사 하나를 잡는다
dartlab의 모든 길은 회사 하나를 잡는 데서 열린다.
import dartlab
c = dartlab.Company("005930") # 삼성전자. 6자리 숫자는 한국, 티커는 미국으로 자동 판정
c.panel("IS").head(3) # 손익계산서 격자의 첫 세 줄 처음 실행하면 20초쯤 걸린다. 브라우저가 파이썬을 통째로 내려받고 dartlab을 설치하는 시간이다. 한 번 끝나면 그다음 칸부터는 즉시 돈다.
방금 나온 표를 보라. 왼쪽에 계정 이름이, 오른쪽에 분기가 늘어서 있다. 매출액, 매출원가, 매출총이익이 분기별로 정렬되어 있다. 사업보고서에서 이 표를 만들려면 여러 해의 PDF를 열어 숫자를 옮겨 적어야 한다. 여기서는 코드 한 칸이다.
Company를 만드는 순간 어디 공시를 볼지가 정해진다. 6자리 숫자면 한국 DART, 알파벳 티커면 미국 EDGAR다.
c.market # KR 이면 DART, US 면 EDGAR 로 간다 데이터는 어떤 모양으로 쌓여 있나
dartlab에서 처음 봐야 할 표는 세 종류다. 회사 하나를 보는 표, 시장 전체를 보는 표, 공시 밖 데이터다.
첫째, 회사 한 곳의 큰 표. 손익계산서, 재무상태표, 현금흐름표를 엑셀처럼 펼쳐 둔 표다. dartlab은 이 표를 panel이라고 부른다.
bs = c.panel("BS") # 재무상태표. IS 는 손익계산서, CF 는 현금흐름표
bs.head(5) 방금 나온 표를 보면 왼쪽에 자산, 부채, 자본 같은 줄이 있고 오른쪽에 기간별 숫자가 붙어 있다. 사업보고서에서 눈으로 찾던 숫자가 코드로 다시 볼 수 있는 표가 된 것이다.
둘째, 시장 전체 표. 회사 하나가 아니라 여러 회사를 한 번에 보는 표다. “매출이 늘고 있는 회사가 뭐가 있나”를 보려면 회사 하나씩 여는 것보다 시장 표를 먼저 보는 편이 빠르다. dartlab에서는 이걸 scan으로 본다.
g = dartlab.scan("growth") # 전상장사 성장 지표를 한 표로
g.head(5) 이 한 줄은 여러 회사의 성장 지표를 표로 보여 준다. 브라우저에서도 돈다. 다만 브라우저에서는 가벼운 파일만 내려받기 때문에, 설치해서 쓰는 파이썬보다 볼 수 있는 항목이 적다.
아래 표는 방금 그 스캔의 결과다. 실행 버튼을 누르지 않아도, 이 페이지가 열리는 동안 브라우저 안 dartlab이 전상장사 성장 지표를 계산해 채운다. 미리 구워 둔 그림이 아니라 지금 값이고, 종목 수가 배포 시점에 정해지지 않으니 빌드로는 담을 수 없는 표다.
셋째, 공시 밖 데이터. 주가, 수급, 뉴스, 지수 같은 것들이다. 재무제표는 회사가 낸 공시에서 오고, 주가는 거래소나 데이터 업체에서 온다. 나오는 곳도 다르고 바뀌는 속도도 다르다. 처음에는 재무제표부터 보는 것이 안전하다.
브라우저에서 안 되는 것을 먼저 말해 둔다
여기서 정직하게 짚고 넘어갈 것이 있다. 주가와 뉴스 수집은 이 브라우저에서 안 된다.
이유는 dartlab이 부족해서가 아니라 브라우저의 보안 정책 때문이다. 웹페이지는 아무 사이트에나 요청을 보낼 수 없다. 주가를 주는 서버들은 대개 다른 도메인에 있고, 브라우저는 그 요청을 막는다. 실행 스레드를 마음대로 만드는 것도 막혀 있다.
같은 이유로 회사 목록을 새로 내려받아 이름을 찾는 작업은 브라우저에서 제한될 수 있다. 코드와 회사명을 잇는 표는 거래소 목록을 받아 와야 한다. 그래서 이 연재의 브라우저 실습은 먼저 종목코드로 회사를 고정한다. 설치본에서는 dartlab.listing(), dartlab.nameToCode("삼성전자"), dartlab.Company("삼성전자")처럼 회사명으로도 찾을 수 있다.
실시간 시세, 수급, 뉴스, 지수 같은 수집도 파이썬을 실제로 설치한 환경에서만 된다.
pip install dartlab 설치와 첫 설정은 dartlab 쉽게 시작하기에 정리해 두었다. 패키지 자체는 PyPI에 있고, 소스는 GitHub에서 볼 수 있다.
설치본에서는 위 모든 것이 열린다. 이 브라우저에서 바로 열리는 것은 공시에서 나온 것들이다. 재무제표 표, 계정 조회, 재무 분석, 신용등급, 보고서, 그리고 전상장사 스캔의 일부다. 이 글과 다음 글들이 가르치는 것도 그 범위다.
이걸 흐리게 말하면 독자는 첫 실행부터 막힌다. 그래서 매 편마다 “브라우저에서 되는 것”과 “설치해야 되는 것”을 나눠 적는다.
데이터는 어떻게 갱신되고 운영되나
도구가 아무리 좋아도 숫자가 낡으면 소용없다. dartlab의 데이터는 세 단계로 움직인다.
수집. 공시가 새로 올라오면 파일을 받아 둔다. 한국은 OpenDART, 미국은 EDGAR에서 온다. 처음 받은 파일은 고치지 않고 보관한다. 나중에 표를 잘못 만들었다는 걸 알아도 원본이 있으면 다시 만들 수 있다.
가공. 받은 공시를 사람이 보기 좋은 표로 바꾼다. 어떤 회사는 “매출액”이라고 쓰고, 어떤 회사는 “영업수익”이라고 쓴다. dartlab은 이런 이름 차이를 표준 이름으로 이어 붙인다. 이 부분은 사람이 검수한다. 자동으로 대충 맞추면 틀린 숫자가 조용히 섞인다.
배포. 만들어진 표는 공개 데이터 저장소에 올라간다. 여러분이 위 코드를 실행할 때 브라우저가 내려받는 것이 그 파일이다. 같은 회사, 같은 기간을 열면 같은 숫자를 보게 하려는 것이다.
중요한 건 하나다. 숫자 복사본을 여러 군데 만들지 않는다. 복사본이 많아지면 어떤 숫자가 진짜인지 금방 헷갈린다.
손익계산서 표를 열어 본다
말로만 하면 와닿지 않는다. 손익계산서를 직접 열어 본다.
is_y = c.panel("IS", freq="Y") # 손익계산서. 연간 기준
is_y.head(5) panel은 표 전체를 연다. "IS"는 손익계산서이고, freq="Y"는 연간 숫자를 보겠다는 뜻이다. 분기로 보고 싶으면 freq="Q"로 바꾸면 된다. 나중에 특정 항목 한 줄만 보고 싶을 때 select를 쓰지만, 처음에는 전체 표를 먼저 봐야 한다.
여기까지 왔다면 할 일은 분명하다. 회사를 고르고, 재무제표 큰 표를 열고, 필요한 기간을 고른다. 이 세 가지가 dartlab 사용의 시작이다.
이렇게 오해하면 안 된다
세 가지를 미리 정리해 둔다.
첫째, dartlab은 투자 판단을 대신 하지 않는다. 신용등급도, 분석 점수도 공시 데이터로 계산한 숫자일 뿐이다. 그 숫자가 왜 그렇게 나왔는지 되짚을 수 있게 만드는 것이 목적이고, 사라는 신호를 주는 것이 목적이 아니다.
둘째, 공시 데이터에는 시차가 있다. 사업보고서는 결산 이후에 나온다. 오늘 주가가 움직인 이유가 오늘 공시에 있을 리 없다. 공시는 이미 벌어진 일의 기록이다.
셋째, 격자에 있는 항목이 곧 회사의 전부는 아니다. 회사가 공시에 적지 않은 것은 격자에도 없다. 없는 항목을 dartlab이 추측해 채우지 않는다. 비어 있으면 비어 있다고 말한다.
다음 편에서 할 것
여기까지 회사를 잡고, 큰 표를 열고, 데이터가 어떻게 갱신되는지를 봤다. 다음 편 재무제표, 파이썬 한 줄은 손을 더 깊이 넣는다. 재무제표를 실제로 불러오고, 계정과 기간 값을 확인하고, 그것을 표로 읽는 법이다.
그 전에, 위 코드 칸 중 아무거나 회사 코드를 바꿔 다시 실행해 보라. 005930 자리에 000660을 넣으면 SK하이닉스가 된다. 첫 코드 칸 아래의 “노트북 생성하기”를 누르면 이 글 전체가 여러분의 노트북 한 권이 되고, 거기서는 마음대로 고치고 칸을 더하고 저장할 수 있다.
오늘 기억할 한 줄: 회사를 잡고, 큰 표를 열고, 기간을 고른다. dartlab의 모든 편이 이 세 동작 위에서 돈다.