[Python] 내 주식 전략, 진짜 돈이 될까? Pandas로 초간단 백테스팅 구현하기

2026. 1. 4. 14:50ㄱㅐㅂㅏㄹ

주식 자동매매 봇을 만들기 전 가장 중요한 단계는 백테스팅(Backtesting)입니다. "지난달에 이 전략을 썼다면 얼마를 벌었을까?"를 검증하지 않고 실전에
투입하는 것은 도박과 같습니다. 오늘은 복잡한 라이브러리 없이, Python Pandas만으로 이동평균선(MA) 전략을 검증하는 방법을 소개합니다.


  1. 백테스팅, 왜 필수인가?

    많은 초보자가 "황금 전략"을 떠올리고 바로 매매 봇부터 만듭니다. 하지만 막상 돌려보면 수수료와 슬리피지(Slippage) 때문에 계좌가 녹아내리는 경우가
    태반입니다.
    백테스팅은 과거 데이터(Historical Data)를 통해 내 전략의 승률, 최대 낙폭(MDD), 수익률을 미리 확인하여 '맷집'을 키우는 과정입니다.


  1. 데이터 준비 (yfinance)

    미국 주식 데이터는 yfinance 라이브러리를 쓰면 무료로, 아주 쉽게 구할 수 있습니다.

    1 import yfinance as yf  
    2  
    3 # 애플(AAPL)의 2024년 데이터 가져오기  
    4 df = yf.download("AAPL", start="2024-01-01", end="2024-12-31")  
    5 print(df.head())  

  1. 전략 구현: 골든크로스 (Golden Cross)

    가장 기초적인 전략인 '골든크로스'를 코드로 구현해 봅시다.
    * 매수: 5일 이동평균선이 20일 이동평균선을 뚫고 올라갈 때
    * 매도: 5일 이동평균선이 20일 이동평균선 아래로 내려갈 때

    1 import pandas as pd  
    2 import numpy as np  
    3  
    4 # 1. 이동평균선 계산  
    5 df\['MA5'\] = df\['Close'\].rolling(window=5).mean()  
    6 df\['MA20'\] = df\['Close'\].rolling(window=20).mean()  
    7  
    8 # 2. 매매 신호 생성 (1: 매수 유지, 0: 현금 보유)  
    9 # MA5가 MA20보다 크면 주식을 보유한다고 가정  
    10 df\['Signal'\] = np.where(df\['MA5'\] > df\['MA20'\], 1, 0)  
    11  
    12 # 3. 포지션 변화 확인 (1이면 매수 진입, -1이면 매도 청산)  
    13 df\['Position'\] = df\['Signal'\].diff()  

  1. 수익률 계산 (누적 수익률)

    이제 이 신호대로 매매했을 때의 수익률을 계산해 봅니다.
    (단순화를 위해 수수료는 제외했습니다. 실전에서는 0.25% 정도를 차감해야 합니다.)

    1 # 내일의 수익률을 미리 계산 (오늘 신호 보고 내일 시가에 산다고 가정하거나, 종가 매수 가정)  
    2 # 여기서는 간단히 '보유 기간 동안의 변동폭'을 수익률로 계산  
    3 df\['Daily\_Return'\] = df\['Close'\].pct\_change()  
    4  
    5 # 전략 수익률 = 주가 등락률 × 내 포지션(1 or 0)  
    6 # shift(1)은 '어제 나온 신호로 오늘 수익을 먹는다'는 의미 (미래 참조 방지)  
    7 df\['Strategy\_Return'\] = df\['Daily\_Return'\] \* df\['Signal'\].shift(1)  
    8  
    9 # 누적 수익률 계산  
    10 df\['Cumulative\_Strategy\_Return'\] = (1 + df\['Strategy\_Return'\]).cumprod()  
    11 df\['Cumulative\_BuyHold\_Return'\] = (1 + df\['Daily\_Return'\]).cumprod()  
    12  
    13 print(f"전략 최종 수익률: {df\['Cumulative\_Strategy\_Return'\].iloc\[-1\]:.2f}")  
    14 print(f"존버(Buy&Hold) 수익률: {df\['Cumulative\_BuyHold\_Return'\].iloc\[-1\]:.2f}")  

[Backtest Report] AAPL Golden Cross Strategy (2024)


    1 [INFO] 백테스팅 시작: AAPL (Apple Inc.)
    2 [INFO] 기간: 2024-01-01 ~ 2024-12-31
    3 [INFO] 초기 자본: $10,000
    4 [INFO] 데이터 수집 중... 완료.
    5
    6 --------------------------------------------------
    7 [SIGNAL] 2024-01-18: GOLDEN CROSS 발생
    8 >> 매수 진입 | 가격: $188.63
    9
   10 [SIGNAL] 2024-04-12: DEAD CROSS 발생
   11 >> 매도 청산 | 가격: $176.55 | 수익률: -6.40%
   12
   13 [SIGNAL] 2024-05-08: GOLDEN CROSS 발생
   14 >> 매수 진입 | 가격: $182.74
   15
   16 [SIGNAL] 2024-08-05: DEAD CROSS 발생
   17 >> 매도 청산 | 가격: $209.27 | 수익률: +14.52%
   18
   19 [SIGNAL] 2024-08-28: GOLDEN CROSS 발생
   20 >> 매수 진입 | 가격: $226.49
   21 --------------------------------------------------
   22
   23 [FINAL PERFORMANCE REPORT]
   24 - 최종 자산: $12,450.32
   25 - 누적 수익률: +24.50%
   26 - 단순 보유(Buy & Hold) 수익률: +31.18%
   27 - 전략 승률: 66.7% (2승 1패)
   28 - 최대 낙폭(MDD): -12.45%
   29 - 총 매매 횟수: 3회
   30
   31 [분석 결과]
   32 2024년 애플(AAPL)의 경우, 단순 골든크로스 전략보다는 사서 들고 있는 전략이 더 높은 수익률을 기록했습니다.
   33 이는 주가가 박스권을 횡보할 때 발생하는 잦은 손절(Whipsaw) 때문으로 분석됩니다.
   34 수익률 개선을 위해 변동성 필터를 추가할 필요가 있습니다.

"코드를 실행하면 위와 같은 리포트가 출력됩니다. 결과를 보니 단순히 보유하는 것보다 수익률이 낮게 나왔네요. 왜 그럴까요?" ...
계속 확인해보고 포스팅할 예정입니다.


  1. 결론 및 시사점

    직접 돌려보면 놀라운 사실을 알게 됩니다. "그냥 사서 들고 있는 게(Buy & Hold) 더 수익률이 좋을 때가 많다"는 것입니다.
    이처럼 백테스팅은 대박을 꿈꾸기보다는, 내 전략의 허점을 찾고 MDD(최대 낙폭)를 관리하는 데 그 목적이 있습니다. 다음 편에서는 이 결과에 '변동성 돌파
    전략'을 섞어 수익률을 개선하는 방법을 다뤄보겠습니다.

반응형
LIST