[python] 우선주와 보통주의 괴리율 계산하기

우선주와 본주의 괴리율 계산하기

우선주와 보통주의 괴리율 계산하기

1. 우선주란?

  • 주식은 의결권 여부에 따라 보통주와 우선주로 나눌 수 있음

  • 보통주(본주)는 주주총회에 참석하여 기업의 주요 경영사항에 대해 의결권을 행사하고 배당을 받는 등 주주로서의 권리를 행사할 수 있는 주식을 말함

  • 우선주는 의결권이 제한되지만 보통주보다 이익, 배당, 잔여재산 분배 등에 있어서 우선적 지위기 인정되는 주식

  • 1996년 상법개정 전 발행된 우선주는 본주명 뒤에 '-우', 이후 발행된 우선주는 '-우B'가 붙어 있음. B가 붙는 이유는 배당 자체를 보장해주는 채권(Bond)의 성격이 들어있기 때문임

  • 1우B, 2우B, 3우B에서 숫자는 발행 순서를 의미함

[출처]: 주린이가 가장 알고 싶은 최다질문 TOP 77

2. 우선주와 보통주의 괴리율

  • 우선주와 보통주의 괴리율은 다음과 같이 계산
$$괴리율 = 1-\frac{우선주가격}{보통주가격}$$
  • 괴리율이 높을수록 우선주가 보통주에 비해 저평가된 것으로 볼 수 있음

3. FinanceDataReader 패키지를 이용하여 우선주와 본주의 괴리율 계산

In [1]:
import FinanceDataReader as fdr
df_krx = fdr.StockListing('KRX')
df_krx['Name'] = df_krx['Name'].str.strip()
df_krx.head()
Out[1]:
Symbol Market Name Sector Industry ListingDate SettleMonth Representative HomePage Region
0 060310 KOSDAQ 3S 특수 목적용 기계 제조업 반도체 웨이퍼 캐리어 2002-04-23 03월 박종익, 김세완 (각자 대표이사) http://www.3sref.com 서울특별시
1 095570 KOSPI AJ네트웍스 산업용 기계 및 장비 임대업 렌탈(파렛트, OA장비, 건설장비) 2015-08-21 12월 이현우 http://www.ajnet.co.kr 서울특별시
2 006840 KOSPI AK홀딩스 기타 금융업 지주사업 1999-08-11 12월 채형석, 이석주(각자 대표이사) http://www.aekyunggroup.co.kr 서울특별시
3 054620 KOSDAQ APS홀딩스 기타 금융업 인터넷 트래픽 솔루션 2001-12-04 12월 정기로 http://www.apsholdings.co.kr 경기도
4 265520 KOSDAQ AP시스템 특수 목적용 기계 제조업 디스플레이 제조 장비 2017-04-07 12월 김영주 http://www.apsystems.co.kr 경기도
In [2]:
# 우선주 목록
ps_list = [s for s in df_krx['Name'] if s.endswith('우') | s.endswith('우B')]
print(ps_list)
['BYC우', 'CJ씨푸드1우', 'CJ우', 'CJ제일제당 우', 'DB하이텍1우', 'GS우', 'JW중외제약2우B', 'JW중외제약우', 'KG동부제철우', 'LG생활건강우', 'LG우', 'LG전자우', 'LG하우시스우', 'LG화학우', 'NH투자증권우', 'NPC우', 'S-Oil우', 'SK네트웍스우', 'SK디스커버리우', 'SK우', 'SK이노베이션우', 'SK증권우', 'SK케미칼우', '계양전기우', '금강공업우', '금호산업우', '금호석유우', '깨끗한나라우', '남선알미우', '남양유업우', '넥센우', '넥센타이어1우B', '노루페인트우', '노루홀딩스우', '녹십자홀딩스2우', '대교우B', '대덕1우', '대덕전자1우', '대림산업우', '대상우', '대상홀딩스우', '대신증권2우B', '대신증권우', '대원전선우', '대한제당우', '대한항공우', '대호피앤씨우', '덕성우', '동부건설우', '동양2우B', '동양3우B', '동양우', '동원시스템즈우', '두산2우B', '두산우', '두산퓨얼셀1우', '두산퓨얼셀2우B', '롯데지주우', '롯데칠성우', '미래에셋대우', '미래에셋대우2우B', '미래에셋대우우', '부국증권우', '삼성SDI우', '삼성물산우B', '삼성전기우', '삼성전자우', '삼성중공우', '삼성화재우', '삼양사우', '삼양홀딩스우', '서울식품우', '성문전자우', '성신양회우', '세방우', '소프트센우', '솔루스첨단소재1우', '솔루스첨단소재2우B', '신영증권우', '신원우', '신풍제약우', '아모레G우', '아모레퍼시픽우', '연우', '유안타증권우', '유유제약1우', '유유제약2우B', '유한양행우', '유화증권우', '이오플로우', '일양약품우', '진흥기업2우B', '진흥기업우B', '코리아써우', '코리아써키트2우B', '코오롱글로벌우', '코오롱우', '코오롱인더우', '크라운제과우', '크라운해태홀딩스우', '태양금속우', '태영건설우', '티와이홀딩스우', '하이트진로2우B', '하이트진로홀딩스우', '한국금융지주우', '한양증권우', '한진칼우', '한화3우B', '한화솔루션우', '한화우', '한화투자증권우', '현대건설우', '현대비앤지스틸우', '현대차2우B', '현대차3우B', '현대차우', '호텔신라우', '흥국화재2우B', '흥국화재우']
  • '미래에셋대우' 같이 본주의 마지막 글자가 '우'로 끝나는 종목을 따로 골라줌
In [3]:
exception = ['미래에셋대우', '연우', '이오플로우']
In [4]:
ps_list = [s for s in df_krx['Name'] if (s.endswith('우') | s.endswith('우B')) & (s not in exception)]
len(ps_list)
Out[4]:
117
In [5]:
df_ps = df_krx.loc[df_krx['Name'].isin(ps_list), ['Symbol', 'Market', 'Name']]
df_ps.head()
Out[5]:
Symbol Market Name
50 001465 KOSPI BYC우
57 011155 KOSPI CJ씨푸드1우
58 001045 KOSPI CJ우
60 097955 KOSPI CJ제일제당 우
72 000995 KOSPI DB하이텍1우
In [6]:
import re
# '~우'로 끝나는 종목은 '우' 앞자리 까지만 가져옴
df_ps.loc[df_ps['Name'].str.endswith('우'), 'CS_Name'] = df_ps['Name'].str[:-1]
# '~우B'로 끝나는 종목은 '우B' 앞자리 까지만 가져옴
df_ps.loc[df_ps['Name'].str.endswith('우B'), 'CS_Name'] = df_ps['Name'].str[:-2]
# 정규표현식으로 숫자만 제거
df_ps['CS_Name'] = df_ps['CS_Name'].map(lambda s: re.sub('\d+', '', s)).str.strip()
df_ps.head()
Out[6]:
Symbol Market Name CS_Name
50 001465 KOSPI BYC우 BYC
57 011155 KOSPI CJ씨푸드1우 CJ씨푸드
58 001045 KOSPI CJ우 CJ
60 097955 KOSPI CJ제일제당 우 CJ제일제당
72 000995 KOSPI DB하이텍1우 DB하이텍
In [7]:
import pandas as pd
df_krx = df_krx[['Symbol', 'Name', 'Sector']].rename(columns={'Symbol':'CS_Symbol', 'Name':'CS_Name'})
df_ps = pd.merge(df_ps, df_krx, how='left', on='CS_Name')
df_ps.head()
Out[7]:
Symbol Market Name CS_Name CS_Symbol Sector
0 001465 KOSPI BYC우 BYC 001460 봉제의복 제조업
1 011155 KOSPI CJ씨푸드1우 CJ씨푸드 011150 기타 식품 제조업
2 001045 KOSPI CJ우 CJ 001040 기타 금융업
3 097955 KOSPI CJ제일제당 우 CJ제일제당 097950 기타 식품 제조업
4 000995 KOSPI DB하이텍1우 DB하이텍 000990 반도체 제조업
In [9]:
fdr.DataReader(symbol='005930', start='20210122', end='20210122')
Out[9]:
Open High Low Close Volume Change
Date
2021-01-22 89000 89700 86800 86800 30430330 -0.014756
In [40]:
for idx in range(len(df_ps)):
    try:
        df_ps.loc[idx, 'PS_price'] = fdr.DataReader(symbol=df_ps.loc[idx, 'Symbol'], start='20210122', end='20210122')['Close'].iat[0]
    except:
        df_ps.loc[idx, 'PS_price'] = 0
    try:
        df_ps.loc[idx, 'CS_price'] = fdr.DataReader(symbol=df_ps.loc[idx, 'CS_Symbol'], start='20210122', end='20210122')['Close'].iat[0]
    except:
        df_ps.loc[idx, 'CS_price'] = 0
In [42]:
df_ps[(df_ps['PS_price']==0) | (df_ps['CS_price']==0)]
Out[42]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price
28 008355 KOSPI 남선알미우 남선알미 NaN NaN 42850.0 0.0
66 010145 KOSPI 삼성중공우 삼성중공 NaN NaN 336000.0 0.0
90 007815 KOSPI 코리아써우 코리아써 NaN NaN 7390.0 0.0
  • 남선알미늄, 삼성중공업, 코리아써키트는 우선주에서 이름이 축약되어 있어서 본주 이름이 제대로 들어가지 않았다.

  • 수정 후 다시 작업

In [43]:
df_ps.loc[df_ps['CS_Name']=='남선알미', 'CS_Name'] = '남선알미늄'
df_ps.loc[df_ps['CS_Name']=='삼성중공', 'CS_Name'] = '삼성중공업'
df_ps.loc[df_ps['CS_Name']=='코리아써', 'CS_Name'] = '코리아써키트'
In [47]:
df_ps = pd.merge(df_ps[['Symbol', 'Market', 'Name', 'CS_Name']], df_krx, how='left', on='CS_Name')
df_ps.head()
Out[47]:
Symbol Market Name CS_Name CS_Symbol Sector
0 001465 KOSPI BYC우 BYC 001460 봉제의복 제조업
1 011155 KOSPI CJ씨푸드1우 CJ씨푸드 011150 기타 식품 제조업
2 001045 KOSPI CJ우 CJ 001040 기타 금융업
3 097955 KOSPI CJ제일제당 우 CJ제일제당 097950 기타 식품 제조업
4 000995 KOSPI DB하이텍1우 DB하이텍 000990 반도체 제조업
In [48]:
for idx in range(len(df_ps)):
    try:
        df_ps.loc[idx, 'PS_price'] = fdr.DataReader(symbol=df_ps.loc[idx, 'Symbol'], start='20210122', end='20210122')['Close'].iat[0]
    except:
        df_ps.loc[idx, 'PS_price'] = 0
    try:
        df_ps.loc[idx, 'CS_price'] = fdr.DataReader(symbol=df_ps.loc[idx, 'CS_Symbol'], start='20210122', end='20210122')['Close'].iat[0]
    except:
        df_ps.loc[idx, 'CS_price'] = 0
In [49]:
df_ps[(df_ps['PS_price']==0) | (df_ps['CS_price']==0)]
Out[49]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price
In [50]:
df_ps.head()
Out[50]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price
0 001465 KOSPI BYC우 BYC 001460 봉제의복 제조업 150000.0 316500.0
1 011155 KOSPI CJ씨푸드1우 CJ씨푸드 011150 기타 식품 제조업 39350.0 4935.0
2 001045 KOSPI CJ우 CJ 001040 기타 금융업 64800.0 106000.0
3 097955 KOSPI CJ제일제당 우 CJ제일제당 097950 기타 식품 제조업 211000.0 443500.0
4 000995 KOSPI DB하이텍1우 DB하이텍 000990 반도체 제조업 124000.0 69200.0
In [53]:
# 괴리율 = 1 - 우선주가격/보통주가격
df_ps['diff'] = 1 - df_ps['PS_price']/df_ps['CS_price']
df_ps.head()
Out[53]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price diff
0 001465 KOSPI BYC우 BYC 001460 봉제의복 제조업 150000.0 316500.0 0.526066
1 011155 KOSPI CJ씨푸드1우 CJ씨푸드 011150 기타 식품 제조업 39350.0 4935.0 -6.973658
2 001045 KOSPI CJ우 CJ 001040 기타 금융업 64800.0 106000.0 0.388679
3 097955 KOSPI CJ제일제당 우 CJ제일제당 097950 기타 식품 제조업 211000.0 443500.0 0.524239
4 000995 KOSPI DB하이텍1우 DB하이텍 000990 반도체 제조업 124000.0 69200.0 -0.791908
In [57]:
df_ps.sort_values(['diff'], ascending=False)
Out[57]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price diff
55 33626K KOSPI 두산퓨얼셀1우 두산퓨얼셀 336260 전동기, 발전기 및 전기 변환 · 공급 · 제어 장치 제조업 20800.0 62500.0 0.667200
75 33637K KOSPI 솔루스첨단소재1우 솔루스첨단소재 336370 전자부품 제조업 18450.0 53900.0 0.657699
56 33626L KOSPI 두산퓨얼셀2우B 두산퓨얼셀 336260 전동기, 발전기 및 전기 변환 · 공급 · 제어 장치 제조업 24200.0 62500.0 0.612800
81 090435 KOSPI 아모레퍼시픽우 아모레퍼시픽 090430 기타 화학제품 제조업 94000.0 238000.0 0.605042
31 002355 KOSPI 넥센타이어1우B 넥센타이어 002350 고무제품 제조업 2625.0 6590.0 0.601669
... ... ... ... ... ... ... ... ... ...
17 001745 KOSPI SK네트웍스우 SK네트웍스 001740 기타 전문 도매업 112500.0 5560.0 -19.233813
50 001529 KOSPI 동양3우B 동양 001520 시멘트, 석회, 플라스터 및 그 제품 제조업 29650.0 1300.0 -21.807692
70 004415 KOSPI 서울식품우 서울식품 004410 기타 식품 제조업 4825.0 206.0 -22.422330
78 009275 KOSPI 신원우 신원 009270 봉제의복 제조업 37900.0 1560.0 -23.294872
66 010145 KOSPI 삼성중공우 삼성중공업 010140 선박 및 보트 건조업 336000.0 6770.0 -48.630724

117 rows × 9 columns

In [58]:
df_ps[df_ps['CS_Name']=='삼성전자']
Out[58]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price diff
65 005935 KOSPI 삼성전자우 삼성전자 005930 통신 및 방송 장비 제조업 77600.0 86800.0 0.105991
  • 삼성전자처럼 보통주와 우선주의 괴리율이 작은 종목이 있는가하면 두산퓨얼셀처럼 보통주와 우선주의 괴리율이 큰 종목도 있음

  • 일반적으로 우선주는 보통주에 비해 가격이 저렴하지만 삼성중공업우 같이 우선주의 가격이 보통주에 비해 비정상적으로 높은 주식도 있음

  • 이는 우선주의 총발행주식수가 매우 적어 발생할 수 있는 현상임

In [59]:
# 괴리율 상위 20개 종목
df_ps.sort_values(['diff'], ascending=False).head(20)
Out[59]:
Symbol Market Name CS_Name CS_Symbol Sector PS_price CS_price diff
55 33626K KOSPI 두산퓨얼셀1우 두산퓨얼셀 336260 전동기, 발전기 및 전기 변환 · 공급 · 제어 장치 제조업 20800.0 62500.0 0.667200
75 33637K KOSPI 솔루스첨단소재1우 솔루스첨단소재 336370 전자부품 제조업 18450.0 53900.0 0.657699
56 33626L KOSPI 두산퓨얼셀2우B 두산퓨얼셀 336260 전동기, 발전기 및 전기 변환 · 공급 · 제어 장치 제조업 24200.0 62500.0 0.612800
81 090435 KOSPI 아모레퍼시픽우 아모레퍼시픽 090430 기타 화학제품 제조업 94000.0 238000.0 0.605042
31 002355 KOSPI 넥센타이어1우B 넥센타이어 002350 고무제품 제조업 2625.0 6590.0 0.601669
80 002795 KOSPI 아모레G우 아모레G 002790 기타 화학제품 제조업 26250.0 64100.0 0.590484
112 005389 KOSPI 현대차3우B 현대차 005380 자동차용 엔진 및 자동차 제조업 111500.0 257000.0 0.566148
90 007815 KOSPI 코리아써우 코리아써키트 007810 전자부품 제조업 7390.0 17000.0 0.565294
105 00088K KOSPI 한화3우B 한화 000880 기타 화학제품 제조업 15100.0 34500.0 0.562319
26 011785 KOSPI 금호석유우 금호석유 011780 기초 화학물질 제조업 83700.0 190500.0 0.560630
22 28513K KOSPI SK케미칼우 SK케미칼 285130 합성고무 및 플라스틱 물질 제조업 181000.0 410500.0 0.559074
91 00781K KOSPI 코리아써키트2우B 코리아써키트 007810 전자부품 제조업 7620.0 17000.0 0.551765
12 108675 KOSPI LG하우시스우 LG하우시스 108670 플라스틱제품 제조업 37150.0 82500.0 0.549697
9 051905 KOSPI LG생활건강우 LG생활건강 051900 기타 화학제품 제조업 709000.0 1562000.0 0.546095
111 005387 KOSPI 현대차2우B 현대차 005380 자동차용 엔진 및 자동차 제조업 117500.0 257000.0 0.542802
59 00680K KOSPI 미래에셋대우2우B 미래에셋대우 006800 금융 지원 서비스업 4490.0 9800.0 0.541837
0 001465 KOSPI BYC우 BYC 001460 봉제의복 제조업 150000.0 316500.0 0.526066
113 005385 KOSPI 현대차우 현대차 005380 자동차용 엔진 및 자동차 제조업 122000.0 257000.0 0.525292
3 097955 KOSPI CJ제일제당 우 CJ제일제당 097950 기타 식품 제조업 211000.0 443500.0 0.524239
11 066575 KOSPI LG전자우 LG전자 066570 통신 및 방송 장비 제조업 87000.0 177500.0 0.509859