Williams Percent Range (%R)의 개념
Williams Percent Range (%R)는 래리 윌리엄스(Larry Williams)가 개발한 모멘텀 지표로, 스토캐스틱 오실레이터(Stochastic Oscillator)와 유사하다. %R은 현재 종가와 일정 기간 동안의 최고가 및 최저가의 상대적 위치를 나타내는 지표이다. 이 지표는 현재 종가가 해당 기간 내에서 어느 정도의 위치에 있는지를 백분율로 표시한다.
%R은 다음과 같은 공식으로 계산된다:
%R = (Highest High - Close) / (Highest High - Lowest Low) * -100
여기서, Highest High는 일정 기간 내 최고가이며, Lowest Low는 일정 기간 내 최저가이다. 일반적으로 %R의 기간은 14일로 설정한다.
%R의 값은 -100에서 0 사이에 위치한다. -100에 가까울수록 현재 종가가 해당 기간 내 최저가에 근접해 있다는 것을 의미하며, 이는 과매도 상태로 해석된다. 반대로, 0에 가까울수록 현재 종가가 해당 기간 내 최고가에 근접해 있다는 것을 의미하며, 이는 과매수 상태로 해석된다.
일반적으로 %R이 -80 이하인 경우 과매도 상태로, -20 이상인 경우 과매수 상태로 간주한다. 또한, %R이 -80에서 상승하거나 -20에서 하락하는 경우, 추세 전환 신호로 해석할 수 있다.
Williams Percent Range (%R)를 활용한 트레이딩전략
%R을 활용한 트레이딩전략은 다음과 같이 구성할 수 있다:
- %R이 -80 이하로 하락한 후 상승하면 매수 신호로 간주한다.
- %R이 -20 이상으로 상승한 후 하락하면 매도 신호로 간주한다.
- %R이 -80에서 -20 사이에 있을 때는 추세가 명확하지 않은 것으로 판단하고 매매를 자제한다.
- 추가적으로, 가격 차트와 %R을 함께 분석하여 매매 타이밍을 결정할 수 있다. 예를 들어, %R이 -80 이하에서 상승하고 가격이 상승 추세를 보인다면 매수 신호로 간주할 수 있다.
이 전략은 %R을 통해 과매수와 과매도 상태를 파악하고, 이를 기반으로 매매 타이밍을 결정하는 것이 특징이다.
파이썬 코드 예시
다음은 FinanceDataReader 모듈을 사용하여 VOO와 QQQ ETF 데이터를 가져와 %R을 계산하고, 이를 기반으로 매매 신호를 생성하는 파이썬 코드 예시이다.
먼저, 필요한 라이브러리를 가상환경에 설치한다:
python -m venv myenv
source myenv/bin/activate
pip install finance-datareader pandas numpy matplotlib
이제 코드를 실행할 수 있다:
import FinanceDataReader as fdr
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def calculate_williams_r(data, period=14):
highest_high = data['High'].rolling(window=period).max()
lowest_low = data['Low'].rolling(window=period).min()
williams_r = (highest_high - data['Close']) / (highest_high - lowest_low) * -100
return williams_r
def backtest_strategy(data, symbol):
# Williams %R 계산
data['Williams %R'] = calculate_williams_r(data)
# 매매 신호 생성
data['Signal'] = 0
data.loc[data['Williams %R'] < -80, 'Signal'] = 1
data.loc[data['Williams %R'] > -20, 'Signal'] = -1
# 수익률 계산
data['Returns'] = data['Close'].pct_change()
data['Strategy Returns'] = data['Signal'].shift(1) * data['Returns']
# 누적 수익률 계산
data['Cumulative Returns'] = (1 + data['Strategy Returns']).cumprod()
# 결과 출력
print(f"{symbol} Backtest Results:")
print(data[['Close', 'Williams %R', 'Signal', 'Strategy Returns', 'Cumulative Returns']].tail())
# 그래프 그리기
plt.figure(figsize=(12, 8))
plt.plot(data['Cumulative Returns'], label=f"{symbol} Strategy Returns")
plt.title(f"Williams %R Strategy Backtest - {symbol}")
plt.ylabel('Cumulative Returns')
plt.xlabel('Date')
plt.legend()
plt.grid(True)
plt.show()
try:
# VOO와 QQQ ETF 데이터 가져오기
voo_data = fdr.DataReader('VOO', data_source='yahoo')
# 백테스트 실행
backtest_strategy(voo_data, 'VOO')
except Exception as e:
print(f"An error occurred: {e}")
이 코드는 FinanceDataReader 모듈을 사용하여 VOO ETF 데이터를 가져와 %R을 계산한다. 그런 다음, %R이 -80 이하이면 매수 신호(+1), -20 이상이면 매도 신호(-1)를 생성한다. 이 신호를 기반으로 각 ETF의 일간 수익률과 누적 수익률을 계산하고, 마지막으로 누적 수익률을 그래프로 그려 전략의 성과를 시각화한다.
또한, 코드는 try-except 블록으로 감싸져 있어 오류가 발생하면 오류 메시지를 출력한다. 이는 데이터를 가져오거나 계산하는 과정에서 발생할 수 있는 오류를 처리하기 위함이다.