본문 바로가기

API

[전자공시 Dart API] PBR 계산 및 낮은 회사 리스트 수집

반응형

전자공시 Dart API의 전체 재무제표와 주식수를 가져와 PBR을 계산해보고, PBR이 낮은 회사 리스트를 수집해보겠습니다.

 

PBR은 아래의 항목으로 계산이 됩니다.(출처 : 나무 위키)

PBR은 주가순자산비율 / Price to Book-value Ratio

  • 주가순자산비율(PBR) = 주가 / 주당순자산가치(BPS) = 시가총액 / 순자산

 

순자산 : 재무제표상 자본총계

시가총액 : 주가 * 발행주식수

 

 

1. 가입 및 인증키 확인(Skip 가능)

2. 전체 회사 리스트 수집(Skip 가능)

3. 전체 재무제표에서 자본총계 수집

4. 회사별 발행주식수 수집

5. 회사별 주가 수집 및 PBR 계산

 

1. 가입 및 인증키 확인(Skip 가능)

https://yenpa.tistory.com/23

 

[전자공시 Dart API] 가입 및 인증키(API Key) 확인하기

1. 사이트 가입 2. 인증키(API Key) 확인하기 1. 사이트 가입 사이트에 접속합니다. https://opendart.fss.or.kr/ 전자공시 OPENDART 시스템 --> 시스템 점검으로 모든 서비스 이용이 일시적으로 중단되어니 양

yenpa.tistory.com

 

2. 전체 회사리스트 수집

전체  회사리스트 csv 파일이 필요한데 아래의 포스팅에서 만드셔도 되고,

첨부해드린 파일로 사용하셔도 됩니다.

https://yenpa.tistory.com/49

 

[전자공시 Dart API] 전체 상장 회사의 상세정보(기업개황) 수집 및 저장

전자공시 Dart API를 이용해서 상장회사의 리스트를 가져와서 저장해보도록 하겠습니다. 공시정보 > 고유번호에서 제공되는 데이터는 기본 정보(회사코드, 회사명, 주식코드)만 있어, 법인구분(코

yenpa.tistory.com

회사상세정보.csv
0.88MB

 

 

3. 전체 재무제표에서 자본총계 수집

요청 parameter는 사업연도(bsns_year) 2021년, 보고서 종류(reprt_code) 사업보고서,

fs_div 연결 재무제표를 설정했습니다.

재무제표의 자본 총계만 따로 저장하겠습니다.

crtfc_key는 본인의 데이터가 필요합니다.

# 회사별 전체재무제표 확인
result_all = pd.DataFrame()

#crtfc_key='YOUR_API_KEY'
bsns_year='2021'
reprt_code='11011' #1분기보고서: 11013 반기보고서: 11012 3분기보고서: 11014 사업보고서: 11011
fs_div='CFS'  #CFS:연결재무제표, OFS:재무제표

for i, r in corp_list.iterrows():
    #전체재무제표 요청인자
    crtfc_key=crtfc_key
    corp_code=str(r['corp_code']).zfill(8)
    
    #if i == 100:
    #    break
    
    time.sleep(0.3)
    
    print(i)
    
    url = 'https://opendart.fss.or.kr/api/fnlttSinglAcntAll.json'
    params = {
        'crtfc_key': crtfc_key,
        'corp_code' : corp_code,
        'bsns_year' : bsns_year,
        'reprt_code' : reprt_code,
        'fs_div' : fs_div,
    }
    
    #결과를 json형태로 저장
    results = requests.get(url, params=params).json()
    
    if results['status'] == '000':
        result_df = pd.DataFrame(results['list'])
        result_all = pd.concat([result_all,result_df])
    
equity=result_all.loc[(result_all['sj_div']=='BS') & (result_all['account_id']=='ifrs-full_Equity')]
equity = equity[['corp_code','thstrm_nm','thstrm_amount','frmtrm_nm', \
                 'frmtrm_amount','bfefrmtrm_nm','bfefrmtrm_amount','currency']]
equity.columns = ['corp_code','2021년','2021_자본총계','2020년','2020_자본총계', \
                  '2019년','2019_자본총계','currency']
equity

 

요청 인자 설정하는 부분입니다.

#crtfc_key='YOUR_API_KEY'
bsns_year='2021'
reprt_code='11011' #1분기보고서: 11013 반기보고서: 11012 3분기보고서: 11014 사업보고서: 11011
fs_div='OFS'  #CFS:연결재무제표, OFS:재무제표

 

2번에서 수집한 전체 회사에 대해 for문을 실행합니다.

for i, r in corp_list.iterrows():

API를 호출해서 status가 '000' 정상일 경우에만 결과를 result_df, result_all에 저장합니다.

url = 'https://opendart.fss.or.kr/api/fnlttSinglAcntAll.json'
params = {
    'crtfc_key': crtfc_key,
    'corp_code' : corp_code,
    'bsns_year' : bsns_year,
    'reprt_code' : reprt_code,
    'fs_div' : fs_div,
}

#결과를 json형태로 저장
results = requests.get(url, params=params).json()

if results['status'] == '000':
    result_df = pd.DataFrame(results['list'])
    result_all = pd.concat([result_all,result_df])

재무제표의 재무상태표(BS)의 자본총계(ifrs-full_Equity)만 따로 저장했습니다.

그리고 필요 column 정보인 corp_code와 2021년, 2020년, 2019년의 자본총계 정보, currency(통화) 정보만

가져왔습니다.

equity=result_all.loc[(result_all['sj_div']=='BS') & (result_all['account_id']=='ifrs-full_Equity')]
equity = equity[['corp_code','thstrm_nm','thstrm_amount','frmtrm_nm', \
                 'frmtrm_amount','bfefrmtrm_nm','bfefrmtrm_amount','currency']]
equity.columns = ['corp_code','2021년','2021_자본총계','2020년','2020_자본총계', \
                  '2019년','2019_자본총계','currency']
equity

 

연결 재무제표의 자본총계는 총 1802개가 검색이 됩니다.

equity.shape

 

반응형

 

 

4. 회사별 발행주식수 수집

2번에서 구한 회사별로 사업보고서 주요 정보 > 주식의 총수의 정보를 가져와서

그중 필요한 정보인 발행주식의 총수와 회사 정보 등을 따로 저장합니다.

#전체결과저장
result_stocks=[]

print('총 회사수는 : ' + str(corp_list.shape[0]))

# 수집한 회사에 대해서 for문.
for i, r in corp_list.iterrows():
    #if i == 1:
    #    break
    
    #없으면 어느 시점에서 에러발생
    time.sleep(0.3)
    
    print('i = ' + str(i))
    corp_code=str(r['corp_code'])
    corp_name=r['corp_name']
    stock_code=str(r['stock_code'])
    bsns_year=2021
    reprt_code='11011' 
    #1분기보고서 : 11013, 반기보고서 : 11012, 3분기보고서 : 11014, 사업보고서 : 11011

    url = 'https://opendart.fss.or.kr/api/stockTotqySttus.json'
    params = {
        'crtfc_key': crtfc_key,
        'corp_code' : corp_code,
        'bsns_year' : str(bsns_year),
        'reprt_code' : reprt_code,
    }

    results = requests.get(url, params=params).json()
    # 응답이 정상 '000' 일 경우에만 데이터 수집
    if results['status'] == '000':
        for result in results['list']:
            if result['se'] in ['보통주','우선주','합계']:
                result_dic={}
                result_dic['se']=result['se']
                result_dic['istc_totqy']=result['istc_totqy']
                result_dic['corp_code']=corp_code
                result_dic['corp_name']=corp_name
                result_dic['stock_code']=stock_code
                result_stocks.append(result_dic)

API를 호출하는 부분이 되겠습니다.

print('i = ' + str(i))
corp_code=str(r['corp_code'])
corp_name=r['corp_name']
stock_code=str(r['stock_code'])
bsns_year=2021
reprt_code='11011' 
#1분기보고서 : 11013, 반기보고서 : 11012, 3분기보고서 : 11014, 사업보고서 : 11011

url = 'https://opendart.fss.or.kr/api/stockTotqySttus.json'
params = {
    'crtfc_key': crtfc_key,
    'corp_code' : corp_code,
    'bsns_year' : str(bsns_year),
    'reprt_code' : reprt_code,
}

results = requests.get(url, params=params).json()

결과 중에서 보통주, 우선주 구분 및 corp_code(재무제표 데이터와 결합 시 key), stock_code(주가 정보) 등을 저장합니다.

# 응답이 정상 '000' 일 경우에만 데이터 수집
if results['status'] == '000':
    for result in results['list']:
        if result['se'] in ['보통주','우선주','합계']:
            result_dic={}
            result_dic['se']=result['se']
            result_dic['istc_totqy']=result['istc_totqy']
            result_dic['corp_code']=corp_code
            result_dic['corp_name']=corp_name
            result_dic['stock_code']=stock_code
            result_stocks.append(result_dic)
            
stocks=pd.DataFrame(result_stocks)
stocks

 

 

5. 회사별 주가 수집 및 PBR 계산

재무제표 데이터와 회사 발행주식 정보를 병합합니다.

발행주식수에서 보통주의 정보만을 가져왔고, 통화를 원화(KRW)를 사용하는 회사 정보만을 저장합니다.

df=pd.merge(left=equity,right=stocks,how='left',on='corp_code')
df1=df.loc[(df['se']=='보통주') & (df['currency']=='KRW')]
df1['stock_code']=df1['stock_code'].str.zfill(6)
df1

 

회사별 오늘 날짜의 주가 정보를 수집합니다.

import matplotlib.pyplot as plt
import FinanceDataReader as fdr
import datetime
plt.rc('font', family='NanumGothic') 

price_all=pd.DataFrame()
for i, r in df1.iterrows():
    
    stock_code = r['stock_code']
    
    
    #주가정보
    code=stock_code
    today=datetime.datetime.now().strftime('%Y%m%d')
    price=fdr.DataReader(code,today,today)[['Close']]
    price['stock_code']=stock_code
    price_all = pd.concat([price_all,price])
    
price_all

 

 

df1에 주가 데이터를 추가합니다.

df2=pd.merge(left=df1,right=price_all,how='left',on='stock_code')
df2

 

 

반응형

 

 

이제 df2에 저장된 정보로 PBR을 계산해볼까요.

주가순자산비율(PBR) = 주가 / 주당순자산가치(BPS) = 시가총액 / 순자산

PBR = Close * istc_totqy / 2021_자본총계

 

object를 int로 변경하고 계산식을 넣어서 PBR을 구합니다.

df2['istc_totqy']=df2['istc_totqy'].str.replace(',','').astype('int64')
df2=df2.astype({'2021_자본총계':'int64'})
df2['PBR'] = df2['Close'] * df2['istc_totqy'] / df2['2021_자본총계']
df2

제일 우측에 PBR이 구해진 것을 알 수 있습니다.

 

PBR이 0보다 큰 회사 중 낮은 순으로 20개 회사만 구했습니다.

df2.loc[df2['PBR']>0].sort_values('PBR')[['corp_name','PBR','Close']].iloc[:20,]

 

PBR조건을 0.5~1.0 사이의 회사를 구해서 PBR이 낮은 순으로 정렬해보겠습니다.

df2.loc[(df2['PBR']>=0.5) & (df2['PBR']<=1)].sort_values('PBR')[['corp_name','PBR','Close']].iloc[:20,]

 

 

이외에도 지난기(2020년)의 데이터 확인도 가능하고,

2020년 대비 PBR 변동량 순을 계산하는데 응용해볼 수도 있을 것 같습니다.

 

PBR을 계산해보고, PBR이 낮은 회사 리스트를 확인해 봤습니다..

반응형