제2회 KRX 주식 투자 알고리즘 경진대회

알고리즘 | 정형 | 시계열 | 포트폴리오 구성 | 금융 | 샤프 지수

  • moneyIcon Prize : 5,000 만원
  • 1,323명 마감
Closed

 

Sharp Index 계산식 공유

2023.07.29 13:20 2,212 Views

몇일전 Sharp Index 계산식을 올리신 분이 있던데, 그동안 자체적으로 만들생각을 못하고 있다가 제가 구현한 내용을 올려드립니다.

주말간 너무 더워서 AI 공부는 쉬고, '너튜브'나 볼렵니다.


1. 필요 라이브러리 임포트

import pandas as pd
import numpy as np
from pprint import pprint


2. 파일 로딩.. test.csv 파일에는 15일간의 데이터가 들어 있어야합니다.(ex.5/31부터 6/21일)

df_test = pd.read_csv('test.csv') ## 2023-05-31 ~ 2023-06-21
cc_close = df_test.sort_values(by='일자').groupby( by=['종목코드'])['종가'].apply(list).to_dict()

df_submission = pd.read_csv('baseline_submission.csv')
cc_rank = df_submission.sort_values(by='순위')['종목코드'].to_list()


[ test.csv ]

# KRX 사이트에서 일자별로 csv 로 다운로드 받아, '종목코드' 앞에 'A'를 붙여서 만들었는데, 데이터 삭제나, 기타이슈가 될 듯하여 올리지 않습니다.

종목코드,종가,일자
A060310,3020,2023-05-31
A095570,4255,2023-05-31
...

3. 샤프 지수 계산

np_cc_buy = np.array([ cc_close[cc] for cc in cc_rank[:200] ])
np_cc_sell = np.array([ cc_close[cc] for cc in cc_rank[-200:] ])

assert np_cc_buy.shape[1] == 15

value = {}
value['매매일수'] = 15
value['무위험수익률'] = 0.035
value['총 매수 수익률']  = + np.sum( np_cc_buy [:,-1]/np_cc_buy [:,0]-1.0 )
value['총 공매도 수익률'] = - np.sum( np_cc_sell[:,-1]/np_cc_sell[:,0]-1.0 )
value['총 자산 최종 수익률'] = ( value['총 매수 수익률'] + value['총 공매도 수익률'] ) / 400
value['연율화된 총자산 최종 수익률'] = value['총 자산 최종 수익률'] * 250 / value['매매일수']

profit_day_buy = + ( np_cc_buy [:,1:]/np_cc_buy [:,:-1]-1.0 )
profit_day_sell = - ( np_cc_sell[:,1:]/np_cc_sell[:,:-1]-1.0 )

value['연율화된 일간수익률의 일별 평균'] = ( profit_day_buy + profit_day_sell ).sum(0) * 250 / 400
value['연율화된 일간수익률의 평균'] = np.mean(value['연율화된 일간수익률의 일별 평균'])
value['총자산 일간 수익률 변동성'] = ( np.sum( ( value['연율화된 일간수익률의 일별 평균'] - value['연율화된 일간수익률의 평균'] ) ** 2.0 ) / (15-2) ) ** 0.5
value['샤프지수'] = ( value['연율화된 총자산 최종 수익률'] - value['무위험수익률'] ) / value['총자산 일간 수익률 변동성']

pprint(value)


4. 샤프지수 계산시 수학함수에서 "표준편차"함수로 계산이 되지 않아, 보정해서 사용하는 방법도 있습니다.

print('총자산 일간 수익률 변동성(다른계산법들)', 
   value['연율화된 일간수익률의 일별 평균'].std() * np.sqrt(14/13),
   np.concatenate( ( profit_day_buy, profit_day_sell ) ).mean(0).std() * np.sqrt(14/13) * 250
   )


5. 참고 출력

{'매매일수': 15,
 '무위험수익률': 0.035,
 '샤프지수': -0.27633581888949926,
 '연율화된 일간수익률의 일별 평균': array([-0.28609279, -1.40358892, -0.7569731 , -0.51138989, -0.23686841,
        0.46050271,  0.05104517,  0.48580122, -1.06660605,  1.47666714,
       -7.53903031, -0.08851103,  0.70398164, -0.43336609]),
 '연율화된 일간수익률의 평균': -0.653173478391572,
 '연율화된 총자산 최종 수익률': -0.5500268464797621,
 '총 공매도 수익률': -17.443426816850504,
 '총 매수 수익률': 4.242782501336216,
 '총 자산 최종 수익률': -0.033001610788785725,
 '총자산 일간 수익률 변동성': 2.117086553711308}
총자산 일간 수익률 변동성(다른계산법들) 2.1170865537113084 2.1170865537113084


공지사항에 나온것 그대로 구현하려고 하였고, numpy 로 코드를 좀 다듬었습니다.

잘못 구현된게 있다면 댓글 남겨주세요.

로그인이 필요합니다
0 / 1000
BA2plus
2023.07.31 19:50

이렇게 하셨을 때 데이콘에 제출해서 나왔던 점수와 값이 모두 일치하셨나요? 

basslibrary
2023.08.01 09:34

샤프지수를 구현해볼 생각을 하지 않고 있어 마지막에서야 구현하고, 2번정도 확인했는데 일치했습니다.
혹시 지금 진행되는 점수 부분을 이야기하신 거라면, 확인하지 않았습니다.

검은짱돌의계략
2023.08.01 14:55

저도 똑같이 나왔습니다. 저는 "총자산 일간 수익률 변동성"을 구현하는 부분에서 저의 실수가 있더군요