본문 바로가기

BLOG/오픈소스 리뷰기

[오픈소스 리뷰기] DART 전자공시시스템(2) - DART-FSS라이브러리 활용하기!

 

오프소스 리뷰 : 슬기로운 오픈소스 사용법 리뷰해드립니다!
#8 DART 전자공시시스템(2) - DART-FSS라이브러리 활용하기!

 

 

 

안녕하세요. 디노랩스입니다!

어제 OPEN DART 전자공시시스템에 대해서 말씀드렸고, 오늘은 그 활용법들을 소개해드릴건데요.

 

앞서 오픈API 인증키를 아직 신청하지 않으셨다면 ▽▼아래글에 자세하게 설명되어있습니다!▽▼

2021.11.11 - [BLOG/오픈소스 리뷰기] - [오픈소스 리뷰기] DART 전자공시시스템(1) - API 이용하기

 

 

이전 실습과 같이 API를 직접 호출한 뒤 json, xml 형태의 데이터를 파싱하여 정보를 수집할 수도 있지만, 조금 더 편리하게 수집할 수 있는 DART-FSS 라는 라이브러리가 있습니다.

이번에는 이 DART-FSS 라이브러리를 활용하여 조금 더 쉽게 데이터를 수집하는 법을 알려드릴게요!!
관련 내용과 자세한 사용법은 아래 링크에서 확인할 수 있습니다.

https://dart-fss.readthedocs.io/en/latest/index.html

 

DART-FSS — dart-fss documentation v0.3.10 documentation

© Copyright 2021, Sungwoo Jo Revision dcf5cf7e.

dart-fss.readthedocs.io

 

 

DART-FSS 라이브러리를 사용하기 위해서는 해당 라이브러리를 설치해야 합니다.

설치 후에는 반드시 런타임을 초기화 해주세요!!

 

!pip install dart-fss

 

 

위에서 알려드린 dart-fss 공식 문서에 들어가보시면 Quick Starts라는 이름으로 아래의 코드를 써두었습니다.

우선 아래의 코드를 그대로 활용하여 코드를 실행해봅시다.

※주의!! 아래 코드를 실행하면 오랜 시간이 걸립니다!!

 

 

import dart_fss as dart

# Open DART API KEY 설정
api_key = 'API key 값 넣기'   # 이전에 발급받은 DART API key를 입력해주세요.
dart.set_api_key(api_key=api_key)

# DART 에 공시된 회사 리스트 불러오기
corp_list = dart.get_corp_list()

# 삼성전자 검색
samsung = corp_list.find_by_corp_name('삼성전자', exactly=True)[0]

# 2018년부터 연간 연결재무제표 불러오기
fs = samsung.extract_fs(bgn_de='20180101')

# 재무제표 검색 결과를 엑셀파일로 저장 ( 기본저장위치: 실행폴더/fsdata )
fs.save()

 

위의 코드를 실행하시면 fsdata라는 폴더 안에 엑셀 파일이 하나 만들어집니다.
총 8개의 시트가 있는데 각각 ‘bs’ 재무상태표, ‘is’ 손익계산서, ‘cis’ 포괄손익계산서, ‘cf’ 현금흐름표를 뜻합니다.

 

위와 같이 dart-fss 라이브러리를 활용하면 직접 xml 데이터를 파싱하지 않고도 손쉽게 데이터를 수집할 수 있습니다.
이제 dart-fss 라이브러리를 활용하여 DART API 에서 제공하는 다양한 데이터를 수집해보겠습니다.

 

 

 

01_공시된 기업정보 불러오기

 

https://dart-fss.readthedocs.io/en/latest/dart_corp.html#

 

기업정보검색 — dart-fss documentation v0.3.10 documentation

© Copyright 2021, Sungwoo Jo Revision dcf5cf7e.

dart-fss.readthedocs.io

아래의 코드를 이용하면 DART에 공시된 모든 회사의 [회사 코드] + 회사 이름을 리스트 형태로 받을 수 있습니다.

 

 

corp_list = dart.get_corp_list()
# 리스트의 첫번째 종목정보 출력
print(corp_list[0])

# 리스트 종목 갯수 출력
print(len(corp_list))

# corp_list 자료형 확인
print(type(corp_list))

 

 

사실 우리가 위에서 얻게된 corp_list는 클래스이며, 이 클래스에서 사용되는 메소드(기능)를 따로 가지고 있습니다.
즉, corp_list.함수의 형태로 몇 가지 함수를 사용할 수 있습니다.

 

# 삼성전자를 이름으로 찾기 ( 리스트 반환 )
samsung = corp_list.find_by_corp_name('삼성전자', exactly=True)[0]
print(samsung)
print()

# 증권 코드를 이용한 찾기
samsung = corp_list.find_by_stock_code('005930')
print(samsung)
print()

# 다트에서 사용하는 회사코드를 이용한 찾기
samsung = corp_list.find_by_corp_code('00126380')
print(samsung)
print()

# "삼성"을 포함한 모든 공시 대상 찾기
corps = corp_list.find_by_corp_name('삼성')
print(corps)
[00126380]삼성전자

[00126380]삼성전자

[00126380]삼성전자

[[00434270]삼성인덱스프리미엄30혼합형뮤추얼펀드, [00126502]삼성콘크리트공업, [00315179]삼성코닝마이크로옵틱스, [00427580]삼성프론티어제십이차유동화전문유한회사, [00434377]삼성중소형알짜주식형뮤추얼펀드, [00434517]삼성인덱스프리미엄주식형뮤추얼펀드, [00427526]삼성신한아하론일차유동화전문유한회사, [00434678]삼성팀파워90주식형뮤추얼펀드, [00429746]삼성프론티어제십삼차유동화전문유한회사, [00436162]광주삼성의료센타, [00359881]삼성프론티어제삼차유동화전문유한회사, [00246462]삼성색소공업, [00356316]삼성공영, [00384674]삼성프론티어제칠차유동화전문유한회사, [00388227]삼성문화재단, [00180582]삼성특수화학, [00474366]삼성초이스유동화전문유한회사, [00376833]삼성프론티어제육차유동화전문유한회사, [00198129]삼성사, [00267483]삼성프라임성장형뮤추얼펀드, [00267465]삼성그랑프리전환형뮤추얼펀드, [00387316]삼성프론티어제팔차유동화전문유한회사, [00180564]삼성제지, [00351205]삼성프론티어제이차유동화전문유한회사, [00267429]삼성프라임플러스이호뮤추얼펀드, [00267386]삼성프라임플러스증권회사, [00429409]삼성신한아하론이차유동화전문유한회사, [00218450]삼성생명서비스, [00373818]삼성프론티어제사차유동화전문유한회사, [00373827]삼성프론티어제오차유동화전문유한회사, [00380890]삼성뉴트리션센터, [00116338]삼성투자신탁운용, [00196963]삼성종합토건, [00180537]삼성그라비아인쇄, [00659356]삼성정유, [00104096]삼성광주전자, [00362414]이삼성인터내셔널, [00567231]삼성철강, [00232654]삼성가구, [00758392]삼성엘이디, [00339063]삼성수산, [00721981]삼성디지털이미징, [00606974]삼성이엔지, [00126265]삼성석유화학, [00762173]143삼성미타유동화전문유한회사, [00865285]삼성복지상조, [00687410]삼성모바일디스플레이, [00509200]삼성에스오씨제일차유동화전문유한회사, [00611055]삼성레저, [00931764]티와이삼성동제일차, [00207728]삼성에스엔에스, [00691990]삼성로하스, [00575647]삼성디와이, [00460114]삼성씨케이, [00551726]삼성종합건설, [00126496]삼성코닝, [00577724]삼성레이저, [00361761]삼성네트웍스, [00624961]삼성전선, [00626871]삼성화장품, [00126210]삼성무역, [00126353]삼성인쇄, [00346595]삼성프론티어제일차유동화전문유한회사, [00274456]삼성캐피탈, [00482851]삼성금은, [00432704]삼성산업개발, [00496988]삼성씨앤지하우징, [00362405]이삼성, [00126140]삼성건설, [00457244]삼성신한프론티어제팔차유동화전문유한회사, [00230559]삼성상용차, [00366678]삼성주택, [00466376]삼성오토론제삼차유동화전문유한회사, [00513212]삼성프론티어제십오차유동화전문유한회사, [00349103]삼성오엘이디, [00260851]삼성코람유동화전문, [00117665]삼성투자신탁증권, [00442464]삼성프론티어제십사차유동화전문유한회사, [00453248]삼성오토론제이차유동화전문유한회사, [00393706]삼성프론티어제구차유동화전문유한회사, [00926054]해피뷰삼성, [00240042]도서출판삼성당, [00453293]삼성AST, [00590275]삼성에이치제이에스, [00500935]도시바삼성스토리지테크놀러지코리아, [00126229]삼성물산, [00545682]삼성신한사차유동화전문유한회사, [00459525]삼성신한아하론삼차유동화전문유한회사, [00440819]삼성오토론제일차유동화전문유한회사, [00408123]삼성프론티어제십일차유동화전문유한회사, [00267447]삼성프라임플러스3호뮤추얼펀드, [01150205]삼성플러스상조, [00531315]삼성유통, [00397146]삼성프론티어제십차유동화전문유한회사, [00943486]삼성케미칼코팅, [01182596]삼성산업개발, [00695491]수원삼성축구단, [01032468]삼성홀딩스, [00545822]삼성미트통상, [01328657]삼성디엔씨, [01328897]삼성금거래소홀딩스, [01275133]삼성인더스트리, [01332003]삼성스카이제일차, [01308945]삼성주택, [00526702]삼성문화인쇄, [01213577]르노삼성자동차사상정비사업소, [01222928]삼성우드산업, [00456430]삼성홈이엔씨, [01364923]삼성택시자동차, [01244531]삼성유리공업, [01082384]삼성금속, [01364507]베올리아삼성오퍼레이팅, [01408175]삼성알앤티, [00235305]삼성식품, [01297825]삼성금속, [00814476]삼성에어컨특판, [00878155]삼성정공, [01135871]삼성메디코스, [01380569]삼성화스나, [01448173]호암삼성, [01382691]삼성건축, [00689205]삼성해운, [01194847]삼성헤지자산운용, [00605771]삼성의료설비, [01326871]지케이삼성, [00451675]삼성금박카드라인, [01367461]삼성파워텍, [00126414]삼성제약, [01495995]삼성케미칼, [00126292]삼성카드, [00924214]삼성정공, [01503939]삼성티엠에스, [01373620]삼성산업개발, [01507661]삼성팜, [01020339]삼성에너지, [00104856]삼성증권, [00998608]삼성카드고객서비스, [01094121]삼성생명금융서비스보험대리점, [01336683]삼성파로스호텔, [00135254]삼성발레오써멀시스템스, [01473203]삼성월드, [01511309]삼성알미늄, [01422698]삼성회계법인, [00126256]삼성생명, [01455669]삼성교역, [01384088]삼성홀딩스, [00234768]삼성여객, [00301574]삼성벤처투자, [00930039]삼성포장, [00558279]삼성생명서비스손해사정, [01345812]삼성전자서비스씨에스, [00217798]삼성경제연구소, [00663085]삼성임업, [00923303]삼성의료고무, [01381717]삼성하우징, [01495463]삼성보안공사, [00236395]삼성화학, [00258999]삼성전자서비스, [00836797]삼성팩, [00568692]삼성석회, [01024478]삼성기전, [00678777]삼성정밀, [00893765]삼성, [00120988]삼성메디슨, [00425962]삼성화재서비스손해사정, [00907679]삼성바이오에피스, [01373383]삼성파워텍, [00362593]삼성에프.씨, [01460980]삼성씨에스, [01214503]삼성금거래소, [01176124]삼성에이아이윈, [00126186]삼성에스디에스, [01012473]삼성메디칼, [00126478]삼성중공업, [00239310]삼성산업, [00149655]삼성물산, [00180546]삼성라이온즈, [00486565]삼성냉장, [00126362]삼성SDI, [00932444]삼성코닝어드밴스드글라스, [01159631]삼성화재금융서비스보험대리점, [00126159]삼성공업, [00252074]삼성전자판매, [00126326]삼성여객자동차, [00623883]삼성테이프, [00483407]삼성잉크, [00854809]삼성금속, [00366997]삼성전자로지텍, [00616546]삼성스텐레스상공, [00965017]삼성텍, [00215657]삼성포리머, [00303323]삼성콘크리트, [01501135]삼성에스엘, [00492052]삼성엠케이, [00197777]삼성정밀공업, [01300208]삼성개발, [00487555]삼성포장, [00361105]르노삼성자동차, [01102466]삼성건설, [00914545]삼성리사이클링, [00423690]삼성출판사, [00126432]삼성제침, [00455714]삼성베올리아인천환경, [00995258]삼성웰스토리, [00126371]삼성전기, [00126201]삼성공조, [00173263]삼성공업, [01549959]삼성스마트하우징, [00951412]삼성에스알에이자산운용, [00912006]삼성디스플레이, [01556524]삼성하나로, [01528530]삼성스팩4호, [01562659]삼성에코텍, [01534522]삼성머스트스팩5호, [00431787]삼성화재애니카손해사정, [00126308]삼성엔지니어링, [01569731]에이치에스삼성, [01564189]삼성골드, [00126380]삼성전자, [01194731]삼성액티브자산운용, [00260453]삼성자산운용, [00245047]삼성선물, [00139214]삼성화재해상보험, [00877059]삼성바이오로직스]

 

 

# "삼성"을 포함한 모든 공시 대상중 코스피 및 코스닥 시장에 상장된 공시 대상 검색(Y: 코스피, K: 코스닥, N:코넥스, E:기타)
corps = corp_list.find_by_corp_name('삼성', market=['Y','K']) # 아래와 동일
corps = corp_list.find_by_corp_name('삼성', market='YK')
print(corps)
print()

# "휴대폰" 생산품과 연관된 공시 대상
corps = corp_list.find_by_product('휴대폰')
print(corps)
print()

# "휴대폰" 생산품과 연관된 공시 대상 중 코스피 시장에 상장된 대상만 검색
corps = corp_list.find_by_product('휴대폰', market='Y')
print(corps)
print()

# 섹터 리스트 확인
print(corp_list.sectors)
print()

# "텔레비전 방송업" 섹터 검색
corps = corp_list.find_by_sector('텔레비전 방송업')
print(corps)
[[00126414]삼성제약, [00126292]삼성카드, [00104856]삼성증권, [00126256]삼성생명, [00126186]삼성에스디에스, [00126478]삼성중공업, [00149655]삼성물산, [00126362]삼성SDI, [00423690]삼성출판사, [00126371]삼성전기, [00126201]삼성공조, [01528530]삼성스팩4호, [01534522]삼성머스트스팩5호, [00126308]삼성엔지니어링, [00126380]삼성전자, [00139214]삼성화재해상보험, [00877059]삼성바이오로직스]

[[00178790]동양이엔피, [00445799]서원인텍, [01035678]와이제이엠게임즈, [01013311]민앤지, [00838005]서진시스템, [00755739]파인테크닉스, [00378628]KH바텍, [00330044]캠시스, [00243757]인포뱅크, [00872452]에이치엔티, [01117246]EMB, [00219486]신세계I&C, [00491415]인포바인, [00479705]EMW, [01031502]코아시아옵틱스, [00364306]성우전자, [00483735]해성옵틱스, [00542898]하이소닉, [00536329]디지탈옵틱, [00575106]씨유테크, [00562360]에스맥, [00126380]삼성전자, [00408956]제넨바이오, [00609634]아이엠]

[[00219486]신세계I&C, [00126380]삼성전자]

['1차 비철금속 제조업', '1차 철강 제조업', '가구 제조업', '가전제품 및 정보통신장비 소매업', '가정용 기기 제조업', '가죽, 가방 및 유사제품 제조업', '개인 및 가정용품 임대업', '건물 건설업', '건물설비 설치 공사업', '건축기술, 엔지니어링 및 관련 기술 서비스업', '건축자재, 철물 및 난방장치 도매업', '경비, 경호 및 탐정업', '고무제품 제조업', '곡물가공품, 전분 및 전분제품 제조업', '골판지, 종이 상자 및 종이용기 제조업', '과실, 채소 가공 및 저장 처리업', '광고업', '교육지원 서비스업', '구조용 금속제품, 탱크 및 증기발생기 제조업', '귀금속 및 장신용품 제조업', '그외 기타 개인 서비스업', '그외 기타 운송장비 제조업', '그외 기타 전문, 과학 및 기술 서비스업', '그외 기타 제품 제조업', '금속 주조업', '금융 지원 서비스업', '기계장비 및 관련 물품 도매업', '기록매체 복제업', '기반조성 및 시설물 축조관련 전문공사업', '기초 의약물질 및 생물학적 제제 제조업', '기초 화학물질 제조업', '기타 과학기술 서비스업', '기타 교육기관', '기타 금속 가공제품 제조업', '기타 금융업', '기타 비금속 광물제품 제조업', '기타 비금속광물 광업', '기타 사업지원 서비스업', '기타 상품 전문 소매업', '기타 생활용품 소매업', '기타 섬유제품 제조업', '기타 식품 제조업', '기타 운송관련 서비스업', '기타 전기장비 제조업', '기타 전문 도매업', '기타 전문 서비스업', '기타 정보 서비스업', '기타 종이 및 판지 제품 제조업', '기타 화학제품 제조업', '나무제품 제조업', '낙농제품 및 식용빙과류 제조업', '내화, 비내화 요업제품 제조업', '담배 제조업', '도로 화물 운송업', '도축, 육류 가공 및 저장 처리업', '동물용 사료 및 조제식품 제조업', '무기 및 총포탄 제조업', '무점포 소매업', '반도체 제조업', '방적 및 가공사 제조업', '보험 및 연금관련 서비스업', '보험업', '봉제의복 제조업', '부동산 임대 및 공급업', '비료, 농약 및 살균, 살충제 제조업', '비알코올음료 및 얼음 제조업', '사업시설 유지·관리 서비스업', '사진장비 및 광학기기 제조업', '산업용 기계 및 장비 임대업', '산업용 농·축산물 및 동·식물 도매업', '상품 종합 도매업', '상품 중개업', '생활용품 도매업', '서적, 잡지 및 기타 인쇄물 출판업', '석유 정제품 제조업', '석탄 광업', '선박 및 보트 건조업', '섬유, 의복, 신발 및 가죽제품 소매업', '섬유제품 염색, 정리 및 마무리 가공업', '소프트웨어 개발 및 공급업', '수산물 가공 및 저장 처리업', '스포츠 서비스업', '시멘트, 석회, 플라스터 및 그 제품 제조업', '시장조사 및 여론조사업', '신발 및 신발 부분품 제조업', '신탁업 및 집합투자업', '실내건축 및 건축마무리 공사업', '악기 제조업', '알코올음료 제조업', '어로 어업', '여행사 및 기타 여행보조 서비스업', '연료 소매업', '연료용 가스 제조 및 배관공급업', '영상 및 음향기기 제조업', '영화, 비디오물, 방송프로그램 제작 및 배급업', '오디오물 출판 및 원판 녹음업', '운동 및 경기용구 제조업', '운송장비 임대업', '유리 및 유리제품 제조업', '유원지 및 기타 오락관련 서비스업', '육상 여객 운송업', '은행 및 저축기관', '음·식료품 및 담배 도매업', '음·식료품 및 담배 소매업', '음식점업', '의료용 기기 제조업', '의료용품 및 기타 의약 관련제품 제조업', '의복 액세서리 제조업', '의약품 제조업', '인쇄 및 인쇄관련 산업', '일반 교습 학원', '일반 목적용 기계 제조업', '일반 및 생활 숙박시설 운영업', '일차전지 및 축전지 제조업', '자동차 부품 및 내장품 판매업', '자동차 신품 부품 제조업', '자동차 재제조 부품 제조업', '자동차 차체 및 트레일러 제조업', '자동차 판매업', '자동차용 엔진 및 자동차 제조업', '자료처리, 호스팅, 포털 및 기타 인터넷 정보매개 서비스업', '자연과학 및 공학 연구개발업', '작물 재배업', '재 보험업', '전구 및 조명장치 제조업', '전기 및 통신 공사업', '전기 통신업', '전기업', '전동기, 발전기 및 전기 변환 · 공급 · 제어 장치 제조업', '전문디자인업', '전자부품 제조업', '절연선 및 케이블 제조업', '제재 및 목재 가공업', '종합 소매업', '증기, 냉·온수 및 공기조절 공급업', '직물직조 및 직물제품 제조업', '창작 및 예술관련 서비스업', '철도장비 제조업', '초등 교육기관', '측정, 시험, 항해, 제어 및 기타 정밀기기 제조업; 광학기기 제외', '컴퓨터 및 주변장치 제조업', '컴퓨터 및 통신장비 수리업', '컴퓨터 프로그래밍, 시스템 통합 및 관리업', '텔레비전 방송업', '토목 건설업', '통신 및 방송 장비 제조업', '특수 목적용 기계 제조업', '펄프, 종이 및 판지 제조업', '편조원단 제조업', '편조의복 제조업', '폐기물 처리업', '플라스틱제품 제조업', '합성고무 및 플라스틱 물질 제조업', '항공 여객 운송업', '항공기,우주선 및 부품 제조업', '해상 운송업', '해체, 선별 및 원료 재생업', '화학섬유 제조업', '환경 정화 및 복원업', '회사 본부 및 경영 컨설팅 서비스업']

[[00349097]케이티스카이라이프, [00657987]KMH, [00130772]SBS, [00249441]씨씨에스, [00265324]CJ ENM, [00263371]한국경제TV, [00650629]SBS미디어홀딩스, [00208134]KNN, [00403632]현대퓨처넷, [00204642]티비씨, [00222532]LG헬로비전]

 

 

 

02_재무제표 데이터

 

위에서 samsung이란 변수에 회사 정보를 저장했습니다.
사실 samsung이란 변수도 dart_fss.corp.Corp 클래스의 인스턴스(객체)로서 메소드(기능)를 사용할 수 있습니다.
우선 재무제표를 정보를 가져오는 extract_fs( ) 메소드를 사용해 보겠습니다.

 

extract_fs() 메소드는 다음과 같은 parameter를 사용합니다.
bgn_de(검색 시작일자)를 제외한 모든 parameter는 optional(선택사항)이며 bgn_de 파라미터는 반드시 입력해야합니다.

 

 

# 2018년 1월 1일부터 현재까지 연간 연결재무제표 검색
fs = samsung.extract_fs(bgn_de='20180101')
fs
# 2018년 1월 1일부터 현재까지 분기 연결재무제표 검색 (연간보고서, 반기보고서 포함)
fs_quarter = samsung.extract_fs(bgn_de='20180101', report_tp='quarter')
fs_quarter
# 2018년 1월 1일부터 현재까지 개별재무제표 검색
fs_separate = samsung.extract_fs(bgn_de='20180101', separate=True)
fs_separate
# 재무제표 검색 결과를 엑셀파일로 저장 (기본저장위치: 실행폴더/fsdata)
fs.save()

 

 

(1)손익계산서

 

위에서 수집한 연간 연결재무제표 중에서 IS(손익계산서)만 데이터프레임으로 가져와보겠습니다.

df_is = fs['is']
df_is

 

손익계산서 데이터프레임을 출력해보니 데이터가 보기 쉽게 정리되지 않았습니다.
데이터를 보기 쉽게 정리해보겠습니다.

 

import pandas as pd

# index와 data 분리하여 정리
index = df_is['[D310000] Income statement, by function of expense - Consolidated financial statements (Unit: KRW)']['label_ko']
df_index = pd.DataFrame(index)
df_data = df_is[['20200101-20201231','20190101-20191231','20180101-20181231','20170101-20171231','20160101-20161231','20150101-20151231']].droplevel(1, axis=1)

# index와 data 합치기
income_statement = pd.merge(df_index, df_data, left_index=True, right_index=True)

# 필요한 열만 가져오기
income_statement.columns = ['Label','2020','2019','2018','2017','2016','2015']
income_statement

 

# 정리된 데이터프레임을 csv 또는 excel 파일로 저장할 수도 있습니다.
income_statement.to_csv('삼성전자_손익계산서_15-20.csv', index=False)
income_statement.to_excel('삼성전자_손익계산서_15-20.xlsx', index=False)

 

이제 깔끔해진 데이터프레임을 활용하여 매출 증감률, 영업이익 증감률, 영업이익률 증감률을 나타내는 간단한 시각화를 해보겠습니다.

 

# Label을 데이터프레임의 index로 사용
# income_statement.set_index('Label', inplace=True)

sales_op_df = pd.DataFrame(income_statement.loc[['수익(매출액)','영업이익'], ['2020','2019','2018','2017','2016','2015']]).transpose().sort_index(ascending=True)

# 영업이익률
sales_op_df['영업이익률'] = sales_op_df['영업이익']/sales_op_df['수익(매출액)']

# 전년 매출액,영업이익,영업이익률
sales_op_df[['전년매출액','전년영업이익','전년영업이익률']] = sales_op_df[['수익(매출액)','영업이익','영업이익률']].shift(1)

# 매출액 증감률
sales_op_df['매출액증감률'] = (sales_op_df['수익(매출액)'] - sales_op_df['전년매출액'])/sales_op_df['전년매출액']
sales_op_df['영업이익증감률'] = (sales_op_df['영업이익'] - sales_op_df['전년영업이익'])/sales_op_df['전년영업이익']
sales_op_df['영업이익률증감률'] = (sales_op_df['영업이익률'] - sales_op_df['전년영업이익률'])/sales_op_df['전년영업이익률']

# 2015년 정보 제외
sales_final_df = sales_op_df.iloc[1:]
sales_final_df

 

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# 마이너스 기호 표기
matplotlib.rcParams['axes.unicode_minus'] = False

plt.figure(figsize = (12,8))
plt.plot(sales_final_df[['매출액증감률','영업이익증감률','영업이익률증감률']])
plt.legend(['change_of_sales','change_of_operating_profit','change_of_operating_margin'])
plt.grid(True)
plt.show()

 

 

(2)재무상태표

 

이번에는 위에서 수집한 연간 연결재무제표 중에서 재무상태표(BS)만 데이터프레임으로 가져와보겠습니다.

 

df_bs = fs['bs']
df_bs

 

재무상태표 역시 보기 쉽게 정리되지 않았습니다.
데이터를 보기 쉽게 정리해보겠습니다.

 

import pandas as pd

# index와 data 분리하여 정리
index = df_bs['[D210000] Statement of financial position, current/non-current - Consolidated financial statements (Unit: KRW)']['label_ko']
df_index = pd.DataFrame(index)
df_data = df_bs[['20201231','20191231','20181231','20171231','20161231','20151231']].droplevel(1, axis=1)

# index와 data 합치기
bs_statement = pd.merge(df_index, df_data, left_index=True, right_index=True)

# 필요한 열만 가져오기
bs_statement.columns = ['Label','2020','2019','2018','2017','2016','2015']
bs_statement

 

재무상태표 역시 원하는 항목의 변화를 시각화하여 표현할 수 있습니다.

 

손익계산서, 재무상태표 이외에도 포괄손익계산서, 현금흐름표를 아래 코드를 활용하면 데이터프레임으로 나타낼 수 있습니다.

 

 

(3)포괄손익계산서

 

df_cis = fs['cis']
df_cis

 

마찬가지로 보기 어렵게 되어있죠? 

동일한 방법으로 데이터를 정리해 보겠습니다.

 

import pandas as pd

# index와 data 분리하여 정리
index = df_cis['[D410000] Statement of comprehensive income - Consolidated financial statements (Unit: KRW)']['label_ko']
df_index = pd.DataFrame(index)
df_data = df_cis[['20200101-20201231','20190101-20191231','20180101-20181231','20170101-20171231','20160101-20161231','20150101-20151231']].droplevel(1, axis=1)

# index와 data 합치기
cis_statement = pd.merge(df_index, df_data, left_index=True, right_index=True)

# 필요한 열만 가져오기
cis_statement.columns = ['Label','2020','2019','2018','2017','2016','2015']

 

cis_statement

 

 

 

(4)현금흐름표

 

df_cf = fs['cf']
df_cf

import pandas as pd

# index와 data 분리하여 정리
index = df_cf['[D520000] Statement of cash flows, indirect method - Consolidated financial statements (Unit: KRW)']['label_ko']
df_index = pd.DataFrame(index)
df_data = df_cis[['20200101-20201231','20190101-20191231','20180101-20181231','20170101-20171231','20160101-20161231','20150101-20151231']].droplevel(1, axis=1)

# index와 data 합치기
cf_statement = pd.merge(df_index, df_data, left_index=True, right_index=True)

# 필요한 열만 가져오기
cf_statement.columns = ['Label','2020','2019','2018','2017','2016','2015']
cf_statement

 

같은 방법으로 깔끔히 정리되었죠?ㅎㅎ

 

 

 

03_공시보고서 데이터

(1)공시보고서 목록

 

이번에는 해당 회사의 공시보고서를 가져오는 search_filings( ) 메소드를 사용해 보겠습니다.

search_filings() 메소드는 다음과 같은 parameter를 사용합니다.

 

# 2019년 3월 1일부터 2019년 5월 31일까지 삼성전자의 모든 공시 정보 조회
reports = samsung.search_filings(bgn_de='20190301', end_de='20190531')
reports
# 2010년 1월 1일부터 현재까지 모든 사업보고서 검색
reports = samsung.search_filings(bgn_de='20100101', pblntf_detail_ty='a001')
reports
# 2010년 1월 1일부터 현재까지 모든 사업보고서의 최종보고서만 검색
reports = samsung.search_filings(bgn_de='20100101', pblntf_detail_ty='a001', last_reprt_at='Y')
reports
# 2010년 1월 1일부터 현재까지 사업보고서, 반기보고서, 분기보고서 검색
reports = samsung.search_filings(bgn_de='20100101', pblntf_detail_ty=['a001', 'a002', 'a003'])
reports

 

 

 

(2)공시보고서 정보

 

이번에는 보고서 검색 결과로부터 특정 보고서를 선택하여 정보를 수집해보겠습니다.

# 가장 오래된 보고서 선택
oldest_report = reports[-1]
oldest_report
# 가장 최신 보고서 선택
newest_report = reports[0]
newest_report

 

newest_report 변수는 dart_fss.filings.reports.Report 클래스의 인스턴스(객체)로서 메소드(기능)를 사용할 수 있습니다.
첨부파일 목록을 불러오는 extract_attached_files() 메서드, 첨부보고서 목록을 불러오는 extract_attached_reports() 메서드 등이 있습니다..

 

type(newest_report)

 

# 첨부파일 목록
newest_report.extract_attached_files()

 

# 첨부보고서 목록
newest_report.extract_attached_reports()

 

 

 

(3)XBRL 데이터

 

각 Report는 XBRL 이라는 형식의 데이터를 포함하고 있습니다.

(참고)
XBRL(eXtensible Business Reporting Language ; 확장성 경영보고언어)은 차세대 인터넷 언어인 XML(eXtensible Markup Language)을 기반으로 복잡한 기업정보를 효율적으로 생성/교환/비교할 수 있도록 만든 기업보고용 국제 표준화 언어입니다. 기업정보의 국제유통을 위해 국가별 제도와 기업별 관습에 따라 서로 다른 양식으로 작성된 기업정보를 이미지로 인식해 인터넷에 올리는 방식(pdf)에서 벗어나 데이터로 정보를 인식하고 공유할 수 있도록 한 체계입니다.
출처 : http://xbrl.or.kr/xbrl%EC%9D%B4%EB%9E%80/

 

XBRL이란? – 한국XBRL본부

XBRL의 특징 XBRL은 정보의 가공을 용이하게 하고 생산된 정보의 호환과 공유를 가능하게 합니다. 다양한 정보원에서 수집된 정보를 분류하여 XBRL방식으로 저장하여 놓으면 서로 다른 형태의 기업

xbrl.or.kr

 

dart-fss 패키지에서 XBRL 파일을 추출하는 방법은 매우 간단합니다.

 

newest_xbrl = newest_report.xbrl
type(newest_xbrl)

 

 

추출된 xbrl 안에는 수 많은 데이터를 포함하고 있습니다.
newest_xbrl 변수 역시 dart_fss.xbrl.dart_xbrl.DartXbrl 클래스의 인스턴스(객체)로서 메소드(기능)를 사용할 수 있습니다.
https://dart-fss.readthedocs.io/en/latest/dart_xbrl.html#dartxbrl

 

XBRL 데이터 추출 — dart-fss documentation v0.3.10 documentation

© Copyright 2021, Sungwoo Jo Revision dcf5cf7e.

dart-fss.readthedocs.io

 

 

# 감사 정보
newest_xbrl.get_audit_information()

 

# 작성자 정보
newest_xbrl.get_author_information()

 

# 공시 문서 정보
newest_xbrl.get_document_information()

 

# 연결재무제표 존재 여부 확인
newest_xbrl.exist_consolidated()

 

이외에도 get_cash_flows()(현금흐름표 가져오기), get_financial_statement()(재무상태표 가져오기), get_income_statement()(포괄손익계산서 가져오기) 와 같이 재무제표 데이터를 직접 가져오는 메소드들이 있습니다.
해당 xbrl 데이터에 포함된 현금흐름표를 가져오는 get_cash_flows() 메소드 사용법 예제는 다음과 같습니다.

 

 

# 연결 현금흐름표 추출 (리스트 반환)
list_cf = newest_xbrl.get_cash_flows()
list_cf

 

# 리스트 unpacking
cf = list_cf[0]
cf

 

# 연결 현금흐름표 DataFrame 형태로 출력
cf.to_DataFrame()

 

끝까지 잘 따라오셨나요? :D

이렇게 오픈 DART- FSS라이브러리를 활용해서 여러 데이터들을 수집하고 정리해봤는데요.

언제든지 손쉽게 공시정보들을 확인해 볼 수 있으니 정말 유용할 것 같습니다!