배우고 나누는 사람

모두에게 더 넓고 더 깊은 세상을 향해

각종 돈 관련/주식 관련

[투자] 적정 레버리지 비율

Jeongwon Seo 2021. 9. 7. 02:41

이번 포스팅에서는 제가 직접 짜본 코드와 백테이팅 결과를 활용해서 최적의 레버리지 배율을 찾아보는 시간을 가지도록 하겠습니다. 블로그를 시작한 이래로 처음으로 제가 짠 코드를 공유드리는 것 같아서 살짝 긴장이 되기도 하네요. 이번 포스팅에서 레버리지 배율을 찾아보겠다 말했죠. 그러니 다음 포스팅은 그 배율을 이용한 예상 수익도 한 번 계산해 보도록 하겠습니다. 먼저 이번 글은 파이썬을 이용한 데이터를 활용했습니다. 자료는 야후 파이낸스에서 가져왔습니다. 

 

먼저 아래 링크로 가시고요.

https://finance.yahoo.com/quote/%5EIXIC/history?period1=34560000&period2=1630886400&interval=1d&filter=history&frequency=1d&includeAdjustedClose=true

 

NASDAQ Composite (^IXIC) Historical Data - Yahoo Finance

Get historical data for the NASDAQ Composite (^IXIC) on Yahoo Finance. View and download daily, weekly or monthly data to help your investment decisions.

finance.yahoo.com

"Time Period" 옆에 파란색으로 표시된 기간이 있을텐데 그걸 클릭한다음 "Max"를 눌러주세요. 

그럼 기간이 제일 오래된 자료(1971년 2월 4일)부터 현재까지 나올거에요. 그럼 "Apply" 아래 있는 "Download" 버튼을 눌러서 자료를 다운 받아주세요. 그럼 일단 1단계 준비는 끝났다고 볼 수 있겠죠? 파일을 열어보셔도 되고요 제가 여러분을 위해 열어봤으니 저를 믿고 그냥 코드만 쭉 따라와 주셔도 됩니다. 여튼 제가 열어봤는데 열어보니 날짜가 있고요, 시가, 종가, 그리고 조정가(Adjusted Close)가 있는데 우리는 조정가를 이용할게요. 뭐든 하나만 잡고 가면 되요. 

 

먼저 필요한 패키지들은 Import 할게요.

import numpy as np
import pandas as pd
import random as rd
import matplotlib.pyplot as plt

하루 하루 어떻게 변했는지 배율을 구해봐야겠죠? 그래야 레버리지를 적용할테니까요. 일단 'Adj Close'열에 해당하는 것들을 따로 읽고 그것들을 이용해 "(다음날 - 전날)/전날"을 구합니다. 참 저는 파일 이름은 NSD.csv로 바꿔서 아래처럼 되어 있습니다.

data = pd.read_csv("./NSD.csv")
print(data)

nsd = data['Adj Close']
rate = np.zeros((len(nsd)-1))
for i in range(len(rate)):
  rate[i] = (nsd[i+1]-nsd[i])/nsd[i]

이제 이 부분은 하셔도 되고 안하셔도 되는데 그래도 해보면 좋겠죠? 먼저 배율을 잘 구했는지 나스닥의 최초 가격 100에 배율을 차례로 곱해서 오늘의 나스닥 가격이 나오는지 구해보고요. 다음으로 우리는 장기투자를 목표로 하니 약 4년 이상의 구간을 잡기 위한 과정을 추가해줍니다. 1년이 약 254영업이라 4년은 대충 1000일정도로 잡았어요.

nsd_init = 100
for i in range(len(rate)):
  nsd_init *= (1 + rate[i])
print(nsd_init)

while True:
  rg = [rd.randrange(len(nsd))+1, rd.randrange(len(nsd))+1]
  rg.sort()
  if rg[1] - rg[0] >= 1000:
    break
print(rg)

nsd_init의 최종가는 15363.5195로 현재가와 잘 맞고 범위를 구한 rg는 2029와 10302로 8천일이라 약 32년이 잡혔네요. 이건 랜덤이기 때문에 매번 실행시킬때마다 달라집니다. 자 그럼 지금까지를 이용해서 배율을 0.1부터 4까지 올려가면 최적이 레버리지 비율이 몇인지 구해봅시다. 

init = np.ones((40))
for j in range(40):
  for i in range(rg[1]-rg[0]):
    init[j] *= (1 + rate[rg[0]+i]*(j+1)/10)

plt.plot((np.arange(40)+1)/10, init)
plt.grid(True)
plt.xlabel("Leverage")
plt.ylabel("Expected profit")
plt.show()

자 위 코드를 실행시키면 아래와 같은 그래프가 나옵니다.

제가 임의로 잡은 기간만 놓고 보면 최적을 레버리지 비율은 약 2.4배 인걸로 나오고 32년간 100배가 넘는 수익을 기대할 수 있다고 나오는군요! 매우 좋습니다. 자 이제 비슷한 과정을 주욱 반복할겁니다. 일단 한 10번만 반복하는 함수를 돌려볼까요?  

for k in range(10):
  while True:
    rg = [rd.randrange(len(nsd))+1, rd.randrange(len(nsd))+1]
    rg.sort()
    if rg[1] - rg[0] >= 10000:
      break

  init = np.ones((40))
  for j in range(40):
    for i in range(rg[1]-rg[0]):
      init[j] *= (1 + rate[rg[0]+i]*(j+1)/10)

  plt.plot((np.arange(40)+1)/10, init)

plt.grid(True)
plt.xlabel("Leverage")
plt.ylabel("Expected profit")
plt.show()

가끔 그래프가 터지는 경우(너무 올라가는)가 나오는데 이를 제거하기 위해 백그라운드 데이터를 10000일로 바꿨어요. 아무래도 4년간 수집하는 건 데이터가 너무 적은 것 같네요. 약 40년 이상의 데이터 이요한다고 가정했을 때의 코드(위)와 그래프(아래)를 보시죠.

오 이 그래프를 보니 2.5배부터는 완만해지긴하지만 3배정도가 최적의 배율로 보이는군요. 확실히 3배 이상은 하는게 안좋아보이네요. 또한 나스닥 지수만 고려되어있고 운영보수 (약 1%)가 고려되어 있지 않기 때문에 코드를 조금 향상시키는게 좋을 듯 합니다. 운영보수를 1년 영업일 254로 나누어 계산해 보겠습니다. 계산식은 다음과 같습니다.

 

$$ (1+x)^{254} = 1.01 \Rightarrow x=3.917529825\times10^{-5} $$

 

여튼 레버리지를 이용하기 위해선 저 만큼의 수수료를 내야 하니 이를 반영해서 다시 코드를 돌려보겠습니다.

expense = np.exp(np.log(1.01)/254)-1
print(expense)

for k in range(10):
  while True:
    rg = [rd.randrange(len(nsd))+1, rd.randrange(len(nsd))+1]
    rg.sort()
    if rg[1] - rg[0] >= 10000:
      break

  init = np.ones((40))
  for j in range(40):
    for i in range(rg[1]-rg[0]):
      init[j] *= (1 + (rate[rg[0]+i]-expense)*(j+1)/10)

  plt.plot((np.arange(40)+1)/10, init)

plt.grid(True)
plt.xlabel("Leverage")
plt.ylabel("Expected profit")
plt.show()

대체로 약 2.5에서 2.7이나 2.8사이에 최대값을 보이는군요. 하지만 증가폭(2계 미분)은 2배정도에서 감소하는 것으로 보이네요. 그럼 이제 엄청나게 많은 수의 샘플을 돌려보고 최적의 비율의 평균값을 구해보겠습니다. 

lev = []
for k in range(1000):
  while True:
    rg = [rd.randrange(len(nsd))+1, rd.randrange(len(nsd))+1]
    rg.sort()
    if rg[1] - rg[0] >= 10000:
      break

  init = np.ones((40))
  for j in range(40):
    for i in range(rg[1]-rg[0]):
      init[j] *= (1 + (rate[rg[0]+i-1]-expense)*(j+1)/10)

  lev.append((np.argsort(init)[-1]+1)/10)
print(np.mean(lev))

구해보니 평균값은 2.6002가 나오네요. 그 말인즉 지금까지의 데이터를 보고 시뮬레이션 해본 결과 최적의 레버리지 배율은 2.6이 되겠네요. 하지만 명심하셔야 할 것은 우리가 감수해야 할 리스크와 얻어갈 수 있는 이득을 계산해본다면 많이 해도 2.25배 정도가 최적이지 않을까 싶네요. 저는 2배인 QLD로 안전하게 갈 생각입니다. 아무래도 2배가 넘어가면 TQQQ를 섞어야 하는데 하락장에서 많이 불안정한 모습을 보이기에 2배로 하더라도 QQQ와 TQQQ를 1:1로 섞어서 가기보단 QLD로 안전하게 가려합니다. 

 

짧은 결론

 

우리는 지금까지 어떻게 하면 안전하게 시장을 이길 수 있을지 고민해봤잖아요. 물론 3배 레버리지를 가져가는 것이 나쁘다는 것은 아닙니다. 변동성이 더욱 심해지고 그만큼 감내해야 할 리스크도 늘어나는 거죠. 게다가 2배에서 2.25배 레버리지까지는 감내하는 리스크 대비 수익률이 평균적으로 좋다고 나옵니다. 우리의 최초 목적은 시장을 이기는 것이잖아요. 너무 욕심내는 것보단 안전하게 QLD로 가시는 걸 다시 한 번 추천 드립니다. 감사합니다.

 

아래 제가 작성한 Colab 공유해 드릴테니 필요하신 분들은 쓰세요.

https://colab.research.google.com/drive/1Ja0l1PN2ZFppmKE5zTGwuEE7tgHwIGd-?usp=sharing 

 

Optimal Leverage for Nasdaq.ipynb

Colaboratory notebook

colab.research.google.com

 

728x90
반응형