본문 바로가기
미래걱정/주식

가치지표 결합하기 (PER , PBR 등) - 파이썬 Finterstellar 모듈 활용하기

by JHistory_ 2023. 3. 31.
반응형
 
미국 주식으로 시작하는 슬기로운 퀀트투자
이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀트투자 전략을 만들기 위해서는 유명한 전략들이 어떻게 만들어졌는지 개념을 이해하고, 어떻게 구현됐는지 기본기를 따라 하며 배워야 한다. 다만 투자 대가들의 전략을 소개한 책은 쉽게 찾아볼 수 있지만, 그 전략을 구현한 기술적인 방법을 담은 책은 매우 찾아보기 어렵다. 또한 퀀트투자 전략을 공부하기 위해서는 코딩이나 수학 등 부가적인 배경지식이 필요하다. 이 책은 이미 잘 알려진 투자 대가들의 전략을 소개하고 자신의 컴퓨터에서 이 전략을 구현해보며 응용하는 방법을 알려준다. 책을 따라 미국 주식 퀀트투자 과정을 배우고 나면 자신만의 투자 전략을 스스로 개발할 수 있을 것이다.
저자
김용환, Yubin Kim
출판
한빛미디어
출판일
2021.09.30

https://jhhistory.tistory.com/entry/%EB%AF%B8%EA%B5%AD%EC%A3%BC%EC%8B%9D%EC%9C%BC%EB%A1%9C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EC%8A%AC%EA%B8%B0%EB%A1%9C%EC%9A%B4-%ED%80%80%ED%8A%B8%ED%88%AC%EC%9E%90-5%EC%9E%A51-%EA%B0%80%EC%B9%98%EC%A3%BC%EB%A5%BC-%EC%B0%BE%EB%8A%94-%EA%B8%B0%EC%88%A0-feat-PER-Band-Chart-%ED%95%80%ED%84%B0%EC%8A%A4%ED%85%94%EB%9D%BC

 

미국주식으로 시작하는 슬기로운 퀀트투자 5장(1) - 가치주를 찾는 기술 (feat. PER Band Chart 핀터스

미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀

jhhistory.tistory.com

 

● 가치지표를 섞어서 백테스팅을 해보자

 책에서는 5장 '가치주를 찾는 기술' 후반 부이다. PER과 PBR을 합쳐서 백 테스팅을 해보자. 교집합을 통해 종목 개수를 추릴 수도 있고, 나름의 점수를 매겨서 줄 세우는 방법이 있을 수 있다고 한다.

 

 후자의 경우 PER이 낮은 순서대로 100점 99점 이렇게 판단할 수도 있고, PER이 1배~10배 면 100점 이런 식으로 판단할 수도 있겠다. 후자는 상황에 따른 본인의 점수 표준표 세팅이 엄청 중요하겠다.

● PER과 PBR의 교집합

지난 5장의 (1)에서 했던 것처럼 일단 PER과 PBR에 대한 퀀트 머신의 판단 시그널을 만들어 준다. 구글 콜랩 키고 pip install finterstellar 해준다음에,

 

import finterstellar as fs
t='2022Q4'
data = fs.fn_consolidated(otp='otp',term=t,vol=0)
data['PER']=data['Price_M3']/data['EPS']
data['PBR']=data['Price_M3']/(data['Shareholders Equity']/data['Shares'])
s1=fs.fn_filter(data,by='PER',floor=1,cap=10,n=10,asc=True)
s2=fs.fn_filter(data,by='PBR',floor=0.1,cap=1,n=10,asc=True)

 

자세한 내용은 반복이라 생략한다. 책과 다르게 2022Q4까지로 하였다. s1과 s2에 어떤 종목이 있는지 살펴보면

 

             PER
symbol          
STAR    1.071542
IMPP    1.142857
ESEA    1.156144
ZEV     1.230769
IREN    1.241667
SBOW    1.364997
AIHS    1.383562
UHAL    1.410104
AZTA    1.427900
SOHO    1.428571
             PBR
symbol          
IMPP    0.107932
CS      0.121102
RKT     0.124655
ROOT    0.128281
KEP     0.128969
COHN    0.132144
BBGI    0.134380
NXTP    0.134399
ACOR    0.134717
TUYA    0.135764

 

이렇게 출력이 된다. 진짜 진심 난생 첨 보는 티커들이다. s1과 s2를 합칠 건데, 교집함이니까 'and'로 간다.(합집합이면 or) 합치는 명령어는 combine_signal() 함수이다.

 

	PER	PBR
symbol		
IMPP	1.142857	0.107932

 

이러면 한 종목 밖에 산출되지 않는다. or이면 19개 종목이 합산되겠지.. 점수방식으로 섞는 다면 아래와 같이 진행하면 된다. 

 

s1=fs.fn_score(data, by='PER', method='absolute', floor=1,cap=10, asc=True)
s2=fs.fn_score(data, by='PBR', method='absolute', floor=0.1, cap=1, asc=True)

 

그러면 PER이 1에 가까운 순서부터 높은 순서대로 100점에서 점수를 나눠먹고 PBR도 마찬가지로 형성이 된다. 

 

             PER  Score
symbol                 
STAR    1.071542   99.2
IMPP    1.142857   98.4
ESEA    1.156144   98.3
ZEV     1.230769   97.4
IREN    1.241667   97.3
...          ...    ...
NBTB    9.960452    0.4
FCCO    9.963731    0.4
EEX     9.970588    0.3
MBCN    9.980843    0.2
GS      9.991442    0.1

[746 rows x 2 columns]


             PBR  Score
symbol                 
IMPP    0.107932   99.1
CS      0.121102   97.7
RKT     0.124655   97.3
ROOT    0.128281   96.9
KEP     0.128969   96.8
...          ...    ...
OMI     0.997372    0.3
AZTA    0.998183    0.2
BY      0.998897    0.1
FIBK    0.999545    0.1
LMND    0.999879    0.0

[868 rows x 2 columns]

 

이 점수를 가지고 높은 순으로 잘라보자 10개로 추려보자. 10개를 추려내는 기준은 PER과 PBR로 추려낸 signal에서 점수가 둘 다 높은 형태로 교집합을 이루고 있는 방식으로 추려내는 것으로 보인다.

 

fs.combine_score(s1,s2,n=10)

 

 Score	Score_	Sum
symbol			
IMPP	49.20	49.55	98.75
CRESY	47.35	44.30	91.65
REI	47.60	38.25	85.85
GTN	45.00	40.10	85.10
DISH	43.95	40.60	84.55
HT	44.50	38.05	82.55
STAR	49.60	32.80	82.40
FRC	40.20	42.15	82.35
PACW	40.30	40.20	80.50
EDRY	47.55	32.40	79.95

 

만약 상대 값으로 가져가면 가장 PER이 낮은 종목이 100인 것을 기준으로 PER의 배수에 따라 점수를 균등 배분하는 식으로 가져가는 것 같다. 

 

s1=fs.fn_score(data, by='PER', method='relative', floor=1,cap=10, asc=True)
s2=fs.fn_score(data, by='PBR', method='relative', floor=0.1, cap=1, asc=True)
print(s1), print(s2)

 

그럼 아래와 같은 결과가 출력된다.

 

             PER  Score
symbol                 
STAR    1.071542  100.0
IMPP    1.142857   99.9
ESEA    1.156144   99.7
ZEV     1.230769   99.6
IREN    1.241667   99.5
...          ...    ...
NBTB    9.960452    0.7
FCCO    9.963731    0.5
EEX     9.970588    0.4
MBCN    9.980843    0.3
GS      9.991442    0.1

[746 rows x 2 columns]
             PBR  Score
symbol                 
IMPP    0.107932  100.0
CS      0.121102   99.9
RKT     0.124655   99.8
ROOT    0.128281   99.7
KEP     0.128969   99.5
...          ...    ...
OMI     0.997372    0.6
AZTA    0.998183    0.5
BY      0.998897    0.3
FIBK    0.999545    0.2
LMND    0.999879    0.1

[868 rows x 2 columns]
(None, None)

 

마찬가지로 시그널 2개에 대해 합쳐보면

fs.combine_score(s1,s2,n=10)

 

아래와 같은 결과가 도출된다. 절댓값과 상대값과 순위차이는 있지만 거의 비슷한 느낌이다.

 

Score	Score_	Sum
symbol			
IMPP	49.95	50.00	99.95
CRESY	49.05	48.55	97.60
REI	49.35	45.95	95.30
GTN	48.40	46.90	95.30
DISH	47.80	47.20	95.00
HT	48.10	45.90	94.00
FRC	46.00	47.60	93.60
PACW	46.05	47.00	93.05
STAR	50.00	42.90	92.90
EDRY	49.25	42.50	91.75

 

● 가치투자 지표 4개 합쳐보기

 내가 좋아하는 할 수 있다 알고 투자 강환국 작가님은 '슈퍼가치전략'이라는 이름으로 PER PBR PCR PSR의 지표를 다 섞어서 소형주에 투자하는 전략을 사용하면 2004년부터 2016년까지 이 전략으로 투자하면 연간 38%의 수익률을 기록한다고 언급한 적이 있다고 한다.

 

  • 시가총액 하위 20% 주식을 뽑아냄.
  • 뽑아낸 주식을 대상으로 PER PBR PCR PSR 지표 순위를 매김 
  • 4 지표의 순위를 더해 종합 순위를 매긴다.
  • 종합 순위가 높은 상위 50개 종목에 투자한다.
  • 연 1회 리밸런싱

순서대로 진행해 보자. 

 

#기간별 data를 뽑아옴

terms=fs.set_terms(trade_start='2011Q1',trade_end='2022Q4')
data={}
for t in terms:
  data[t]=fs.fn_consolidated(otp='otp',term=t)
  
#PER PBR PSR PCR을 구함

for t in terms:
  data[t]['Market Cap']=data[t]['Price_M3']*data[t]['Shares']
  data[t]['PER']=data[t]['Price_M3']/data[t]['EPS']
  data[t]['PBR']=data[t]['Price_M3']/(data[t]['Shareholders Equity']/data[t]['Shares'])
  data[t]['PSR']=data[t]['Price_M3']/(data[t]['Revenue']/data[t]['Shares'])
  data[t]['PCR']=data[t]['Price_M3']/((data[t]['Net Income']+data[t]['Depreciation'])/data[t]['Shares'])
  
  #시가총액 계산이 잘 되어있는 지 확인, 2021년 1분기를 시가총액 순위로 내림차순 정리
  data['2021Q1'].sort_values(by='Market Cap', ascending=False).head()

 

그다음은 시그널을 변수에 담고 시가총액 순으로 오름차순으로 솎아내고 (작은 것부터 위로), PER PBR PSR PCR에 대한 시그널도 낮은 것부터 추려낸다. PER만 1부터 나머지는 0.1부터

 

s1={}
s2={}
s3={}
s4={}
s5={}

#20%시가총액 뽑을 수가 없어서 5000개 종목 중 1000개로 선정

for t in terms:
  s1[t]=fs.fn_filter(data[t],by='Market Cap', floor=0, n=1000, asc=True)
  s2[t]=fs.fn_score(data[t], by='PER', method='relative', floor=1, asc=True)
  s3[t]=fs.fn_score(data[t], by='PBR', method='relative', floor=0.1, asc=True)
  s4[t]=fs.fn_score(data[t], by='PSR', method='relative', floor=0.1, asc=True)
  s5[t]=fs.fn_score(data[t], by='PCR', method='relative', floor=0.1, asc=True)

 

상대평가 처리했고, score에 대한 합치기 해보자.

 

s6={}
for t in terms:
	s6[t] = fs.combine_score(s2[t], s3[t], s4[t], s5[t])

 

그러면 아래와 같이  2011 Q3 기준으로 점수가 합산되어 있다. 각 항목(PER PBR PSR PCR)에 대한 점수를 합산한 대로 내림차순으로 나열된다.

 

[1535 rows x 5 columns], '2011Q3':          Score  Score_  Score_  Score_     Sum
symbol                                        
SOL     25.000  24.850  24.925  24.850  99.625
GOOG    24.975  24.875  23.425  24.825  98.100
CAAS    24.850  24.075  23.625  24.575  97.125
HPQ     24.675  23.350  24.450  24.600  97.075
SPXC    24.275  24.500  24.300  23.800  96.875
...        ...     ...     ...     ...     ...
HALO       NaN   0.175   0.425     NaN   0.600
VHC        NaN   0.375   0.025     NaN   0.400
INVA       NaN     NaN   0.225     NaN   0.225
GSG        NaN     NaN   0.075     NaN   0.075
MNKD       NaN     NaN   0.025     NaN   0.025

 

분기별로 50개 종목을 선정해 본다.

 

s={}
signal = {}
for t in terms:
    s[t]=fs.combine_signal(s6[t], s1[t], how='and',n=50)
    signal[t] =list(s[t].index)

 

s 리스트에 대해서 시가총액 리스트와 교집합 시켜서 signal을 만들어본다. 예를 들어 2021Q4에 대해 종목이 필터 된 것을 확인해 보면

 

print(signal['2021Q4'])

 

['OPFI', 'LX', 'XYF', 'SSY', 'SALM', 'LDI', 'BZH', 'TPC', 'CLPS', 'COWN', 'CONN', 'DHC', 'QIWI', 'RYAM', 'BBAR', 'PANL', 'NLS', 'BEST', 'CRESY', 'AAN', 'LAZY', 'GLBS', 'TCS', 'QD', 'ADES', 'VIOT', 'CTRM', 'JOB', 'FHS', 'CVLG', 'BGFV', 'PFSW', 'ACCO', 'MITT', 'CPOP', 'UONEK', 'KIRK', 'OVID', 'MOD', 'BXC', 'SB', 'ACTG', 'TLYS', 'EMKR', 'CBAT', 'RCON', 'USX', 'OPRT', 'KOP', 'RVP']

 

이 정도가 추려졌는데, 정말 한 번도 들어 본 적이 없는 종목이다. 이제 백테스트를 돌려보면 아래와 같다. 가격은 재무제표 발표 후 3개월 후의 주가를 이용하는 것이다.

 

df=fs.backtest(signal=signal, data=data, m=3, cost=0.001)

 

결과를 보면 아래와 같다.

 

CAGR: 5.68%
Accumulated return: 91.54%
Investment period: 11.8yrs
Sharpe ratio: 0.25
MDD: -51.66%

 

미국 주식으로는 연평균 수익률 5.68% 밖에 되지 않는다. 역시 미국에서 초보자는 S&P500이 최고 ~!라고 생각할지는 모르겠지만, 만약 대형주로 바꿔서 백테스트를 해보면 (asc=False로 변경) 어떨까?라는 생각을 해볼 수도 있다.

2011년 1분기부터 2022년 4분기까지의 포트폴리오의 수익률과 벤치마크 수익률의 비교이다. 코로나 시기 전까지는 대동소이하다가 코로나 이후 S&P500의 수익률이 훨씬 좋아졌다.

 

s1만 시가총액의 순서이므로 False로 해서 순서만 돌려주자 (상위 20% 종목 발굴)

 

for t in terms:
  s1[t]=fs.fn_filter(data[t],by='Market Cap', floor=0, n=1000, asc=False)
  s2[t]=fs.fn_score(data[t], by='PER', method='relative', floor=1, asc=True)
  s3[t]=fs.fn_score(data[t], by='PBR', method='relative', floor=0.1, asc=True)
  s4[t]=fs.fn_score(data[t], by='PSR', method='relative', floor=0.1, asc=True)
  s5[t]=fs.fn_score(data[t], by='PCR', method='relative', floor=0.1, asc=True)
  s6[t] = fs.combine_score(s2[t], s3[t], s4[t], s5[t])
  s[t]=fs.combine_signal(s6[t], s1[t], how='and',n=50)
  signal[t] =list(s[t].index)
  
df=fs.backtest(signal=signal, data=data, m=3,cost=0.001)

 

for 문 돌렸던 것을 한 번에 처리하고 백테스트를 돌렸다. 더 구리다. 시가총액이 높은 순서로 사서 저 PER, PBR, PSR, PCR의 순서대로 점수를 먹여서 리벨런싱 하는 것도 답이 아니라는 말이다.

 

CAGR: 4.11%
Accumulated return: 60.61%
Investment period: 11.8yrs
Sharpe ratio: 0.22
MDD: -45.61%

 

2011년 1분기부터 2022년 4분기까지의 포트폴리오의 수익률과 벤치마크 수익률의 비교이다. 

 

2011년 1분기부터 2022년 4분기까지의 포트폴리오의 수익률과 벤치마크 수익률의 비교이다. (시가 총액 상위 20% 기준) 코로나 시기 전까지는 대동소이하다가 코로나 이후 S&P500의 수익률이 훨씬 좋아졌다.

 

상승장에서 소형주가 대형주보다 상승률이 더 높았다는 뜻인데, 어줍잖은 전략을 쓸바에는 그냥 S&P500사자.

 


 

https://jhhistory.tistory.com/entry/%EC%8A%AC%EA%B8%B0%EB%A1%9C%EC%9A%B4-%ED%80%80%ED%8A%B8%ED%88%AC%EC%9E%90-2%EC%9E%A5-%EC%9D%BC%EB%8B%A8-%ED%95%B4%EB%B3%B4%EC%9E%90-%ED%8E%B8

 

슬기로운 퀀트투자 - 2장 일단 해보자 편

미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀

jhhistory.tistory.com

 

https://jhhistory.tistory.com/entry/%EC%8A%AC%EA%B8%B0%EB%A1%9C%EC%9A%B4-%ED%80%80%ED%8A%B8%ED%88%AC%EC%9E%90-3%EC%9E%A5-%EB%8B%A8%EA%B8%B0-%ED%88%AC%EC%9E%90%EC%9D%98-%EA%B8%B0%EC%88%A0-%ED%8E%B8-%EB%B3%B4%EC%A1%B0%EC%A7%80%ED%91%9C%EB%A5%BC-%ED%86%B5%ED%95%9C-%EB%B0%B1%ED%85%8C%EC%8A%A4%ED%8C%85

 

슬기로운 퀀트투자 3장 - 단기 투자의 기술 편 (보조지표를 통한 백테스팅)

미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀

jhhistory.tistory.com

 

반응형

댓글