안녕하세요, 다빈치스탁의 시청자 여러분. 오늘은 투자의 거장 워렌 버핏도 높이 평가한다는 켈리의 공식에 대해 살펴보겠습니다.
켈리 공식은 반복적으로 베팅을 할 때 파산하지 않고 최대의 수익을 얻기 위해 어느 정도 비율로 베팅해야 하는지 계산하는 공식으로, 벨 연구소에서 근무했던 Kelly라는 연구원이 개발했는데요. 그러나 이 공식의 발표 초기만 하더라도 현실성에 대해 많은 의문점이 제기 되었습니다.
이에 켈리는 몇 가지 실험을 통해 단순화된 가정 하의 대부분의 도박과 몇몇 투자 시나리오에서, 장기적으로 다른 어떤 전략보다 우월한 성과를 낸다는 현실적 유용성을 검증하였습니다.
하지만 이건 모든 게임이나 투자에 적용되지는 않습니다. 왜 그런지 살펴볼까요? 우선 켈리의 공식은 다음과 같이 계산됩니다. 여기서 f는 배당 비율, b는 단위 금액 당 배당 금액, p는 승리 확률, 마지막으로 q는 패배 확률인데요.
만약 이기면 건 돈 만큼 받는 동전 던지기 게임을 한다면, 승률은 50%과 되고 배당률은 1이되기 때문에 공식에 대입하면 0으로 계산되기 때문이죠. 따라서 아주 작은 금액이라도 투자하는 것이 유리하기 위해서는 승률과 배당률 둘 중 하나는 높아야 합니다.
또한 배당률과 승률이 낮을 경우 음수로 계산되기 때문에 일반적인 도박에서는 허용되지 않는 역베팅 방법이 됩니다. 그러나 이 공식을 주식투자에 대입한다면 이야기가 달라지는데요. 우선 주식투자는 동전 던지기와 같은 순수한 무작위 게임과는 거리가 있죠.
아울러 건 돈을 다 날리는 것이 아닌 등락률에 따라 1보다 크거나 작은 배당률을 받습니다. 그리고 음수의 베팅률이 계산되더라도 매도로서 대응이 가능하죠. 어때요, 그림이 그려지시나요? 아직 잘 모르시겠다구요?
그럼 지금부터 몇 가지 실험을 통해 이 공식의 유용성에 대해 검증해보겠습니다. 실험에 사용할 종목은 KODEX200 ETF로 지정하고, 매일 1주씩 분할 매수하는 방법과 켈리의 공식에 입각한 방식을 비교해서 분석해보겠습니다.
첫 째, 거래시작일부터 오늘까지 매일 1주씩 분할 매수를 수행했다면 어떤 결과가 나올까요? 시뮬레이션 결과 약 11%의 평가손익으로 계산됩니다. 그리고 필요한 투자 금액은 평균단가인 32425원 곱하기 500거래일을 적용하여 약 1550만원 정도되죠.
이어서 이와 동일한 금액인 1550만원에 대해 켈리의 공식을 사용하여 시뮬레이션 해볼건데요. 그전에 켈리의 공식을 적용하기 위해서는 몇 가지 가정이 필요합니다. 바로 배당률과 승률에 대한 가정입니다.
우선 승률은 테스트 기간인 과거 2년 동안 전일 대비 상승했으면 승리, 하락했으면 패배라고 가정하여 측정한 결과인 51%를 사용하였고, 매 거래일의 등락률을 배당률로 산정하여 시뮬레이션 해보았습니다.
측정 결과 최종 평균 단가는 31322원으로 낮아져 약 15%의 평가 수익으로 계산됩니다. 물론 매일 1주씩 분할 매수한 결과보다는 우수한 것으로 산출되었지만, 유의미한 결과라 보기에는 차이가 너무 미미하다고 볼 수 있죠.
그래서 이번에는 동 종목에 대해 실험 구간을 과거 2년이 아닌 4년으로 변경하여 시뮬레이션 해본 결과 분할 매수는 4.52%, 켈리의 공식은 30.49%로 압도적 우위를 보였습니다. 우연의 결과일 수도 있기에 이번에는 나스닥 지수를 추종하는 QQQ ETF를 대상으로 실험을 진행해보겠습니다.
실험결과 분할 매수는 35.56%, 켈리의 공식은 93.56%로 이번에도 압도적인 승리였습니다. 이외에도 엔비디아의 경우 288% 대 1134%, 테슬라의 경우에는 -19.85% 대 168.93%로 극명한 차이를 보이는 등 통계적 유의미성을 높이는 결과를 보였습니다.
물론 이 실험의 결과는 앞으로 나올 승률이 아니라 과거 등락률의 분포를 통해 승률을 추정했다는 점에서 반박의 여지는 있습니다. 하지만 켈리의 공식은 음의 베팅을 허용합니다. 즉 과거의 높은 승률에서 점차 낮은 승률로 변한다 하더라도 보유비중을 줄여나가는 결과를 제시하겠죠.
오히려 문제가 되는 것은 많은 시행을 해야 한다는 점인데요. 제 아무리 날고 기는 엔비디아라 하더라도 과거 4년 동안 상승한 일수는 전체 구간에서 55% 밖에 되지 않습니다. 따라서 투자 심리가 뒷받침 되지 않는다면 결국에는 아무런 의미가 없어지게 되죠.
하지만 켈리의 이론이 워렌 버핏과 같은 투자의 대가 뿐만 아니라 많은 경제학자들에게 인정되어, 투자론의 한 분야로 자리잡게 되었다는 점을 감안한다면 꾸준함과 인내심을 가지고 시도해볼 만한 전략이라고 판단됩니다.
이상 켈리의 공식을 이용한 투자전략에 대한 강의를 마치겠습니다. 오늘의 영상이 여러분들에게 도움이 되었기를 바라며, 다음 시간에는 더 유익한 정보로 찾아 뵙겠습니다. 시청해주셔서 감사합니다.
import numpy as np
import pandas as pd
import yfinance as yf
# 켈리의 공식 함수
def kelly_criterion(b, p):
# 승률 p, 배당률 b
q = 1 - p
f = (b * p - q) / b
return f
# 종목 데이터 다운로드
code = 'NVDA'
data = yf.download(code, start="2020-05-24", end="2024-05-31")
data = data.dropna()
data['Adj Close'] = data['Adj Close']
data['Returns'] = data['Adj Close'].pct_change()
data.dropna(inplace=True)
# pct_change가 양수인 경우의 수를 세기
positive_changes = (data['Returns'] > 0).sum()
# 전체 데이터 포인트의 수
total_changes = len(data['Returns'])
# 양수인 pct_change의 확률 계산
probability_positive = positive_changes / total_changes
print(f"pct_change가 양수인 확률: {probability_positive:.2f}")
# 총 누적 투자금액
investment = 0
stock_quantity = 0
average_price = 0
# 매 거래일마다 1주씩 주식 구매
for i in range(len(data) - 1):
# 보유 주식 수 업데이트
stock_quantity += 1
# 평단가 업데이트
average_price = ((average_price * (stock_quantity - 1)) + data.iloc[i]['Adj Close']) / stock_quantity
# 구매한 금액을 누적
investment += data.iloc[i]['Adj Close']
# 최종 투자금액 및 평단가 대비 수익률 출력
print("-----------------------------------------------------normal----------------------------------------------------")
final_return = (data.iloc[-1]['Adj Close'] - average_price) / average_price *100
print(f"최종 평가손익: {final_return:.2f} %")
print(f"최종 필요자본: {investment:.2f}원")
print(f"최종 평균단가: {average_price}원")
# 투자금액, 주식 수, 평단가 초기화
stock_quantity = 0
average_price = 0
cash = investment
# 매 거래일마다 켈리의 공식에 따른 투자 실행 및 평단가 계산
for i in range(len(data) - 1):
# 오늘의 등락률을 기반으로 배당률 계산
dividend = 1 + data.iloc[i]['Returns']
# 켈리의 공식에 따른 배팅 비율 계산
betting_ratio = kelly_criterion(dividend, probability_positive)
# 배팅 비율에 따른 투자금액 계산
bet_amount = cash * betting_ratio
# 배팅 비율이 양수면 매수, 음수면 매도
if bet_amount > 0:
# 매수할 주식 수 계산
buy_quantity = bet_amount / data.iloc[i]['Adj Close']
# 보유 주식 수 업데이트
stock_quantity += buy_quantity
# 평단가 업데이트
average_price = ((average_price * (stock_quantity - buy_quantity)) + data.iloc[i]['Adj Close'] * buy_quantity) / stock_quantity
# 매수한 금액만큼 보유현금에서 차감
cash -= buy_quantity * data.iloc[i]['Adj Close']
# 구매한 금액을 누적
investment += buy_quantity * data.iloc[i]['Adj Close']
# 최종 투자금액 및 평단가 대비 수익률 출력
print("-----------------------------------------------------kelly-----------------------------------------------------")
final_return = 0
if average_price > 0:
final_return = (data.iloc[-1]['Adj Close'] - average_price) / average_price
print(f"최종 수익률: {final_return*100:.2f} %")
print(f"최종 평균단가: {average_price}원")
# 초기 투자금액 설정
initial_investment = 10000000
# 투자금액, 주식 수, 평단가 초기화
stock_quantity = 0
average_price = 0
cash = initial_investment
# 매 거래일마다 켈리의 공식에 따른 투자 실행 및 평단가 계산
for i in range(len(data) - 1):
# 오늘의 등락률을 기반으로 배당률 계산
dividend = 1 + data.iloc[i]['Returns']
# 켈리의 공식에 따른 배팅 비율 계산
betting_ratio = kelly_criterion(dividend, probability_positive)
# 배팅 비율에 따른 투자금액 계산
bet_amount = cash * betting_ratio
# 배팅 비율이 양수면 매수, 음수면 매도
if bet_amount > 0:
# 현금 잔고가 있을 경우에만 매수
if cash > 0:
# 매수할 주식 수 계산
buy_quantity_ = bet_amount / data.iloc[i]['Adj Close']
buy_quantity = int(buy_quantity_)
# 새로 매수한 주식의 구매 비용
new_purchase_cost = buy_quantity * data.iloc[i]['Adj Close']
# 총 구매 비용 업데이트
total_purchase_cost = average_price * stock_quantity + new_purchase_cost
# 보유 주식 수 업데이트
stock_quantity += buy_quantity
# 평단가 계산
average_price = total_purchase_cost / stock_quantity
# 매수한 금액만큼 보유현금에서 차감
cash -= buy_quantity * data.iloc[i]['Adj Close']
else:
if stock_quantity > 0:
# 매도할 주식 수 계산 (절대값 사용)
sell_quantity = min(stock_quantity, abs(bet_amount / data.iloc[i]['Adj Close']))
# 주식 수 업데이트
stock_quantity -= sell_quantity
# 매도한 금액을 보유현금에 반영
cash += sell_quantity * data.iloc[i]['Adj Close']
# 최종 투자금액 및 평단가 대비 수익률 출력
print("-----------------------------------------------------kelly&limit-----------------------------------------------")
print(f"최종 보유주식: {stock_quantity*data.iloc[-1]['Adj Close']}")
print(f"최종 보유현금: {cash:.2f}원")
print(f"최종 잔고: {cash + stock_quantity*data.iloc[-1]['Adj Close']:.2f}원")
final_return = (cash + stock_quantity*data.iloc[-1]['Adj Close']) / initial_investment - 1
print(f"최종 수익률: {final_return*100:.2f} %")
'실전머신러닝' 카테고리의 다른 글
인공지능이 파헤친 세력의 숨겨진 패턴, 파이썬 강화학습으로 마스터하는 세력주 공략법! (0) | 2024.04.21 |
---|---|
인공지능을 활용한 최적화된 MACD지표로 수익성을 강화하고 스마트하게 투자하기! (0) | 2024.04.18 |
의사결정나무를 이용해서 HTS 조건검색식 만들어보기 (0) | 2020.11.12 |
KNN, 나이브베이즈 분류를 이용해서 종목분석하기 (0) | 2020.11.10 |
머신러닝 개요 with R (0) | 2020.11.06 |
댓글