- 저자
- 김용환, Yubin Kim
- 출판
- 한빛미디어
- 출판일
- 2021.09.30
● 영업 효율이 좋은 기업을 찾는 지표 GP/A
처음 들어보는 지표인데, 매출총이익(Gross Profit)을 총 자산(Total Asset)으로 나눈 값이라고 한다. 이익을 자산으로 나눈 것이라 ROA랑 비슷한 개념인데, 당기순이익까지 계산하기 전 딱 영업이익만 보는 느낌이다.
GP/A = ( 매출액 - 매출원가 ) / 총 자산
ROA에서 당기 순이익(Net Income)은 여러 가지 것들이 묻어있는데, GP/A는 정말 기업의 영업 활동에 의한 매출 이익만 볼 수 있는 점이 장점이라고 한다.
또한, 가치투자 지표에 GP/A를 투자하면 싸지만 수익성이 떨어지는 종목을 매수하거나 비싸지만 수익성이 높은 종목을 매도하는 것을 방지할 수 있다고 한다. ROA는 별로였는데, GP/A를 확인해 보자.
pip install finterstellar
import finterstellar as fs
df=fs.fn_single(otp='otp', symbol='ASML',window='T')
df['Avg Assets']=(df['Total Assets'] + df['Total Assets'].shift(4))/2
df['GP/A']=df['Gross Profit']/ df['Avg Assets']
#ROA
df['ROA']=df['Net Income']/df['Avg Assets']
#그래프 GP/A, 가격
fs.draw_chart(df,left='GP/A', right='Price')
#GP/A, ROA
fs.draw_chart(df,left=['GP/A','ROA'])
그래프를 그려보면, GP/A와 주가가 어느 정도 상관관계는 있어 보이긴 한다.
ROA와 비교를 해보자. GP/A와 ROA가 아주 똑같이 같은 방향으로 움직이고 있다. 하지만, 어떤 종목에 한해서는 세금을 몰아내거나 기타 다른 영향으로 트렌드가 달라질 수 있다. GP/A가 높은 종목 30개에 대한 백테스트 진행해 보자.
terms=fs.set_terms(trade_start='2011Q1', trade_end='2023Q1')
data={}
for t in terms:
data[t]=fs.fn_consolidated(otp='otp', term=t)
prev_t=fs.quarters_before(terms,t,4)
data[t]['Avg Assets']=(data[t]['Total Assets']+data[prev_t]['Total Assets'])/2
data[t]['GP/A'] = data[t]['Gross Profit']/ data[t]['Avg Assets']
data[t].loc[(data[t]['Gross Profit']<0) | (data[t]['Avg Assets']<0) | (data[t]['Total Assets']<0), 'GP/A']=float('nan')
s={}
signal = {}
for t in terms :
s[t]=fs.fn_filter(data[t], by='GP/A', floor = 0, n=30, asc=False)
signal[t]=list(s[t].index)
df=fs.backtest(singal=signal, data=data, m=3, cost=0.001)
결과는 아래와 같다. 이게 fs.draw_return(df)로 수익률을 그려보면, 2020년까지는 기가 막히게 수익률을 추월하는 듯하였으나, 장이 박살 나면서 굿바이 마이 프렌드 하는 형상이 된다.
CAGR: 6.91%
Accumulated return: 123.17%
Investment period: 12.0yrs
Sharpe ratio: 0.39
MDD: -39.64%
● 가치주 지표와의 결합 (PER, PBR)
예전에 했던 백테스트 기법에서 시그널 항을 2개 만들어서 상대 점수 혹은 교집합으로 순서를 내는 방식으로 결합할 수 있다. 위에 terms로 돌려놨으니 바로 이어서 진행해 보자.
s={}
signal={}
for t in terms:
data[t]['PER']=data[t]['Price_M3']/data[t]['EPS']
s[t]=fs.fn_filter(data[t],by='PER',floor=1, cap=10,n=30, asc=True)
signal[t] = list(s[t].index)
df=fs.backtest(signal=signal, data=data,m=3,cost=0.001)
CAGR: 0.96%
Accumulated return: 12.22%
Investment period: 12.0yrs
Sharpe ratio: 0.04
MDD: -46.61%
30개 하위 PER에 대한 3개월 리밸런싱 전략은 결과가 매우 별로이다.
s={}
s1={}
s2={}
signal={}
for t in terms:
prev_t = fs.quarters_before(terms, t, 4)
data[t]['PER'] = data[t]['Price_M3'] / data[t]['EPS']
data[t]['Avg Assets'] = ( data[t]['Total Assets']+ data[prev_t]['Total Assets'])/2
data[t]['GP/A']=data[t]['Gross Profit']/data[t]['Avg Assets']
data[t].loc[(data[t]['Gross Profit']<0) | (data[t]['Avg Assets']<0) | (data[t]['Total Assets']<0), 'GP/A'] = float('nan')
s1[t] = fs.fn_score(data[t], by='PER', method='relative', floor=1, cap=10, asc=True)
s2[t] = fs.fn_score(data[t], by='GP/A', method='relative', floor=0, asc=False)
s[t]=fs.combine_score(s1[t], s2[t], n=30)
signal[t] = list(s[t].index)
df= fs.backtest(signal=signal, data=data, m=3, cost=0.001)
CAGR: 0.80%
Accumulated return: 10.04%
Investment period: 12.0yrs
Sharpe ratio: 0.03
MDD: -55.31%
합쳐도 별로이다. PBR로 해보자
s={}
signal={}
for t in terms:
data[t]['PBR']=data[t]['Price_M3'] / (data[t]['Shareholders Equity']/ data[t]['Shares'])
s[t] = fs.fn_filter(data[t], by='PBR', floor=0.1, cap=1, n=30, asc=True)
signal[t]=list(s[t].index)
df=fs.backtest(signal=signal, data=data, m=3, cost=0.001)
CAGR: 26.98%
Accumulated return: 1661.13%
Investment period: 12.0yrs
Sharpe ratio: 2.99
MDD: -43.98%
오 PBR을 꽤 의미가 있다. PBR 전략으로 계좌를 하나 파야 되나 싶을 정도로 괜찮은 것 같다. 물론 MDD를 버텨야 하는 문제가 있긴 하다. 여기에 GP/A를 섞어보자. 큰 개선이 되진 않을 것 같긴 하다.
s={}
s1={}
s2={}
signal={}
for t in terms:
prev_t = fs.quarters_before(terms, t, 4)
data[t]['PBR'] = data[t]['Price_M3'] / (data[t]['Shareholders Equity']/data[t]['Shares'])
data[t]['Avg Assets'] = ( data[t]['Total Assets']+ data[prev_t]['Total Assets'])/2
data[t]['GP/A']=data[t]['Gross Profit']/data[t]['Avg Assets']
data[t].loc[(data[t]['Gross Profit']<0) | (data[t]['Avg Assets']<0) | (data[t]['Total Assets']<0), 'GP/A'] = float('nan')
s1[t] = fs.fn_score(data[t], by='PBR', method='relative', floor=0.1, cap=1, asc=True)
s2[t] = fs.fn_score(data[t], by='GP/A', method='relative', floor=0, asc=False)
s[t]=fs.combine_score(s1[t], s2[t], n=30)
signal[t] = list(s[t].index)
df= fs.backtest(signal=signal, data=data, m=3, cost=0.001)
CAGR: 16.17%
Accumulated return: 504.62%
Investment period: 12.0yrs
Sharpe ratio: 1.19
MDD: -48.90%
오히려 수익성이 떨어졌다. 좋은 전략을 섞는다고 무조건 좋은 것은 아니라는 것을 알 수 있었다.
EV/EBITA EV/Sales, NCAV(안전마진, 1170%의 수익률), PEG(주가수익성장비율)로 백테스트 해보기 (feat. 핀터
https://jhhistory.tistory.com/entry/%EA%B0%80%EC%B9%98%EC%A7%80%ED%91%9C-%EA%B2%B0%ED%95%A9%ED%95%98%EA%B8%B0-PER-PBR-%EB%93%B1-%ED%8C%8C%EC%9D%B4%EC%8D%AC-Finterstellar-%EB%AA%A8%EB%93%88-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0 가치지표 결합하기 (PER
jhhistory.tistory.com
가치지표 결합하기 (PER , PBR 등) - 파이썬 Finterstellar 모듈 활용하기
미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀
jhhistory.tistory.com
미국주식으로 시작하는 슬기로운 퀀트투자 5장(1) - 가치주를 찾는 기술 (feat. PER Band Chart 핀터스
미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀
jhhistory.tistory.com
단기 투자의 기술 편 (보조지표를 통한 백테스팅) - 슬기로운 퀀트투자 3장
미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀
jhhistory.tistory.com
슬기로운 퀀트투자 - 2장 일단 해보자 편
미국 주식으로 시작하는 슬기로운 퀀트투자 이 책은 서학개미를 위한 미국 주식 퀀트투자 입문+실습서이다. 퀀트투자는 수학적, 통계적 기법을 활용해 투자 종목을 발굴하는 투자 방법이다. 퀀
jhhistory.tistory.com
'미래걱정 > 주식' 카테고리의 다른 글
달러와 엔화, 미국과 일본 더 안전하고 유망한 투자처는? (0) | 2023.07.09 |
---|---|
안정성 지표 (부채비율, 차입금 비율)을 통한 백테스트 - 슬기로운 퀀트투자 6장 우량주를 찾는 기술 (finterstellar) (0) | 2023.04.08 |
우량주를 찾는 기술 (ROA, ROE, RIM) [슬기로운 퀀트투자 6장(feat. finterstellar)] (0) | 2023.04.04 |
EV/EBITA EV/Sales, NCAV(안전마진, 1170%의 수익률), PEG(주가수익성장비율)로 백테스트 해보기 (feat. 핀터스텔라 finterstellar) (0) | 2023.04.02 |
가치지표 결합하기 (PER , PBR 등) - 파이썬 Finterstellar 모듈 활용하기 (0) | 2023.03.31 |
댓글