들어가며
"이 종목 왜 갑자기 10% 올랐지?"
주가가 급등하거나 급락할 때, 대부분의 경우 답은 공시에 있다. 자사주 매입, 유상증자, 실적 발표, 대표이사 변경 — 상장회사가 의무적으로 시장에 알려야 하는 정보들이다.
문제는 공시를 보려면 DART(금융감독원 전자공시시스템)에 직접 들어가서 찾아봐야 한다는 것이다. 종목 상세 페이지에서 공시까지 한 번에 보여주면 편할 텐데. 그래서 종목 상세의 탭으로 공시 자동 분류 페이지를 만들었다.

DART API 연동
DART는 공시 정보를 조회할 수 있는 공식 API를 제공한다. API 키를 발급받고 종목별 공시 목록을 JSON으로 받아올 수 있다.
API에서 받아오는 정보:
- 공시 날짜
- 공시 제목
- 제출인 (회사명)
- 접수번호 (DART 원문 링크용)
최근 3개월(89일)치를 한 번에 요청하고, 10분 동안 캐시해서 같은 종목을 다시 열 때 API를 또 호출하지 않게 했다.
DART API의 불안정함
이론적으로는 간단하지만, 실전에서는 꽤 귀찮았다. DART API가 생각보다 불안정하다:
- 타임아웃 — 응답이 10초 넘게 안 올 때가 있다
- 서버 다운 — 가끔 아예 연결이 안 된다
- 일시적 오류 — 같은 요청인데 어떨 때는 되고 어떨 때는 안 된다
그래서 3회 재시도 로직을 넣었다. 한 번 실패하면 다시 시도하고, 3번 다 실패하면 마지막에 성공했던 캐시(stale 캐시)를 보여준다. "공시를 못 불러왔습니다"보다는 "조금 전 데이터입니다"가 낫다.
공시 제목만으로 호재/악재 분류
이게 이 기능의 핵심이다. DART API는 공시 제목만 준다. 본문을 분석하려면 PDF를 열어서 파싱해야 하는데, 공시 본문 형식이 제각각이라 현실적으로 불가능하다.
그래서 제목만 보고 분류하기로 했다. 다행히 공시 제목에는 핵심 키워드가 들어간다.
5색 분류 체계
| 색상 | 분류 | 키워드 예시 |
|---|---|---|
| 빨강 | 악재 | 관리종목, 감사의견 거절, 횡령, 감자, 자본잠식, 적자전환 |
| 녹색 | 호재 | 자기주식 취득, 무상증자, 흑자전환, 특별배당, 수주 |
| 보라 | 실적 | 매출액 또는 손익구조, 사업보고서, 감사보고서 |
| 파랑 | 중요 | 유상증자, 전환사채, 합병, 대표이사 변경, 배당 |
| 회색 | 일반 | 주주총회소집, 임원 변동, 증권신고서 |
우선순위는 악재 > 호재 > 실적 > 중요 > 일반. 하나의 공시가 여러 키워드에 해당하면 가장 중요한 분류가 적용된다. "감자 결정"이 들어있으면 다른 키워드가 뭐가 있든 빨간색(악재)이다.
90개+ 정규식 패턴
분류 규칙은 처음 20개로 시작해서, 실제 공시를 확인하며 계속 추가했다. 현재 90개가 넘는 정규식 패턴이 들어있다.
예를 들어 악재 판정:
관리종목|상장폐지→ "주의"감사의견\s*(거절|한정)|부적정→ "감사"횡령|배임|피소|소송\s*제기→ "이슈"부도|회생절차|파산|워크아웃→ "부도"적자전환|영업손실\s*확대→ "실적악화"
호재 판정:
자기주식\s*(취득|소각)→ "자사주"흑자전환|실적\s*급증→ "호실적"단일판매|공급계약\s*체결→ "수주"
처음에는 단순한 문자열 매칭으로 시작했지만, 공시 제목의 띄어쓰기가 일관적이지 않아서 정규식으로 바꿨다. "자기주식 취득"도 있고 "자기주식취득"도 있다.
3번 갈아엎은 분류 규칙
분류 규칙을 처음 만들고 실제 공시에 적용해보니, 오분류가 꽤 있었다.
v1 → v2: "유상증자"의 딜레마
유상증자는 호재인가 악재인가? 회사가 돈을 더 조달하는 건 좋은 건데, 기존 주주 입장에서는 지분이 희석된다. v1에서는 호재로 분류했다가, 실제 시장 반응을 보고 "중요"(파랑)으로 옮겼다. 호불호가 갈리는 공시는 중립적으로 표시하는 게 맞다.
v2 → v3: "배당"의 세분화
"배당"이라는 단어 하나로 다 묶었더니, "현금배당 결정"도 "배당 감소"도 같은 색이었다. v3에서는 "특별배당, 배당 확대"는 녹색(호재), "현금 배당, 결산배당"은 파랑(중요)으로 분리했다.
v3 → v3.1: 정정공시
공시 제목에 [정정], [기재정정], [첨부정정], [재공시]가 붙는 경우가 있다. 처음에는 이걸 무시했는데, 정정공시는 원래 공시 내용이 바뀌었다는 뜻이니까 따로 표시해야 한다. 주황색 "정정" 배지를 추가하고, 분류할 때는 정정 접두사를 제거한 뒤 원래 제목으로 판단하게 했다.
필터 UI
공시가 수십 건이면 전부 보기 힘드니까, 분류별 필터를 만들었다.
6개 필터 버튼: 전체 | 악재 | 호재 | 실적 | 중요 | 일반
각 버튼 옆에 카운트 배지가 붙는다. "악재 3 | 호재 5 | 실적 2" 이런 식. 한눈에 "이 종목에 최근 악재가 몇 개 있었는지" 파악된다.
"악재" 필터를 누르면 빨간색 공시만 남는다. 종목을 처음 볼 때 악재 필터부터 누르는 습관이 생겼다. 최근 3개월 내 감자나 소송이 있었는지 먼저 확인하는 것이다.
삽질 기록
ETF는 공시 탭 자체가 없다
ETF 종목에서는 공시 탭을 아예 숨기기로 했다. ETF 공시는 "설정/해지 현황", "자산운용보고서" 같은 내용이라 일반 투자자에게 실질적 가치가 적다. ETF 투자자가 관심 있는 분배금과 구성종목 정보는 ETF 전용 탭에서 별도로 보여주고 있으니, 공시를 억지로 끼워넣을 필요가 없었다.
공시 제목 띄어쓰기
"자기주식 취득 결정"과 "자기주식취득결정"은 같은 공시인데, 단순 문자열 매칭으로는 둘 중 하나만 잡힌다. 정규식에 \s*를 넣어서 공백 유무와 관계없이 매칭되게 했다.
이것보다 더 까다로운 건, 같은 종류의 공시가 회사마다 제목이 다른 경우다. "타법인주식및출자증권취득결정"과 "타법인 주식 취득 결정"은 같은 건데, 하나의 정규식으로 둘 다 잡으려면 패턴이 점점 복잡해진다.
정리
- DART API — 종목별 최근 3개월 공시 조회, 10분 캐시 + 3회 재시도 + stale 폴백
- 5색 분류 — 악재(빨강) > 호재(녹색) > 실적(보라) > 중요(파랑) > 일반(회색)
- 90개+ 정규식 — 공시 제목만으로 분류, v1→v3.1까지 3번 개선
- 정정공시 — [정정]/[기재정정]/[첨부정정]/[재공시] 4종류 별도 배지
- 필터 UI — 6개 분류별 필터 + 카운트 배지
- 클릭 — 공시 클릭 시 DART 원문으로 이동
공시 분류는 "완벽하게 맞추는 것"보다 "대략적으로 빠르게 파악하는 것"이 목표다. 90개 정규식으로도 100% 정확하지는 않지만, 악재가 빨간색으로 눈에 띄는 것만으로도 투자 판단에 도움이 된다.
다음 편에서는 증권사 리포트를 다룬다.
'바이브 코딩 > 주식 정보 분석 사이트 만들기' 카테고리의 다른 글
| 11편: 증권사 리포트를 모아서 한 눈에 보기 (0) | 2026.03.28 |
|---|---|
| 9편: 시장 지도를 통해 오늘의 주식 시황을 한 눈에 파악하기 (0) | 2026.03.18 |
| 8편: 퀀트 전략 삽질기 - 수많은 실패와 검증의 반복 (0) | 2026.03.17 |
| 7편: 퀀트 전략 만들기 - 기본 전략 3개, 일일 추천, 그리고 성과 추적 (0) | 2026.03.17 |
| 6편: 종목 상세 페이지 - 종목의 모든 정보를 쉽게 찾아서 보자 (0) | 2026.03.16 |