Lala's tower

파이썬으로 손익계산서 분석하기 2

파이썬으로 손익계산서 분석하기 2

2024-05-27 22:48:58

지난 글의 내용과 상단의 코드는 동일합니다. 파이썬으로 손익계산서의 데이터를 수집하고 그래프를 그리는 코드입니다. 금융감독원 API를 이용하여 데이터로 최근 5년간의 데이터를 수집하여 추이를 그래프로 그렸습니다.

파이썬으로 손익계산서 데이터 수집

아래 코드는 colab 에서 붙여넣기하고 재생버튼만 누르면 실행됩니다.
(코드를 시작하거나 AI로 코드를 생성하세요 라고 씌여져 있는 칸에 붙여넣기 하시면 됩니다.)

api_key = ‘금융감독원 api-key’

이 부분에 금융감독원 Open DART API에서 가입 후 복사하시면 됩니다.

실행 결과 그래프의 한글이 깨질겁니다. colab메뉴의 runtime/restart session을 선택 후 재실행하하셔야 한글이 아래와 같이 제대로 나올겁니다.

# # 파이썬으로 손익계산서 
# 금융감독원 API를 위한 패키지 설치
!pip install OpenDartReader

# 그래프의 한글을 위한 폰트 설치
!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf

import matplotlib.font_manager as fm
import OpenDartReader
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# # 파이썬으로 손익계산서 
# 재무제표 분석을 위해 opendartreader 데이터를 가공하는 클래스
class OpenDartReaderEx:
    def __init__(self, api_key):
        self.api_key = api_key
        self.dart = OpenDartReader(api_key)

    def get_financial_statements(self, company_name, year, report_types=['11013', '11012', '11014', '11011']):
        dfList = []
        for report_type in report_types:
            dfList.append(self.dart.finstate_all(company_name, year, reprt_code=report_type, fs_div='CFS'))

        df = pd.concat(dfList, ignore_index=True)
        return df

    def get_filter(self, df, account_name):
        sj_nm_conditions = {
            '유동자산': ['재무상태표'],
            '부채총계': ['재무상태표'],
            '자본총계': ['재무상태표'],
            '매출액': ['손익계산서', '포괄손익계산서'],
            '매출총이익': ['손익계산서', '포괄손익계산서'],
            '영업이익': ['손익계산서', '포괄손익계산서'],
            '당기순이익': ['손익계산서', '포괄손익계산서', '현금흐름표'],
            '영업활동현금흐름': ['현금흐름표'],
            '투자활동현금흐름': ['현금흐름표'],
            '자산총계': ['재무상태표'],
            '매출원가': ['손익계산서', '포괄손익계산서'],
            '순이익': ['손익계산서', '포괄손익계산서'],
            '지출비용': ['손익계산서', '포괄손익계산서'],
            '재료비': ['손익계산서', '포괄손익계산서'],
            '유형자산증가': ['현금흐름표']
        }

        account_nm_conditions = {
            '유동자산': ['유동자산', 'II. 유동자산', 'Ⅰ.유동자산', '유동자산 합계', 'I.유동자산', 'I. 유동자산', 'l. 유동자산'],
            '부채총계': ['부채총계', '부  채  총  계', '부채 총계'],
            '자본총계': ['자본총계', '반기말자본', '3분기말자본', '분기말자본', '1분기말자본', '자  본  총  계', '기말',
                     '자본 총계', '기말자본 잔액', '분기말', '반기말', '자 본 총 계', '분기말 잔액', '반기말 잔액'],
            '매출액': ['매출액', '수익(매출액)', '매출', '영업수익', '수익', '영업수익(매출액)', 'Ⅰ.매출', 'I.매출액',
                    'Ⅰ.매출액', 'I. 매출액', '매출액(영업수익)'],
            '매출총이익': ['매출총이익', '매출 총이익', '매출총이익(손실)', 'Ⅲ.매출총이익', 'III.매출총이익',
                      'Ⅲ.매출총이익', 'III. 매출총이익(손실)', 'III. 매출총이익', '매출총이익(영업수익)', 'II.재료비'],
            '영업이익': ['영업이익(손실)', '영업이익', '영업손실(이익)', '영업손익', '계속영업이익(손실)', 'Ⅳ.영업이익',
                     'VI.영업이익(손실)', 'V.영업이익', 'V. 영업이익(손실)', 'IV. 영업이익', '영업이익 (손실)', '영업손실'],
            '당기순이익': ['당기순이익(손실)', '당기순이익', '분기순이익', '분기순이익(손실)', '반기순이익', '반기순이익(손실)',
                      '연결분기순이익', '연결반기순이익', '연결당기순이익', '연결분기(당기)순이익', '연결반기(당기)순이익',
                      '연결분기순이익(손실)', '당기순손익', 'Ⅶ.당기순이익', 'VIII.당기순이익(손실)', 'XIII. 당기순이익(손실)',
                      '반기연결순이익(손실)', '연결당기순이익(손실)', '당기의 순이익', '분기기순이익(손실)', '분기순손익',
                      '분기순손실', '반기순손익', '분기연결순손실', '분기연결순이익(손실)'],
            '영업활동현금흐름': ['영업활동으로 인한 현금흐름', '영업활동 현금흐름', '영업활동현금흐름', '영업활동으로인한 현금흐름',
                         '영업활동으로인한순현금흐름', 'Ⅰ. 영업활동으로 인한 현금흐름', 'I.영업활동현금흐름', '영업활동으로인한현금흐름',
                         '영업활동으로 인한 순현금흐름', '영업활동으로인한 순현금흐름', '1.영업활동현금흐름', 'Ⅰ.영업활동현금흐름',
                         '영업활동으로 인한 현금 흐름', 'I. 영업활동현금흐름', 'I. 영업활동으로 인한 현금흐름', 'I.영업활동으로 인한 현금흐름',
                         '영업활동순현금흐름 합계', 'Ⅰ. 영업활동현금흐름', '영업으로부터 창출된 현금흐름', 'Ⅰ. 영업활동으로 인한 순현금흐름'],
            '투자활동현금흐름': ['투자활동으로 인한 현금흐름', '투자활동 현금흐름', '투자활동현금흐름', '투자활동으로인한 현금흐름',
                         '투자활동으로인한순현금흐름', 'Ⅱ. 투자활동으로 인한 현금흐름', 'II.투자활동현금흐름', '투자활동으로인한현금흐름',
                         '투자활동으로 인한 순현금흐름', '투자활동으로인한 순현금흐름', '2.투자활동현금흐름', 'Ⅱ.투자활동현금흐름',
                         'Ⅱ. 투자활동현금흐름', 'II. 투자활동으로 인한 현금흐름', 'II.투자활동으로 인한 현금흐름', 'II. 투자활동현금흐름',
                         '투자활동순현금흐름 합계', '투자활동으로부터의 순현금유입(유출)', 'Ⅱ. 투자활동으로 인한 순현금흐름'],
            '자산총계': ['자산총계', '자  산  총  계', '자산 총계', '자본과부채총계'],
            '매출원가': ['매출원가'],
            '순이익': ['법인세비용차감전순이익', '당기순이익'],
            '지출비용': ['Ⅵ.영업외비용', 'VI.영업외비용', 'Ⅶ.법인세비용', 'VII.법인세비용'],
            '재료비': ['II.재료비'],
            '유형자산증가': ['유형자산의 증가', '유형자산의증가', ' 유형자산의 취득', ' 유형자산의취득', '유형자산의취득', '유형자산의 취득']
        }

        if account_name not in sj_nm_conditions or account_name not in account_nm_conditions:
            raise ValueError(f"Unsupported account name: {account_name}")

        return (df.sj_nm.isin(sj_nm_conditions[account_name])) & (
            df.account_nm.isin(account_nm_conditions[account_name]))

    def get_sum(self, df, account_name):
        filter = self.get_filter(df, account_name)
        dffiltered = df[filter]
        dffiltered.loc[dffiltered.index, 'thstrm_amount'] = pd.to_numeric(dffiltered['thstrm_amount'],
                                                                          errors='coerce').astype(
            'Int64')

        return dffiltered['thstrm_amount'].sum()

# 파이썬으로 손익계산서 데이터 수집하기
api_key = '금융감독원 api-key'
odr = OpenDartReaderEx(api_key)
# 파이썬으로 대차대조표 삼성전자 5년 간의 데이터 수집
# 삼성전자 2019~2023 데이터 수집 (가정: odr.get_financial_statements 함수 사용)
years = [2019, 2020, 2021, 2022, 2023]
data = {}

for year in years:
    df = odr.get_financial_statements("삼성전자", year)
    revenue = odr.get_sum(df, "매출액")
    cost_of_goods_sold_sum = odr.get_sum(df, "매출원가")
    gross_profit_sum = odr.get_sum(df, "매출총이익")
    profit_sum = odr.get_sum(df, "영업이익")
    net_profit_sum = odr.get_sum(df, "당기순이익")
    net_income_sum = odr.get_sum(df, "순이익")
    expenses_sum = odr.get_sum(df, "지출비용")
    material_costs_sum = odr.get_sum(df, "재료비")
    data[year] = {"매출액": revenue, 
                  "매출원가": cost_of_goods_sold_sum, 
                  "매출총이익": gross_profit_sum, 
                  "영업이익": profit_sum, 
                  "당기순이익": net_profit_sum, 
                  "순이익":net_income_sum, 
                  "지출비용": expenses_sum, 
                  "재료비": material_costs_sum
                  }

df_financials = pd.DataFrame(data).T

# 금액에 콤마 추가
df_financials = df_financials.applymap(lambda x: f"{int(x):,}")

print(df_financials)

# 한글 폰트 로드
font_path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf'
font_name = fm.FontProperties(fname=font_path).get_name()
plt.rc('font', family=font_name) 

# 그래프 그리기
plt.figure(figsize=(15, 10))

# 각 항목별 그래프 그리기
for column in df_financials.columns:
    sns.lineplot(data=df_financials, x=df_financials.index, y=df_financials[column].str.replace(",", "").astype(int), label=column)

plt.title("삼성전자 손익계산서 2019-2023")
plt.xlabel('년도')
plt.ylabel('금액 (단위: 백만원)')
plt.legend(title='항목')
plt.grid(True)

plt.tight_layout()
plt.show()

파이썬으로 손익계산서 해석하기

매출이 매년 증가하는 것이 바람직하겠습니다. 실제 삼성전자의 주가 그래프도 한번 비교해보시기 바랍니다.

파이썬으로 손익계산서 결과 이미지

파이썬으로 재무제표 분석하기 1
금융감독원 단일회사 재무제표 조회
파이썬으로 팩터투자 (퀀트 투자)
오늘자 골든크로스/데드크로스 종목 추출 파이썬 코드
퀀트를 위한 파이썬 이동 평균선
퀀트를 위한 파이썬FinanceDataReader