본문 바로가기

API

[FinanceDataReader] CAGR, MDD, 샤프지수,소르티노지수 계산 및 코스피 회사에 대한 결과 시각화

반응형

FinanceDataReader를 이용해서 CAGR, MDD, 샤프지수, 소르티노 지수를 계산하고 

전체 코스피 회사에 대한 2022년의 결과를 그래프로 확인해보겠습니다.

 

FinanceDataReader의 설치 및 기본 사용법이 필요하신 분은 1번 참조 부탁드립니다. 

 

1. FinanceDataReader 설치 및 주가정보 확인(Skip가능)

2. CAGR, MDD, 샤프지수, 소르티노 지수

3. 코스피 회사에 대한 결과 확인

 

 

1. FinanceDataReader 설치(Skip가능)

https://yenpa.tistory.com/19

 

[FinanceDataReader] 설치 및 주식 주가 정보 가져오기(코스피, 코스닥)

국내 주식 정보를 가져와 보겠습니다. FinanceDataReader의 수집데이터의 변경이 있었네요. 내용 수정했습니다(2022/11/09) 1. FinanceDataReader 설치 2. 종목 정보 가져오기 3. 주가 정보 가져오기 1. FinanceDataR

yenpa.tistory.com

 

 

2. CAGR, MDD, 샤프지수, 소르티노 지수

필요 라이브러리를 import 하고 회사 list를 불러옵니다.

import FinanceDataReader as fdr
df_list=fdr.StockListing('KRX')
df_list

 

CAGR, MDD, 샤프지수, 소르티노 지수의 계산에 사용할 주가 정보를 저장합니다.

2022-01-01 ~ 2022-12-08일까지의 삼성전자의 주가를 이용하겠습니다.

name='삼성전자'
df_filter=df_list.loc[df_list['Name']==name]
code=df_filter['Code'].values[0]
startdate='2022-01-01'
enddate='2022-12-08'

df_result=fdr.DataReader(code,startdate,enddate)
df_result

 

 

그럼 CAGR을 계산해보겠습니다.

CAGR = (마지막 날 주가/시작 날 주가) ^ (1/경과 연도) - 1

의 식으로 계산을 할 수 있는데 각 날짜별 누적 수익률을 구해서 계산하셔도 됩니다.

CAGR = (마지막 날 누적수익률+1) ^ (1/경과 연도) - 1

# CAGR
df_result['누적수익률']=((df_result['Change'] + 1).cumprod() -1)
경과년도=(df_result.index[-1]-df_result.index[0]).days / 365
cagr = (df_result['누적수익률'] + 1).iloc[-1] ** (1/경과년도) -1

print('CAGR은 ' + str(cagr * 100) + '% 입니다.')

 

 

다음으로 MDD를 계산하겠습니다.

mdd = (저점) / (고점) - 1로 계산이 됩니다.

# MDD
df_result['max'] = 0
for i, r in df_result.iterrows():
    maxval = df_result.loc[:i,'Close'].max()
    df_result.loc[i,'max']=maxval
df_result['drawdown'] = (df_result['Close']/df_result['max']-1)*100
mdd = round(df_result['drawdown'].min(),1)
print('MDD는 ' + str(mdd) + '% 입니다.')

 

날짜 별로 for문을 실행하면서 이전 기간의 고점을 찾아서 max에 저장합니다.

df_result['max'] = 0
for i, r in df_result.iterrows():
    maxval = df_result.loc[:i,'Close'].max()
    df_result.loc[i,'max']=maxval

각 날짜 기준 drawdown을 구하고 가장 낮은 날짜의 값을 mdd에 저장합니다.

df_result['drawdown'] = (df_result['Close']/df_result['max']-1)*100
mdd = round(df_result['drawdown'].min(),1)
print('MDD는 ' + str(mdd) + '% 입니다.')

 

 

샤프지수와 소르티노 지수를 계산해보겠습니다.

샤프지수 : (연간 투자수익률 - 무위험수익률) / 표준편차

소르티노 지수 : (연간 투자수익률 - 무위험수익률) / 마이너스 수익 표준편차

 

무위험 수익률은 국채나 예금이자 등으로 계산이 되는데

여기에서는 코스피 지수를 무위험 수익률로 해서 코스피지수 대비 차이를 구해보겠습니다.

 

코스피 지수를 불러와서 누적수익률을 계산합니다.

kospi=fdr.DataReader('KS11',startdate,enddate)
kospi['Change']=kospi['Close'].pct_change()
kospi['누적수익률']=((kospi['Change'] + 1).cumprod()-1)

 

샤프지수를 계산합니다.

#샤프지수
sto=df_result.loc[df_result.index==enddate,'누적수익률'].values[0]
kos=kospi.loc[kospi.index==enddate,'누적수익률'].values[0]
std=df_result['Change'].std()
sharp=(sto/100-kos/100)/std
sharp

소르티노 지수를 계산합니다.

#소르티노지수
sto=df_result.loc[df_result.index==enddate,'누적수익률'].values[0]
kos=kospi.loc[kospi.index==enddate,'누적수익률'].values[0]
std=df_result.loc[df_result['Change']<0,'Change'].std()
sortino=(sto/100-kos/100)/std
sortino

 

반응형

 

3. 코스피 회사에 대한 결과 확인

우선 코스피 회사 리스트만 따로 저장합니다.

kospi_list=df_list.loc[df_list['Market']=='KOSPI']

 

각 결과를 계산하는 function을 만들겠습니다.

def getresult(code,name,df_result):
    result={}
    result['code']=code
    result['name']=name
    
    
    # CAGR
    df_result['누적수익률']=((df_result['Change'] + 1).cumprod() -1)
    경과년도=(df_result.index[-1]-df_result.index[0]).days / 365
    result['cagr'] = ((df_result['누적수익률'] + 1).iloc[-1] ** (1/경과년도) -1)*100

    # MDD
    df_result['max'] = 0
    for i, r in df_result.iterrows():
        maxval = df_result.loc[:i,'Close'].max()
        df_result.loc[i,'max']=maxval
    df_result['drawdown'] = (df_result['Close']/df_result['max']-1)*100
    result['mdd'] = round(df_result['drawdown'].min(),1)
    
    #샤프지수
    sto=df_result.loc[df_result.index==enddate,'누적수익률'].values[0]
    kos=kospi.loc[kospi.index==enddate,'누적수익률'].values[0]
    std=df_result['Change'].std()
    result['sharp']=(sto/100-kos/100)/std
    
    #소르티노지수
    sto=df_result.loc[df_result.index==enddate,'누적수익률'].values[0]
    kos=kospi.loc[kospi.index==enddate,'누적수익률'].values[0]
    std=df_result.loc[df_result['Change']<0,'Change'].std()
    result['sortino']=(sto/100-kos/100)/std
    
    return result

코스피 회사별로 결과를 저장합니다.

# Kospi 지수 
kospi=fdr.DataReader('KS11',startdate,'2022-12-09')
kospi['Change']=kospi['Close'].pct_change()
kospi['누적수익률']=((kospi['Change'] + 1).cumprod()-1)

startdate='2022-01-01'
enddate='2022-12-08'

result_all=[]
for i, r in kospi_list.iterrows():
    code=r['Code']
    name=r['Name']
    
    df_result=fdr.DataReader(code,startdate,enddate)
    
    # 120영업일보다 적은 회사는 skip
    if df_result.shape[0]<120:
        continue
    
    result_all.append(getresult(code,name,df_result))

DataFrame으로 변환 후 확인해 보겠습니다.

import pandas as pd
df=pd.DataFrame(result_all)
df

각 회사별로 결과가 저장이 잘 된 것을 알 수 있습니다.

 

그래프로 확인해볼까요

x축은 CAGR, y축은 mdd, 크기는 sharp지수입니다.

import plotly.express as px
df1=df.loc[df['sharp']>0]
fig=px.scatter(data_frame=df1,x='cagr',y='mdd',size=df1['sharp']*100, hover_name='name')
fig.update_layout(
    title_text='MDD CAGR Sharp',
    title={'x':0.5, 'y':0.95}
)
fig.show()

오른쪽 위쪽의 데이터일수록 CAGR이 크고 MDD가 적은 회사가 되겠습니다.

2022년 삼천리의 경우는 CAGR(367%), MDD(-7.9%), 샤프지수(1.76)를 기록했습니다.

 

그럼 샤프지수를 소르티노 지수로 변경해서 확인해볼까요.

전체적인 크기의 경향은 비슷해 보이는데 중간중간 다른 경향도 확인할 수 있습니다.

이상으로  CAGR, MDD, 샤프지수, 소르티노 지수를 계산하고

전체 코스피 회사에 대한 2022년의 결과를 그래프로 확인해봤습니다.

 

 

반응형