본문 바로가기
python/주식

전자공시 Open API 활용(5), 기업 재무제표 조회 API ( 분기/반기/사업보고서 - 재무상태표, 손익계산서 )

by 맑은안개 2020. 3. 28.

이제까지 전자공시 Open API를 사용하여 다트에 등록되어있는 기업을 검색했다. 다트에서는 기업정보 상세조회시 종목코드가 아닌 고유번호(8)가 필요하므로 고유번호를 알아야 한다.

전 블로그에서 기업명 검색으로 고유번호, 종목코드를 조회하였다. 해당 데이터를 가지고 기업의 재무제표를 조회해본다. 

제공된 데이터를 대형포털사에서 제공하는 재무재표 데이터와 비교하여 문제가 없는지 검증까지 해보자! ( 당연히 없겠지만.. )

 

관련 포스트 시리즈

 

상장기업 재무정보 > 단일회사 주요계정 선택

단일회사 주요계정 선택
상장기업 재무정보 > 단일회사 주요계정 개발가이드

예시 검색으로 삼성전자(고유번호:00126380)를 검색한다. ( 포스팅 시점 2019년도 삼성전자 사업보고서가 제출되지 않았으므로 2018년도 보고서를 조회한다. )

import requests

URL = 'https://opendart.fss.or.kr/api/fnlttSinglAcnt.json'
PARAMS = {
  'crtfc_key': 'Insert your crtfc key', # API 인증키
  'corp_code': '00126380', # 삼성전자 고유번호
  'bsns_year': '2018', # 사업연도(4자리)
  'reprt_code': '11011', # 사업보고서
}

resp = requests.get(url = URL, params = PARAMS)

# http 정상응답시 처리
if resp.status_code == 200:
  data_json = resp.json()
  
  # 콘솔 output
  data_str = json.dumps(data_json, indent=4, ensure_ascii=False)
  print(data_str)

이전 포스팅에서 HTTP호출로 사용한 urllib가 아닌 requests를 사용하였다. 편리한 유틸을 많이 제공하므로 HTTP 핸들링에선 requests 라이브러리가 가장 많이 사용된다.

 

외부라이브러리이므로 설치가 되어있지 않은경우 pip를 사용하여 아래와 같이 설치한다.

pip install requests

 

위의 코드를 실행하면 requests의 Response객체가 리턴된다. Response객체는 status_code를 반환하는데 이는 http 요청에 대한 응답코드이다. 200은 정상응답코드이다. 

 

OUTPUT

{
    "status": "000",
    "message": "정상",
    "list": [
        {
            "rcept_no": "20190401004781",
            "reprt_code": "11011",
            "bsns_year": "2018",
            "corp_code": "00126380",
            "stock_code": "005930",
            "fs_div": "CFS",
            "fs_nm": "연결재무제표",
            "sj_div": "BS",
            "sj_nm": "재무상태표",
            "account_nm": "유동자산",
            "thstrm_nm": "제 50 기",
            "thstrm_dt": "2018.12.31 현재",
            "thstrm_amount": "174,697,424,000,000",
            "frmtrm_nm": "제 49 기",
            "frmtrm_dt": "2017.12.31 현재",
            "frmtrm_amount": "146,982,464,000,000",
            "bfefrmtrm_nm": "제 48 기",
            "bfefrmtrm_dt": "2016.12.31 현재",
            "bfefrmtrm_amount": "141,429,704,000,000",
            "ord": "1"
        },
        ... 중략 ...
        {
            "rcept_no": "20190401004781",
            "reprt_code": "11011",
            "bsns_year": "2018",
            "corp_code": "00126380",
            "stock_code": "005930",
            "fs_div": "OFS",
            "fs_nm": "재무제표",
            "sj_div": "IS",
            "sj_nm": "손익계산서",
            "account_nm": "당기순이익",
            "thstrm_nm": "제 50 기",
            "thstrm_dt": "2018.01.01 ~ 2018.12.31",
            "thstrm_amount": "32,815,127,000,000",
            "frmtrm_nm": "제 49 기",
            "frmtrm_dt": "2017.01.01 ~ 2017.12.31",
            "frmtrm_amount": "28,800,837,000,000",
            "bfefrmtrm_nm": "제 48 기",
            "bfefrmtrm_dt": "2016.01.01 ~ 2016.12.31",
            "bfefrmtrm_amount": "11,579,749,000,000",
            "ord": "30"
        }
    ]
}

응답데이터 중 status는 api 결과 응답코드로 데이터가 존재하지 않거나 하는 경우 "000"이 아닌 응답코드를 준다. 따라서 "000" 인 경우에만 데이터를 읽도록 조건식을 추가한다.

( 응답데이터의 데이터 구조를 이해하기 위해서 다트에서 제공하는 응답결과(속성)를 먼저 이해해야 한다. ) 

if resp.status_code == 200:
  data_json = resp.json()

  # OUTPUT
  data_str = json.dumps(data_json, indent=4, ensure_ascii=False)
  # print(data_str)
  
  # 조건식 추가
  if data_json['status'] == "000":
    pass
  else :
    print(data_json['message'])

이제 재무제표를 읽을 모든 준비가 끝났다. 

예제로 삼성전자 2018년도 IFRS연결 당기순이익을 조회하는 코드를 작성해보자.

  if data_json['status'] == "000":
    detail = data_json['list']
    for x in detail:
      if x['fs_div'] == 'CFS' and x['sj_div'] == 'IS' and x['account_nm'] == '당기순이익':
        print(json.dumps(x, indent=4, ensure_ascii=False))
  else :
    print(data_json['message'])

CFS와 IS는 연결재무제표와 손익계산서를 뜻한다. 조건을 한 이유는 결과 리스트에 "별도재무제표" 가 같이 존재하기 때문이다. 이런 속성들은 API의 Response내역을 참고한다. 

 

OUTPUT

{
    "rcept_no": "20190401004781",
    "reprt_code": "11011",
    "bsns_year": "2018",
    "corp_code": "00126380",
    "stock_code": "005930",
    "fs_div": "CFS",
    "fs_nm": "연결재무제표",
    "sj_div": "IS",
    "sj_nm": "손익계산서",
    "account_nm": "당기순이익",
    "thstrm_nm": "제 50 기",
    "thstrm_dt": "2018.01.01 ~ 2018.12.31",
    "thstrm_amount": "44,344,857,000,000",
    "frmtrm_nm": "제 49 기",
    "frmtrm_dt": "2017.01.01 ~ 2017.12.31",
    "frmtrm_amount": "42,186,747,000,000",
    "bfefrmtrm_nm": "제 48 기",
    "bfefrmtrm_dt": "2016.01.01 ~ 2016.12.31",
    "bfefrmtrm_amount": "22,726,092,000,000",
    "ord": "29"
}

삼성전자 2018년도 제50기 연결 당기순이익은 443,449억원(올림)이다. 금액이 너무 커서 읽기도 힘들다.

자 이제 이 데이터를 다른 포털사이트에서 제공하는 재무제표와 비교해보자.

네이버 금융 - 삼성전자 재무제표

 

다트 Open API를 사용하여 재무제표를 조회해보았다. 결과데이터는 데이터를 비교, 분석하기에 쉬운 구조가 아니므로 행,열 데이터로 가공할 필요가 있다.

다음 장에서는 본 장에서 다룬 결과데이터(Dictionary)를 Pandas의 dataframe으로 가공하여 데이터 핸들링을 해보도록 한다.

 

 

반응형