
파이썬으로 배우는 포트폴리오 study day1
재무기초지식
현금흐름, 이자율과 시간 가치
미래가치는 단리 또는 복리(연속복리 포함)로 계산할 수 있다.
단리는 최초의 금액을 대상으로 이율을 곱해 미래가치를 계산하고,
복리는 일정기간마다 이자를 원금에 합쳐 그 합계 금액에 대한 이자를 다시 계산
단리 : 원금 x (1 + 이율 x 기간)
복리 : 원금 x (1 + 이율)$^{기간}$
단리이자 계산
(1)
은행에 1,000만 원 예금하고 1년 후에 인출하기로 한다. 1년 후 받는 금액을 단리로 계산하면 다음과 같다.
원금 = 1,000만원
이율 = (연간) 5%
기간 = 1년
1년 후 인출액 = 1,000만 원 x (1 + 5% x 1) = 10,500,000원
# 변수 a에 예금액 입력
a = 1000
# 1년간 이자 계산이 1회 이뤄지므로 변수 n에 1을 입력
n = 1
# 이자율은 5%이므로 0.05 입력
r = 0.05
# 단리 계산이므로 원금액*(1+이자율*기간) 식에 따라 계산
s_simple = a*(1+r*n)
print(s_simple)
(2)
주의할 점은, 이율과 기간의 단위가 같아야 한다.
이자율은 보통 연 단위로 표시하는데, 만일 월 단위로 바꿔 계산한다면 이율은 12로 나눠야 함
원금 = 1,000만원
이율 = (월간) 5% / 12
기간 = 12개월
1년 후 인출액 = 1,000만 원 x (1 + 5% x 1) = 10,500,000원
# 변수 a에 예금액 입력
a = 1000
# 1년간 이자 계산이 12회 이뤄지므로 n=12을 입력
n = 12
# 1년간 이자율 5%를 12로 나눠 월간 이자율로 바꾼다.
# 이자 계산도 월간, 이자율도 월간으로 일치시키는 것
r = 0.05/n
# 단리 계산이므로 원금액*(1+이자율*기간) 식에 따라 계산
s_simple = a*(1+r*n)
print(s_simple)
간단한 계산이라 수식만으로 계산이 가능하지만, numpy_financial 라이브러리의 fv
함수를 이용할 수도 있다.
책에는 scipy 라이브러리 사용한다 했는데...
AttributeError: Module 'scipy' has no attribute 'fv'
라 떠서.. 찾아보니 numpy_financial 라이브러리를 이용해야 한다고 한다.
npf.fv(rate, nper, pmt, pv=0, when='end')
- rate : 이율
- nper : 복리 투자기간(연 단위)
- pmt : payment
- pv : present value
import numpy_financial as npf
# 미래가치를 계산하기 위한 변수로 설정
a = 1000
n = 1
r = 0.05
# fv() 함수를 이용해 미래가치를 계산
s_simple = npf.fv(r, n, 0, -a)
print(s_simple)
# >> 1050.0
#--------
# 월 단위라면
a = 1000
n = 12
r = 0.05
s_simple = npf.fv(r/n, n, 0, -a)
print(s_simple)
# >> 1051.161897881733
npf.fv는 복리계산이라 두 개의 값이 다르게 나온다...
내 구글링이 부족한지 단리 계산법은 못 찾겠다..ㅠㅠ
복리 계산
이율 5%를 월 복리로 계산한다면, 즉 월마다 생기는 이자에 대한 이자를 누적해 계산한다면 다음과 같다.
원금 = 1,000만 원
이율 = (월간) 5% / 12
기간 = 12개월
1년 후 인출액 = 1,000만 원 x (1 + (5% / 12))$^{12}$ = 10,511,619원
# 5% 이자율을 월 단위로 복리 계산하는 경우
a = 1000
# 이자 계산 횟수는 12회이므로 n=12이다
n = 12
# 이자율을 5%이므로 r = 0.05
r = 0.05
# 복리식에 따라 복리 계산을 한다
# r/n은 이자 횟수별 이자율을 계산
s_compound = a*(1+(r/n))**n
print(s_compound)
# >> 1051.161897881733
연속복리
연속 복리 : 원금 $\times e^r$
특징은 복리 횟수가 늘어날수록 값은 오일러상수에 근접하게 된다. ( 대략 2.718...)
NPV와 IRR
현금흐름을 할인하는 방법.
NPV
순현재가치(Net Present Value, NPV)
현재의 액면가를 나타내는 현금 흐름의 순가치. 돈의 시간 가치로 인해 오늘 돈을 받는 것이 내일 돈을 받는 것보다 가치가 높다. 화폐가치는 계속 떨어지기 때문. NPV는 미래에 발생할 일련의 현금흐름을 현재가치로 계산한 것
NPV = SUM(현금흐름 / (1 + 할인율)$^i$
$$
NPV = \sum \frac{C}{(1+rate)^i}
$$
C는 현금흐름, rate는 할인율, i는 기간
현재 시점에서 70,000을 지출해 사업을 시작하고 나서 향후 5년 동안 다음과 같은 수익을 내는 사업이 있을 때 사업타당성을 검토한다. 할인율이 1.5%라고할 때, NPV가 0 이상이면 수익성이 있다고 판단해 투자안을 채택하고, 그렇지 않다면 투자안을 포기한다.
예시)
현재 - 현금 유출 : - 70,000 | 순현금흐름 : -70,000 => 87,517
1년후 - 현금 유입 : 12,000 | 순현금흐름 : 12,000 | NPV : 11,823
2년후 - 현금 유입 : 15,000 | 순현금흐름 : 15,000 | NPV : 14,560
3년후 - 현금 유입 : 18,000 | 순현금흐름 : 18,000 | NPV : 17,214
4년후 - 현금 유입 : 21,000 | 순현금흐름 : 21,000 | NPV : 19,786
5년후 - 현금 유입 : 26,000 | 순현금흐름 : 26,000 | NPV : 24,135
| 최종 NPV 합: 17,517
위 내용을 python 코드로 나타내보자.
# 현금흐름을 cashflows 리스트에 저장한다.
# i는 햇수, r은 이자율
cashflows = [12000, 15000, 18000, 21000, 26000]
i = 0
r = 0.015
# 최소 투자금액이며 현금 유출이므로 (-)로 표시
npv = -7000
# cashflows 리스트를 반복해 미래에 들어올 현금흐름을 할인함으로써 현재가치로 계산한 다음 npv변수에 누적
for c in cashflows:
i = i + 1
npv = npv + c/(1+r)**i
print(npv)
# 17516.929512135568
npv는 numpy_financial의 npv()
함수를 이용한다.
npf.npv(rate, values)
import numpy_financial as npf
import numpy as np
# 현금흐름을 리스트로 만든다.
# cashflows[0]에 초기 자금을 기재
cashflows = [-7000, 12000, 15000, 18000, 21000, 26000]
r = 0.015
# 순현재가치
npv = npf.npv(r, cashflows)
print(npv)
# 17516.929512135568
IRR
내부수익률(Internal Rate of Return, IRR)
- 수익률 : 현재 시점의 가치를 미래 시점의 가치로 환산할 때
- 할인율 : 미래 시점의 가치를 현재 시점의 가치로 환산할 때
NPV가 0인 경우의 할인율이 IRR이다.
현금 유입과 현금 유출의 현재가치를 일치 시키면 NPV = 0이고, 이때 할인율이 IRR.
NPV의 예제에서 IRR > 기업의 자본비용(시장이자율)일 경우 그 사업을 채택하고, 그렇지 않으면 사업을 포기한다.
IRR은 투자의 수익성을 측정하는 지표이지만, 이것만 갖고 의사결정을 하지는 않는다. 투자 기간이 짧고 초반 현금 유입이 클수록 IRR은 높을 수 있다. 그러나 장기적으로 현금 유입이 더 많은 경우에는 단기 투자안보다 가치가 높을 수 있기 때문이다.
$$ IRR = NPV = \sum \frac{C_t}{(1+rate)^t} - C_0 = 0 $$
IRR은 numpy_financial의 irr()
을 이용한다.
npf.irr(values)
- values : cash flows per time period.
import numpy_financial as npf
import numpy as np
cashflows = [-70000, 12000, 15000, 18000, 21000, 26000]
# irr 함수를 사용해 내부 수익률 계산
irr = npf.irr(cashflows)
# 구한 iRR을 npv의 할인율로 사용해 NPV를 구한다.
# IRR을 정확하게 구했다면 NPV는 0이 나올 것이다.
npv = npf.npv(irr, cashflows)
print('IRR {0:.1%} makes NPV {1:.2f}'.format(irr,npv))
# >> IRR 192.1% makes NPV -0.00
수익률 대 수익률
수익률과 할인율의 개념
수익률이란 미래의 시점에서 발생하는 모든 현금흐름 합계액과 현재의 가치를 일치시키는 할인율
즉,
- 수익률 = 현재 시점에서 미래 가치 계산
- 할인율 = 미래 가치를 현재의 시점으로 되돌려 계산
기간 수익률의 평균, 산술평균과 기하평균
산술평균 $\frac{1}{n}(r_1 + r_2 + ... + r_n)$
기하평균 $\sqrt[n]{(1+r_1)(1+r_2)...(1+r_n)}$
각 기간별 수익률로 계산한 경우 | 기하평균으로 계산한 경우 | |||||
---|---|---|---|---|---|---|
연도 | 수익률 | 투자액 | 수입금 | 수익률 | 투자액 | 수익금 |
1 | 10% | 1,100.00 | 100.00 | 1,069.78 | 69.78 | |
2 | 6% | 1,166.00 | 66.00 | 1,144.44 | 74.65 | |
3 | 5% | 1,224.30 | 58.30 | 1,244.30 | 79.86 | |
최종 | 7% | 6.98% |
기간별 수익률 평균
# 기간별 수익률 평균
# 기간별 수익률을 returns 리스트에 저장
returns = [0.1, 0.06, 0.05]
sum_rtn = 0.0 # 합계
arimean = 0.0 # 평균
geomean = 1.0
# 기간별 수익률의 데이터 개수
n = len(returns)
# returns 리스트를 for 루프로 반복. 반복하는 동안 각 수익률을 변수 r로 받음
for r in returns:
sum_rtn = sum_rtn + r
arimean = sum_rtn /3
print('AriMean is {:.2%}'.format(arimean))
AriMean is 7.00%
기하평균 코드
# 기하평균
for r in returns:
geomean = geomean * (1+r)
# 기간 수익률로 변환
geomean = geomean ** (1/n) - 1
# 기하평균 출력
print('GeoMean is {:.2%}'.format(geomean))
# >> GeoMean is 6.98%
지배원리
포트폴리오는 '기대수익률'과 '위험'이라는 기준으로 평가할 수 있다.
포트폴리오로부터 얻는 기대수익률은 클수록 좋고, 표준편차 또는 분산으로 표현되는 위험은 작을수록 좋다.
즉, 두 포트폴리오 수익률의 표준편차가 동일하다면 (= 위험이 동일하다면), 기대수익률이 상대적으로 큰 포트폴리오를 고르게 될 것이다.
이를 평균 - 분산 기준 (mean-variance criterion) 또는 지배원리 (dominance principle)라고 한다.
만약 4가지의 포트폴리오가 있다고 가정하자.
투자 대상 | 기대수익률(%) | 표준편차(%) |
---|---|---|
A | 7.0 | 2.0 |
B | 7.0 | 3.0 |
C | 9.0 | 2.0 |
D | 9.0 | 3.0 |
- 포트폴리오 A와 B는 기대수익률이 같지만 포트폴리오 A의 표준편차가 낮기 때문에 포트폴리오 A는 포트폴리오 B를 지배한다.
- 포트폴리오 C와 D는 기대수익률이 같지만 포트폴리오 C의 표준편차가 낮기 때문에 포트폴리오 C는 포트폴리오 D를 지배한다.
- 포트폴리오 C는 A와 표준편차가 같지만 C의 기대수익률이 높으므로 C를 선택하게 될 것이다.
- 결국 지배원리에 따라 포트폴리오 C를 선택하게 된다.
그러나, 평균-분산 지배원리의 오류라는 것이 있다.
포트폴리오 A와 D는 지배원리만으로 선택할 수 없다. D는 기대수익률이 더 높고, A는 위험이 더 낮다.
즉, 지배원리만 가지고 포트폴리오를 모두 판단하는 것은 위험하다.