본문 바로가기

개발 프로젝트

주식 종목 가치평가 알고리즘

728x90

 

이 알고리즘은 "채권 쟁이 서준식의 다시 쓰는 주식 투자 교과서"에 나온 가치투자 기법을 바탕으로 개발하였습니다. 

기업의 재무제표 항목 중 주당순이익(EPS), 주당순자산(BPS), 자기 자본 이익률(ROE), 주당 순이익률(PER) 그리고 주가를 활용하여 5년 뒤의 기대 BPS를 구한 뒤 연간 기대 수익률 15%로 계산하여 현재 기대 주가를 산출해내는 기법입니다.

이번 포스팅에서는 파이썬 코드와 결과값을 보여주며 그 방식에 대해 소개하겠습니다.

 

1. 크롤링

def get_html(jcode):     #재무재표 크롤링
    url = 'http://comp.fnguide.com/SVO2/ASP/SVD_main.asp?pGB=1&gicode=A%s' % jcode
    html = urlopen(url).read()
    html = bs4.BeautifulSoup(html,'lxml')
    table = html.find('div',{'id':'highlight_D_Y'})
    crt_data = html.find('div',{'id':'corp_group2'}).find_all('dl')
    crt_PER = crt_data[0].find_all('dd')[1].text   #PER
    crt_around_PER = crt_data[4].find_all('dd')[1].text   #업종 PER
    crt_PBR = float(crt_data[6].find_all('dd')[1].text)
    crt_price = int(html.find('span',{'id' : 'svdMainChartTxt11'}).text.replace(',',''))
    name = html.find('h1',{'id':'giName'}).text

    date_col = table.find_all('tr')[1].find_all('th')[:5]
    date_col=list(i.text for i in date_col) #dataframe의 column

    j = table.find_all('td',{'class','r'})
    tr = table.find_all('tr')[18:]
    df = pd.DataFrame()


    for i in tr:        #테이블 항목 가져오기
        category = i.find('span',{'class':'txt_acd'})
        if(category==None):
            category=i.find('th')
        category = category.text.strip()
        value_list = []
        j = i.find_all('td',{'class','r'})[:5]

        for value in j:
            temp = value.text.replace(',','').strip()
            try:
                temp = float(temp)
                value_list.append(temp)
            except:
                value_list.append(0)
            data = {category:value_list}
            data = pd.DataFrame(data)
        df = pd.concat([df,data],axis=1)

    df.index=date_col
    return df
    

 

 

 

이 메서드의 실행 결과는 다음의 데이터프레임입니다.

INPUT : 삼성전자 005930

Comp.fnguide.com

 

삼성전자(A005930) | Snapshot | 기업정보 | Company Guide

삼성전자 005930 | 홈페이지 홈페이지http://www.samsung.com/sec 전화번호 전화번호031-200-1114 | IR 담당자 02-2255-9000 주소 주소경기도 수원시 영통구 삼성로 129 (매탄동) KSE  코스피 전기,

Comp.fnguide.com

 Fnguide에서 제공하는 재무제표를 크롤링하여 최근 5년간의 재무제표로 재구성하였습니다.


2. 기대 BPS 계산

def df_extension(df):       #데이터테이블 확장(2025년까지)
    for i in range(1,7):
        ROE_mean = df['ROE'].mean()
        new_eps = df['BPS'][-1]*ROE_mean/100
        new_bps = new_eps + df['BPS'][-1]
        PER = df['PER'][-1]
        PBR = df['PBR'][-1]
        stock_ret = df['배당수익률'][-1]
        df.loc['202'+str(i)+'/12'] = [df['ROA'].mean(),ROE_mean,new_eps,new_bps, np.nan, PER, PBR, np.nan, stock_ret]
    return df

이 메서드의 실행 결과는 다음과 같습니다.

반복문을 통해 5년 뒤의 기대 BPS를 계산하였습니다.

계산식

Expected BPS = BPS + BPS*(ROE/100) 

3. 현재 가치로 환산

def report(self):
  self.new_price = int(self.df['BPS'][-1]/((1.15)**5))

  self.all_datas = pd.DataFrame(index = ['종목이름','종목코드','평균ROE','PER','업종PER','현재가치','주가','평가'],
  data = [self.name,self.jcode,self.ROE_mean,self.crt_PER,self.crt_around_PER,self.new_price,self.crt_price,\
  '적합' if self.new_price>=1.5*self.crt_price else '부적합']).T
  return self.all_datas

이 메서드의 실행 결과는 다음과 같습니다.

현재 기대 주가는 5년 뒤 기대 BPS를 기대수익률 15%로 계산하여 현재 가치를 구합니다. 현재 가치가 주가의 1.5배보다 크다면 적합, 아니면 부적합으로 평가됩니다. 삼성전자의 경우 현재 가치가 주가를 한참 밑돌고 있고 PER로 업종 PER보다 높게 나와 부적합으로 평가되었습니다.

 


4. 고배당주와 시가총액 상위 순으로 기업 조회

def get_excel_high_dividend(self):    #고배당주 엑셀 read
        load_wb = load_workbook("stock_div.xlsx", data_only=True)
        load_ws = load_wb['Sheet1']
        row_num = 0
        jcode=[]
        for row in load_ws.rows:
            row_num+=1
            if row_num==1:
                continue
            elif row_num==100:   #100개만
                break
            jcode.append(row[2].value)
        return jcode

    def get_excel_siga_top(self):  #시가총액 엑셀 read
        load_wb = open('siga.csv','r',encoding='utf-8')
        load_ws = csv.reader(load_wb)
        row_num = 0
        jcode=[]
        for row in load_ws:
            row_num+=1
            if row_num==1:
                continue
            jcode.append(row[1])
        return jcode

이 두 메서드는 시가총액 순서대로 기업코드가 적혀있는 엑셀과 고배당주 순서대로 기업코드가 적혀있는 엑셀을 읽어와 기업코드를 리턴하는 메서드입니다. 따라서 반복문을 시행하면서 위 알고리즘을 적용해 데이터 프레임을 산출해내면 다음과 같습니다.

 

이 프로그램의 실행결과 적합 판정을 받은 기업이 소수입니다. 현재 그만큼 자산시장이 고평가 되어있다고 볼 수도 있을 것 같습니다.