본문 바로가기
가상화폐 퀀트 전략

트레이딩 전략 6 : 듀얼 모멘텀 + 현금 비중 최소 90%

by TenMillionQuant 2022. 4. 5.

가상화폐 투자마법 공식 발췌 (전체코드는 아래 파일에 있습니다)

 

 

 

 

투자전략 : 듀얼 모멘텀 + 현금 비중 최소 90%

 

이 전략은 좋아하는 가상화폐 3~4개를 고른 후, 지난 한 달(30일) 동안 잘나갔던 가상화폐에만 투자하고, 최근 가장 많이 오르는 대세 화페(?)가 바뀔 경우 갈아타는 전략이다.

 

그리고 만약 선택한 3~4개 화폐의 과거 한 달 수익이 모두 마이너스로 전환하면 모든 가상화폐를 현금화 하고 형세를 관망한다. 

 

투자대상 : 비트코인(BTC), 이더리움(ETH), 라이트코인(LTC), 이더리움클래식(ETC), 리플(XRP) 

투자기간 : 2017.05 ~ 2022.03

거래비용 : 0.2% 적용

투자전략

  • 선택한 가상화폐의 과거 30일 수익률 체크
  • 현재 가격이 이 4개 이동평균보다 높으면 매수 또는 보유
  • 현재 가격이 이동평균보다 낮으면 매도 또는 투자 보류
  • 자금 관리 : 가상화폐별 투입 금액은 (타깃 변동성 / 특정 화폐의 변동성 / 가상 화폐 수)
  • 변동성 : 최근 5일간의 1일 변동성의 평균

 

이제 코드를 구현해보자

 

#필요한 데이터를 불러온다

import pybithumb
import pandas as pd
import numpy as np

 

티커 리스트를 정한다. 

 

tickers_list = ['BTC','ETH', 'LTC', 'ETC', 'XRP']

# 비트코인, 이더리움, 라이트코인, 이더리움클래식, 리플을 가져오자
btc_df = pybithumb.get_ohlcv('BTC')
eth_df = pybithumb.get_ohlcv('ETH')
ltc_df = pybithumb.get_ohlcv('LTC')
etc_df = pybithumb.get_ohlcv('ETC')
xrp_df = pybithumb.get_ohlcv('XRP')

start_date_list = [] # 데이터시작일 저장 리스트
end_date_list = [] # 마지막일 저장 리스트

for ticker in tickers_list:
    df = pybithumb.get_ohlcv(ticker)
    
    start_date_list.append(str(df.index[0]))
    end_date_list.append(str(df.index[-1]))
    
    print(ticker, start_date_list[-1], end_date_list[-1])
    
    # 리플 데이터가 가장 적으므로, 시작일을 리플로 기준을 잡자
ticker_df = pd.DataFrame({"tickers_list" : tickers_list, "start_date" : start_date_list, "end_date" : end_date_list})
ticker_df

 

 

 

데이터 클리닝을 진행한다. 

 

# 시작일은 리플 시작일로 설정하고, 다른 코인도 다 그날에 시작하게 바꾸자
start_date = xrp_df.index[0]

btc_df = btc_df[btc_df.index >= start_date]
eth_df = eth_df[eth_df.index >= start_date]
ltc_df = ltc_df[ltc_df.index >= start_date]
etc_df = eth_df[eth_df.index >= start_date]
xrp_df = xrp_df[xrp_df.index >= start_date]

# 30일전 종가를 past_close 열에 저장하자
btc_df['past_close'] = btc_df['close'].shift(30)
eth_df['past_close'] = eth_df['close'].shift(30)
ltc_df['past_close'] = ltc_df['close'].shift(30)
etc_df['past_close'] = etc_df['close'].shift(30)
xrp_df['past_close'] = xrp_df['close'].shift(30)

# past_close가 none인 row들은 다 삭제한다
btc_df.dropna(inplace=True)
eth_df.dropna(inplace=True)
ltc_df.dropna(inplace=True)
etc_df.dropna(inplace=True)
xrp_df.dropna(inplace=True)

 

백테스팅을 진행한다. 

 

total_capital = 0 # 전체 투자금액
investing_weight = 0.1 # 90% 정도 현금을 남긴다
cash = 100000000 # 현금, 처음 시드머니 1억
fee = 0.002 # 수수료 0.2%
coin_invested = 0 # 가상화폐에 투자된 금액
mom_coin_saved = None #가상화폐 저장

total_capital_list = []

mom_coin = None # 가장 수익률이 좋은 코인
mom_ror = 0 # 가장 좋은 수익률

changed = None # 수익률 좋은 코인 바뀌었는지 확인

all_minus = None # 모든 수익률이 마이너스인지 확인

# 데이터프레임 list를 만든다
df_list = [btc_df, eth_df, ltc_df, etc_df, xrp_df]

for i in range(len(btc_df)):
    
    all_minus_ror_list = []
    
    # 가장 수익률이 좋은 코인 구하기
    for num,df in enumerate(df_list):
        ror = df.iloc[i]['open'] / df.iloc[i]['past_close']
        
        if ror > mom_ror:
            mom_ror = ror
            mom_coin = num
        
        all_minus_ror_list.append(ror)
    
    
    # 만약 코인이 바뀌었다면
    if mom_coin != mom_coin_saved:
        mom_coin_saved = mom_coin
        changed = True
    else:
        changed = False
    
    # 만약 모든 수익률이 마이너스이면 all_minus는 True
    if max(all_minus_ror_list) < 0:
        all_minus = True
    else:
        all_minus = False
            
    # 최근 30일간 가장 수익률이 좋은 가상화폐에 자산에 10% 투입
    if i == 0:
        
        print('buy')
        
        total_capital = cash + coin_invested
        
        # 현금은 90% 남긴다
        cash = total_capital * (1 - investing_weight)
        
        # 가장 수익률이 좋은 가상화페에 10% 투자한다(수수료비용은 차감한다)
        coin_invested = total_capital * (investing_weight) * (1 - fee)
        total_capital = cash + coin_invested # 전체 투자금액은 현금에 코인에 투자된 금액이다
        
        # 시가에 사서 종가 업데이트를 한다
        coin_open = df_list[mom_coin].iloc[i]['open']
        coin_close = df_list[mom_coin].iloc[i]['close']   

        # 코인 변동만큼 투자금액에 반영한다
        coin_invested *= (coin_close / coin_open)    

         # 총금액은 현금과 비트코인 투자한 금액
        total_capital = cash + coin_invested
        
        
    # 만약 수익률이 좋은 코인이 바뀌지 않았다면,
    if not changed:
            yesterday_coin_close = df_list[mom_coin].iloc[i-1]['close']
            coin_close = df_list[mom_coin].iloc[i]['close']   
            
            # 코인 변동만큼 투자금액에 반영한다
            coin_invested *= (coin_close / yesterday_coin_close)    
    
             # 총금액은 현금과 비트코인 투자한 금액
            total_capital = cash + coin_invested
            
            changed = False
            
    # 만약 최근 30일간 가장 수익률이 좋은 가상화폐가 바뀔경우, 기존 보유 화폐 매도, 새로운 화폐 매수
    elif changed:
        
        print('changed')
        
        # 코인을 매도한다 (매도할때 수수료 차감한다)
        coin_invested = coin_invested * (1 - fee)
        total_capital = cash + coin_invested # 전체 투자금액은 현금에 코인에 투자된 금액이다
        cash = total_capital #전체 투자금액은 현금으로 보유한다 
        
        # 코인 투자금액을 0으로 만든다
        coin_invested = 0
        
        # 가장 수익률이 좋은 가상화페에 10% 투자한다(수수료비용은 차감한다)
        coin_invested = total_capital * (investing_weight) * (1 - fee)
        total_capital = cash + coin_invested # 전체 투자금액은 현금에 코인에 투자된 금액이다
        
        # 시가에 사서 종가 업데이트를 한다
        coin_open = df_list[mom_coin].iloc[i]['open']
        coin_close = df_list[mom_coin].iloc[i]['close']   

        # 코인 변동만큼 투자금액에 반영한다
        coin_invested *= (coin_close / coin_open)    

         # 총금액은 현금과 비트코인 투자한 금액
        total_capital = cash + coin_invested
        
        changed = None
        
    # 만약 모든 수익률이 마이너스이면 기존 보유 화폐 매도
    elif all_minus:
        
        print("all_sell")
        
        # 코인을 매도한다 (매도할때 수수료 차감한다)
        coin_invested = coin_invested * (1 - fee)
        total_capital = cash + coin_invested # 전체 투자금액은 현금에 코인에 투자된 금액이다
        cash = total_capital #전체 투자금액은 현금으로 보유한다 
        
        # 코인 투자금액을 0으로 만든다
        coin_invested = 0
        
        all_minus = None

      
    total_capital_list.append(total_capital)
    
    print(btc_df.index[i],changed, mom_coin, total_capital)

 

그리고 수익률을 확인해보자. 약, 1.82배정도 올랐다. 

 

ror_df = pd.DataFrame({ "total_capital" : total_capital_list}, index = btc_df.index)

ror_df['ror'] = ror_df['total_capital'].pct_change() + 1
ror_df['cum_ror'] = ror_df['ror'].cumprod()

ror_df

 

 

이제, MDD를 확인해보자. 약, -21%정도이다. 

 

# 전 고점(HWM : High Water Mark)
ror_df['highwatermark'] =  ror_df['cum_ror'].cummax()
ror_df['drawdown'] = (ror_df['cum_ror'] / ror_df['highwatermark']) - 1

# mdd를 구한다
ror_df['max_drawdown'] = ror_df['drawdown'].cummin()

ror_df

 

 

그래프를 그려보면, 아래와 같다. 2018년에 올랐다가 그 이후론 횡보하는 추세이다. 

 

import matplotlib.pyplot as plt

plt.plot(ror_df['cum_ror'])

 

 

 

 

트레이딩 전략 6 듀얼 모멘텀 + 현금 비중 최소 90%.ipynb
0.14MB

 

댓글