전자공시 Dart API의 전체 재무제표와 주식수를 가져와 PER을 계산해보고,
PER이 낮은 순으로 정렬해서 리스트를 구해보겠습니다.
PER은 아래의 항목으로 계산됩니다.(출처 나무 위키)
- 시가총액/당기순이익
당기순이익 : 재무제표상 지배기업의 소유주에게 귀속되는 당기순이익(손실) 사용
시가총액 : 주가 * 발행주식수
1. 가입 및 인증키 확인(Skip 가능)
2. 전체 회사 리스트 수집(Skip 가능)
3. 전체 재무제표에서 당기순이익 수집
4. 회사별 발행주식수 수집
5. 회사별 주가 수집 및 PER 계산
1. 가입 및 인증키 확인(Skip 가능)
2. 전체 회사 리스트 수집(Skip 가능)
전체 회사 리스트 csv 파일이 필요한데 아래의 포스팅에서 만드셔도 되고,
첨부해드린 파일로 사용하셔도 됩니다.
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])
profit=result_all.loc[(result_all['account_id']=='ifrs-full_ProfitLossAttributableToOwnersOfParent')]
profit = profit[['corp_code','thstrm_nm','thstrm_amount','frmtrm_nm', \
'frmtrm_amount','bfefrmtrm_nm','bfefrmtrm_amount','currency']]
profit.columns = ['corp_code','2021년','2021_당기순이익','2020년','2020_당기순이익', \
'2019년','2019_당기순이익','currency']
profit
요청 인자 설정하는 부분입니다.
#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])
재무제표의 손익계산서의 지배기업의 소유주에게 귀속되는 당기순이익(손실)
(ifrs_ProfitLossAttributableToOwnersOfParent)만 따로 저장했습니다.
그리고 필요 column 정보인 corp_code와 2021년, 2020년, 2019년의 자본총계 정보, currency(통화) 정보만
가져왔습니다
profit=result_all.loc[(result_all['account_id']=='ifrs-full_ProfitLossAttributableToOwnersOfParent')]
profit = profit[['corp_code','thstrm_nm','thstrm_amount','frmtrm_nm', \
'frmtrm_amount','bfefrmtrm_nm','bfefrmtrm_amount','currency']]
profit.columns = ['corp_code','2021년','2021_당기순이익','2020년','2020_당기순이익', \
'2019년','2019_당기순이익','currency']
profit
4. 회사별 발행주식수 수집
2번에서 구한 회사별로 사업보고서 주요 정보 > 주식의 총수의 정보를 가져와서
그중 필요한 정보인 발행주식의 총수와 회사 정보 등을 따로 저장합니다.
#전체결과저장
result_stocks=[]
print('총 회사수는 : ' + str(corp_list.shape[0]))
# 수집한 회사에 대해서 for문.
for i, r in corp_list.iterrows():
#if i == 100:
# break
#없으면 어느 시점에서 에러발생
time.sleep(0.1)
print('i = ' + str(i))
corp_code=str(r['corp_code']).zfill(8)
corp_name=r['corp_name']
stock_code=str(r['stock_code'])
bsns_year=2021
reprt_code='11011'
#1분기보고서 : 11013, 반기보고서 : 11012, 3분기보고서 : 11014, 사업보고서 : 11011
#print(corp_code)
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)
stocks=pd.DataFrame(result_stocks)
stocks
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. 회사별 주가 수집 및 PER 계산
재무제표 데이터와 회사 발행주식 정보를 병합합니다.
발행주식수에서 보통주의 정보만을 가져왔고, 통화를 원화(KRW)를 사용하는 회사 정보만을 저장합니다.
df=pd.merge(left=profit,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를 만듭니다.
df2=pd.merge(left=df1,right=price_all,how='left',on='stock_code')
df2
이제 df2에 저장된 정보로 PER을 계산해볼까요.
PER = 시가총액 / 당기순이익
PER = Close * istc_totqy / 2021_당기순이익
object를 int로 변경하고 당기순이익의 데이터가 없는 회사는 제외했습니다.
그다음 계산식을 넣어서 PER을 구합니다.
df2['istc_totqy']=df2['istc_totqy'].str.replace(',','').astype('int64')
df2=df2.loc[df2['2021_당기순이익']!='',]
df2=df2.astype({'2021_당기순이익':'int64'})
df2['PER'] = df2['Close'] * df2['istc_totqy'] / df2['2021_당기순이익']
df2
PER이 0보다 큰 회사 중에서 PER이 낮은 순으로 정렬 후에 20개의 회사를 구했습니다.
df2.loc[df2['PER']>0].sort_values('PER')[['corp_name','PER','Close']].iloc[:20,]
이상으로 전자공시 Dart API의 재무제표와 FinanceDataReader를 이용해서
PER이 낮은 회사 리스트를 구해봤습니다.
'API' 카테고리의 다른 글
[FinanceDataReader] 업종별 수익(CAGR) 및 MDD 비교하기 (4) | 2022.11.18 |
---|---|
[FinanceDataReader] 주가 및 MDD(Maximum DrawDown) 확인 (6) | 2022.11.18 |
[전자공시 Dart API] PBR 계산 및 낮은 회사 리스트 수집 (6) | 2022.11.14 |
[공공데이터_data API] 1++ 한우 경매가 월별 트렌드 확인 (4) | 2022.11.12 |
[FinanceDataReader] 검색년도 CAGR(연평균 성장률) 상위 회사확인 (4) | 2022.11.10 |