Williams Percent Range (%R)를 활용한 트레이딩전략(Trading Strategy Using Williams Percent Range)

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을 활용한 트레이딩전략은 다음과 같이 구성할 수 있다:

  1. %R이 -80 이하로 하락한 후 상승하면 매수 신호로 간주한다.
  2. %R이 -20 이상으로 상승한 후 하락하면 매도 신호로 간주한다.
  3. %R이 -80에서 -20 사이에 있을 때는 추세가 명확하지 않은 것으로 판단하고 매매를 자제한다.
  4. 추가적으로, 가격 차트와 %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 블록으로 감싸져 있어 오류가 발생하면 오류 메시지를 출력한다. 이는 데이터를 가져오거나 계산하는 과정에서 발생할 수 있는 오류를 처리하기 위함이다.

Leave a Reply

error: Content is protected !!