이 섹션에서는 백테스팅의 핵심인 가상 매매 시뮬레이션 로직 구현을 다룹니다. 과거 데이터를 기반으로 자동매매 전략을 가상으로 실행합니다. 실제 시장과 유사한 환경을 구축하여 전략의 성능을 평가합니다. 체계적인 단계를 따라 구현하여 실질적인 도움을 얻을 수 있습니다.
가상 매매 시뮬레이션은 실제 시장 거래를 모방합니다. 과거의 가격 변동 데이터를 입력으로 사용합니다. 미리 정의된 매매 전략에 따라 매수, 매도 주문을 생성합니다. 생성된 주문은 가상으로 체결됩니다. 가상 포트폴리오를 통해 자산 변화를 추적합니다.
이 과정은 전략의 수익성과 위험성을 평가하는 데 중요합니다. 다양한 시나리오를 통해 전략의 강점과 약점을 분석합니다. 백테스팅 결과를 바탕으로 전략을 개선할 수 있습니다. 안정적인 자동매매 시스템 구축에 기여합니다.
1단계: 데이터 준비 및 전처리
가상 매매 시뮬레이션에 사용할 과거 데이터를 준비합니다. 업비트 또는 바이낸스 API를 사용하여 데이터를 수집합니다. 수집된 데이터는 OHLCV(Open, High, Low, Close, Volume) 형태입니다. 데이터의 시간 간격을 설정합니다. (예: 1분봉, 1시간봉, 일봉)
데이터의 결측치를 처리합니다. 결측치가 있는 경우, 이전 값으로 채우거나 제거합니다. 데이터의 이상치를 제거합니다. 이상치가 있는 경우, 분석 결과에 왜곡을 줄 수 있습니다. 데이터의 형식을 통일합니다. 날짜, 가격, 거래량 등의 형식을 일관되게 유지합니다.
import pandas as pd
# CSV 파일에서 데이터 불러오기
df = pd.read_csv("btc_ohlcv.csv")
# 날짜 컬럼을 datetime 형식으로 변환
df['date'] = pd.to_datetime(df['date'])
# 인덱스를 날짜 컬럼으로 설정
df.set_index('date', inplace=True)
# 결측치 처리 (이전 값으로 채우기)
df.fillna(method='ffill', inplace=True)
# 데이터 확인
print(df.head())
2단계: 매매 전략 구현
매매 전략은 자동매매 시스템의 핵심 로직입니다. 과거 데이터를 기반으로 매수 및 매도 시점을 결정합니다. 이동평균선 교차, RSI, MACD 등 다양한 기술적 지표를 활용합니다. 전략의 규칙을 명확하게 정의합니다.
매수 조건과 매도 조건을 설정합니다. 예를 들어, “5일 이동평균선이 20일 이동평균선을 상향 돌파할 때 매수”와 같이 정의합니다. 손절매(Stop-loss) 및 익절매(Take-profit) 조건을 설정합니다. 위험 관리를 위해 필수적인 요소입니다.
def moving_average_crossover(df, short_window, long_window):
"""
이동평균선 교차 전략
"""
# 이동평균선 계산
df['short_ma'] = df['close'].rolling(window=short_window).mean()
df['long_ma'] = df['close'].rolling(window=long_window).mean()
# 매수/매도 신호 생성
df['signal'] = 0.0
df['signal'][short_window:] = np.where(df['short_ma'][short_window:] > df['long_ma'][short_window:], 1.0, 0.0)
df['position'] = df['signal'].diff()
return df
3단계: 가상 주문 처리 로직 구현
가상 주문 처리 로직은 매매 전략에 따라 주문을 생성하고 체결합니다. 실제 거래소 API를 사용하는 대신 가상으로 주문을 처리합니다. 주문 유형을 정의합니다. (예: 지정가 주문, 시장가 주문) 주문 수량을 결정합니다. (예: 보유 자산의 10% 매수)
주문 체결 로직을 구현합니다. 시장가 주문은 즉시 체결된다고 가정합니다. 지정가 주문은 특정 가격에 도달하면 체결된다고 가정합니다. 거래 수수료를 고려합니다. 수수료는 거래 금액의 일정 비율로 부과됩니다. 슬리피지를 고려합니다. 슬리피지는 주문 가격과 실제 체결 가격의 차이입니다.
def execute_order(df, initial_capital, commission=0.0005, slippage=0.0001):
"""
가상 주문 처리 로직
"""
# 초기 자본 설정
capital = initial_capital
position = 0 # 0: No position, 1: Long position
# 결과 저장 리스트
trade_log = []
for i in range(1, len(df)):
# 매수 신호
if df['position'][i] == 1:
# 수수료 및 슬리피지 고려
buy_price = df['close'][i] * (1 + slippage)
buy_commission = buy_price * commission
# 매수 가능 수량 계산
quantity = capital / (buy_price + buy_commission)
# 자본 업데이트
capital -= (buy_price + buy_commission) * quantity
position = 1
# 로그 기록
trade_log.append({
'date': df.index[i],
'type': 'buy',
'price': buy_price,
'quantity': quantity,
'commission': buy_commission * quantity,
'capital': capital
})
# 매도 신호
elif df['position'][i] == -1:
# 수수료 및 슬리피지 고려
sell_price = df['close'][i] * (1 - slippage)
sell_commission = sell_price * commission
# 자본 업데이트
capital += (sell_price - sell_commission) * quantity
position = 0
# 로그 기록
trade_log.append({
'date': df.index[i],
'type': 'sell',
'price': sell_price,
'quantity': quantity,
'commission': sell_commission * quantity,
'capital': capital
})
return trade_log, capital
4단계: 포트폴리오 관리
포트폴리오 관리는 가상 자산의 변화를 추적하고 관리합니다. 초기 자본을 설정합니다. (예: 1000만원) 보유 자산의 수량과 가치를 기록합니다. 매수 및 매도 시 자산 정보를 업데이트합니다.
거래 내역을 기록합니다. 매수, 매도, 수수료, 슬리피지 등을 기록합니다. 손익을 계산합니다. 각 거래별 손익과 전체 손익을 계산합니다.
def calculate_profit(trade_log, initial_capital, last_price):
"""
손익 계산
"""
# 최종 자본
final_capital = initial_capital
for trade in trade_log:
if trade['type'] == 'buy':
final_capital -= (trade['price'] + trade['commission']) * trade['quantity']
elif trade['type'] == 'sell':
final_capital += (trade['price'] - trade['commission']) * trade['quantity']
# 보유 자산 가치
if trade_log and trade_log[-1]['type'] == 'buy':
quantity = trade_log[-1]['quantity']
final_capital += quantity * last_price
# 수익률 계산
profit = final_capital - initial_capital
profit_rate = (profit / initial_capital) * 100
return profit, profit_rate, final_capital
5단계: 백테스팅 실행 및 결과 분석
백테스팅을 실행하고 결과를 분석합니다. 과거 데이터를 순차적으로 입력하여 가상 매매를 진행합니다. 각 시점마다 포트폴리오를 업데이트하고 거래 내역을 기록합니다. 백테스팅 종료 후, 수익률, MDD, 승률 등 다양한 지표를 계산합니다.
백테스팅 결과를 시각화합니다. 수익 곡선을 그래프로 표시하여 전략의 성과를 직관적으로 파악합니다. 매매 내역을 분석합니다. 어떤 시점에서 매수 및 매도가 이루어졌는지 확인합니다. 전략의 강점과 약점을 파악합니다.
“`python
import matplotlib.pyplot as plt
def analyze_results(trade_log, initial_capital, df):
“””
백테스팅 결과 분석
“””
# 손익 계산
last_price = df[‘close’].iloc[-1]
profit, profit_rate, final_capital = calculate_profit(trade_log, initial_capital, last_price)
# 결과 출력
print(f"초기 자본: {initial