VR 지표를 활용한 트레이딩 전략(VR Indicator Trading Strategy)

VR 지표의 개념과 유래

VR(Volatility Ratio) 지표는 시장의 변동성을 측정하는 데 사용되는 기술적 분석 도구이다. 이 지표는 현재 주가의 변동성을 과거의 변동성과 비교하여 상대적인 변동성의 크기를 나타낸다. VR 지표는 주가의 변동성이 확대되거나 축소되는 시점을 파악하는 데 유용하다.

VR 지표의 유래는 명확하게 알려져 있지 않지만, 변동성을 측정하는 다양한 지표 중 하나로 개발되었다. VR 지표는 주가의 변동성을 상대적으로 비교하여 현재 시장의 상태를 판단하는 데 도움을 준다.

VR 지표 계산 방법

VR 지표는 다음과 같은 단계를 통해 계산된다:

  1. 일정 기간(예: 14일) 동안의 주가 변동성을 계산한다.
  • 변동성 = (고가 – 저가) / 전일 종가
  1. 일정 기간(예: 252일) 동안의 주가 변동성의 평균을 계산한다.
  2. VR 지표 계산:
  • VR = 단기 변동성(예: 14일) / 장기 변동성(예: 252일)

예를 들어, 14일 동안의 평균 변동성이 0.02이고, 252일 동안의 평균 변동성이 0.01이라면, VR 지표는 0.02 / 0.01 = 2가 된다. 이는 현재 주가의 변동성이 과거 대비 2배 높음을 의미한다.

VR 지표를 활용한 매매 전략

VR 지표를 활용한 매매 전략은 다음과 같이 구성할 수 있다:

  1. 변동성 확대 시 매매 기회 포착:
  • VR 지표가 일정 수준(예: 2) 이상으로 상승할 때, 변동성 확대로 인한 추세 전환 또는 모멘텀 매매 기회로 활용한다.
  • VR 지표가 높은 수준에서 하락할 때, 변동성 축소로 인한 추세 전환 또는 반전 매매 기회로 활용한다.
  1. VR 지표의 상대적 수준 활용:
  • VR 지표가 일정 기간(예: 1년) 동안의 상위 10% 수준에 진입할 때, 과매수 신호로 해석하여 매도 기회로 활용한다.
  • VR 지표가 일정 기간(예: 1년) 동안의 하위 10% 수준에 진입할 때, 과매도 신호로 해석하여 매수 기회로 활용한다.
  1. VR 지표와 주가 추세 결합:
  • VR 지표가 상승하고 주가가 상승 추세일 때, 강한 상승 모멘텀으로 판단하여 매수 기회로 활용한다.
  • VR 지표가 하락하고 주가가 하락 추세일 때, 강한 하락 모멘텀으로 판단하여 매도 기회로 활용한다.

VR 지표는 주가 변동성의 상대적인 크기를 파악하는 데 유용하지만, 단독으로 사용하기보다는 다른 기술적 지표나 시장 상황과 함께 종합적으로 판단하는 것이 효과적이다. 또한 변동성이 크게 확대되는 시기에는 리스크 관리에 유의해야 한다.

파이썬을 활용한 VR 지표 백테스팅

파이썬을 사용하여 VR 지표 기반의 트레이딩 전략을 백테스팅해보자. 다음 라이브러리를 활용할 것이다:

  • pandas: 데이터 조작 및 분석
  • numpy: 수치 계산
  • matplotlib: 데이터 시각화
  • FinanceDataReader: 주가 데이터 수집

먼저 가상환경을 활성화하고 필요한 라이브러리를 설치한다.

source venv/bin/activate
pip install pandas numpy matplotlib FinanceDataReader

FinanceDataReader를 설치하면 종속 모듈도 함께 설치된다.

다음으로 VR 지표를 계산하고 매매 신호를 생성하는 코드를 작성해보자.

import FinanceDataReader as fdr
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 데이터 가져오기
symbol = "VOO"
start_date = "1900-01-01"
end_date = "2023-05-01"

try:
    data = fdr.DataReader(symbol, start_date, end_date)
except Exception as e:
    print(f"Error occurred while fetching data: {e}")
    exit(1)

# VR 지표 계산 함수
def calculate_vr(data, short_term=14, long_term=252):
    data = data.copy()
    data['volatility'] = (data['High'] - data['Low']) / data['Close'].shift(1)
    data['short_term_vr'] = data['volatility'].rolling(window=short_term).mean()
    data['long_term_vr'] = data['volatility'].rolling(window=long_term).mean()
    data['vr'] = data['short_term_vr'] / data['long_term_vr']
    return data

# 매매 신호 생성 함수
def get_signals(data, upper_threshold=2, lower_threshold=0.5):
    signals = pd.DataFrame(index=data.index)
    signals['signal'] = 0

    signals['signal'][data['vr'] > upper_threshold] = -1
    signals['signal'][data['vr'] < lower_threshold] = 1

    signals['positions'] = signals['signal'].diff()

    return signals

# VR 지표 계산
vr_data = calculate_vr(data)

# 매매 신호 생성
signals = get_signals(vr_data)

# 백테스팅
initial_capital = 10000
positions = pd.DataFrame(index=signals.index).fillna(0.0)
positions[symbol] = 100 * signals['signal']

portfolio = positions.multiply(vr_data['Adj Close'], axis=0)
pos_diff = positions.diff()

portfolio['holdings'] = (positions.multiply(vr_data['Adj Close'], axis=0)).sum(axis=1)
portfolio['cash'] = initial_capital - (pos_diff.multiply(vr_data['Adj Close'], axis=0)).sum(axis=1).cumsum()

portfolio['total'] = portfolio['cash'] + portfolio['holdings']
portfolio['returns'] = portfolio['total'].pct_change()

# 결과 출력
print(f"Final portfolio value: ${portfolio['total'][-1]:,.2f}")
print(f"Total returns: {100 * (portfolio['total'][-1] / initial_capital - 1):.2f}%")

# 시각화
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(15, 15), gridspec_kw={'height_ratios': [3, 1, 1]})

ax1.plot(vr_data['Adj Close'], label='Price')
ax1.set_ylabel('Price')
ax1.set_title('Price Chart')
ax1.legend(loc='upper left')

ax2.plot(vr_data['vr'], label='VR')
ax2.axhline(y=2, color='r', linestyle='--', label='Upper Threshold')
ax2.axhline(y=0.5, color='g', linestyle='--', label='Lower Threshold')
ax2.set_ylabel('VR')
ax2.set_title('Volatility Ratio (VR)')
ax2.legend(loc='upper left')

ax3.plot(portfolio['total'], label='Portfolio Value')
ax3.set_ylabel('Portfolio Value')
ax3.set_title('Portfolio Performance')
ax3.legend(loc='upper left')

plt.tight_layout()
plt.show()

위 코드에서는 FinanceDataReader를 사용하여 VOO ETF의 전체 기간 주가 데이터를 가져온다. start_date를 가능한 한 오래전 날짜로 설정하여 모든 데이터를 가져올 수 있도록 한다.

calculate_vr 함수는 주어진 데이터를 바탕으로 VR 지표를 계산한다. 먼저 일별 변동성을 계산하고, 이를 기반으로 단기 변동성(기본값: 14일)과 장기 변동성(기본값: 252일)을 구한다. 그 후 단기 변동성을 장기 변동성으로 나누어 VR 지표를 계산한다.

get_signals 함수는 계산된 VR 지표를 기준으로 매매 신호를 생성한다. VR 지표가 상단 임계값(예: 2)을 초과할 때 매도 신호(-1), 하단 임계값(예: 0.5)을 하회할 때 매수 신호(1)를 생성한다.

백테스팅을 위해 초기 자본금을 10,000달러로 설정하고, 생성된 매매 신호를 바탕으로 포트폴리오 가치를 계산한다. 최종적으로 총 수익률과 포트폴리오 가치를 출력한다.

matplotlib을 사용하여 주가, VR 지표, 포트폴리오 가치를 시각화한다. VR 지표 차트에는 상단 및 하단 임계값을 나타내는 기준선도 표시한다.

코드 실행 중 발생할 수 있는 오류를 처리하기 위해 try-except 문을 사용하였다. 데이터를 가져오는 과정에서 오류가 발생하면 에러 메시지를 출력하고 프로그램을 종료한다.

Leave a Reply

error: Content is protected !!