3.7.3. 전략 2. RSI를 이용한 과매수 과매도 전략

이 섹션에서는 RSI를 활용한 과매수/과매도 전략을 구현합니다. RSI는 가격 변동의 속도와 크기를 측정하는 지표입니다. 과매수 및 과매도 상태를 판단하는 데 유용합니다. 이 전략은 RSI를 이용하여 매매 시점을 포착합니다.

3.7.3.1 전략 로직 설명

RSI는 0부터 100 사이의 값을 가집니다. 일반적으로 70 이상이면 과매수 상태로 간주합니다. 30 이하이면 과매도 상태로 간주합니다. 과매수 상태는 가격이 비정상적으로 높다는 의미입니다. 매도 시점으로 활용할 수 있습니다. 과매도 상태는 가격이 비정상적으로 낮다는 의미입니다. 매수 시점으로 활용할 수 있습니다.

이 전략은 다음과 같은 로직으로 작동합니다.

  1. RSI가 특정 값 이상이면 과매수 상태로 판단합니다.
  2. 과매수 상태에서는 매도 주문을 실행합니다.
  3. RSI가 특정 값 이하이면 과매도 상태로 판단합니다.
  4. 과매도 상태에서는 매수 주문을 실행합니다.
  5. 매수 또는 매도 후, 반대 신호가 발생하면 포지션을 청산합니다.

RSI 값의 기준은 시장 상황에 따라 조정할 수 있습니다. 백테스팅을 통해 최적의 값을 찾아야 합니다. 다른 기술 지표와 함께 사용하여 신호의 정확도를 높일 수 있습니다.

3.7.3.2 파이썬 코드 구현

다음은 RSI를 이용한 과매수/과매도 전략을 파이썬으로 구현하는 예시입니다. Pandas와 TA-Lib 라이브러리를 사용합니다.

1단계: 필요한 라이브러리 임포트

import pandas as pd
import talib
import pyupbit

2단계: 데이터 불러오기 및 RSI 계산

# 업비트 API를 통해 데이터 가져오기
df = pyupbit.get_ohlcv("KRW-BTC", interval="minute60", count=500)

# 컬럼명 변경 (필요한 경우)
df.rename(columns={'open': 'Open', 'high': 'High', 'low': 'Low', 'close': 'Close', 'volume': 'Volume'}, inplace=True)

# RSI 계산 (14일 기준)
df['RSI'] = talib.RSI(df['Close'], timeperiod=14)

3단계: 매매 신호 생성 함수 정의

def generate_rsi_signals(df, overbought=70, oversold=30):
    """RSI 기반 과매수/과매도 전략 매매 신호 생성

    Args:
        df (pd.DataFrame): OHLCV 데이터프레임, RSI 컬럼 필요
        overbought (int): 과매수 기준 (기본값: 70)
        oversold (int): 과매도 기준 (기본값: 30)

    Returns:
        pd.DataFrame: 'signal' 컬럼이 추가된 데이터프레임 (1: 매수, -1: 매도, 0: 유지)
    """
    signals = [0] * len(df) # 초기값 0으로 설정
    position = 0 # 0: No position, 1: Long, -1: Short

    for i in range(1, len(df)):
        # 매수 신호 (과매도 상태 and No Position)
        if df['RSI'][i] < oversold and position == 0:
            signals[i] = 1 # 매수 신호
            position = 1 # Long Position
        # 매도 신호 (과매수 상태 and Long Position)
        elif df['RSI'][i] > overbought and position == 1:
            signals[i] = -1 # 매도 신호 (Long 청산)
            position = 0 # No Position
        # 매도 신호 (과매수 상태 and No Position)
        elif df['RSI'][i] > overbought and position == 0:
            signals[i] = -1 # 매도 신호 (Short 진입)
            position = -1 # Short Position
        # 매수 신호 (과매도 상태 and Short Position)
        elif df['RSI'][i] < oversold and position == -1:
            signals[i] = 1 # 매수 신호 (Short 청산)
            position = 0 # No Position
        else:
            signals[i] = 0 # 유지 신호
    df['signal'] = signals
    return df

df = generate_rsi_signals(df)
print(df[['Close', 'RSI', 'signal']].tail())

4단계: 백테스팅 함수 정의 (간단한 예시)

def rsi_backtest(df, initial_balance=1000000, fee=0.0005):
    """RSI 기반 과매수/과매도 전략 백테스팅

    Args:
        df (pd.DataFrame): OHLCV 데이터프레임, Close, signal 컬럼 필요
        initial_balance (float): 초기 자본
        fee (float): 거래 수수료

    Returns:
        float: 최종 자산
    """
    balance = initial_balance
    position = 0 # 0: No position, 1: Long, -1: Short
    buy_price = 0

    for i in range(1, len(df)):
        if df['signal'][i] == 1 and position == 0: # 매수 신호 and No Position
            buy_price = df['Close'][i]
            balance *= (1 - fee)
            position = 1 # Long
            print(f"{df.index[i]}: Buy at {buy_price}")
        elif df['signal'][i] == -1 and position == 1: # 매도 신호 and Long Position
            sell_price = df['Close'][i]
            profit = (sell_price - buy_price) / buy_price
            balance += balance * profit * (1 - fee)
            position = 0 # No Position
            print(f"{df.index[i]}: Sell at {sell_price}, Profit: {profit:.4f}")
        elif df['signal'][i] == -1 and position == 0: # 매도 신호 and No Position
            buy_price = df['Close'][i]
            balance *= (1 - fee)
            position = -1 # Short
            print(f"{df.index[i]}: Short at {buy_price}")
        elif df['signal'][i] == 1 and position == -1: # 매수 신호 and Short Position
            sell_price = df['Close'][i]
            profit = (buy_price - sell_price) / sell_price
            balance += balance * profit * (1 - fee)
            position = 0 # No Position
            print(f"{df.index[i]}: Cover at {sell_price}, Profit: {profit:.4f}")

    if position != 0:
        last_price = df['Close'][len(df)-1]
        if position == 1:
            profit = (last_price - buy_price) / buy_price
        else:
            profit = (buy_price - last_price) / last_price
        balance += balance * profit * (1 - fee)
        print(f"마지막 청산: {last_price}, 수익률: {profit:.4f}")

    print(f"최종 자산: {balance:.0f}")
    return balance

rsi_backtest(df)

5단계: 결과 분석 및 개선

백테스팅 결과를 분석합니다. 수익률, MDD 등을 확인합니다. 전략의 파라미터(과매수/과매도 기준)를 조정하여 성능을 개선합니다.

주의사항:

  • 위 코드는 예시이며, 실제 투자에 사용하기 전에 충분한 검증이 필요합니다.
  • 수수료, 슬리피지 등을 고려하여 백테스팅해야 합니다.
  • 백테스팅 결과는 과거 데이터에 기반하며, 미래 수익을 보장하지 않습니다.
  • 다양한 시장 상황에서 전략의 성능을 평가해야 합니다.

이 섹션에서는 RSI를 이용한 과매수/과매도 전략을 파이썬 코드로 구현했습니다. 다음 섹션에서는 볼린저 밴드를 활용한 매매 전략을 구현합니다.

위로 스크롤