비트코인 120일 이평선 전략 vs 바이 앤 홀드 전략 비교
나는 120일 이동평균선(MA : Moving Average)을 기준으로 비트코인을 매수/매도하는 전략을 유효하게 생각한다. 그건 바로 최근 5개년간 수익률만 보아도 알 수 있다. 물론 Buy & Hold 전략으로 더 큰 수익을 낸 해도 있었지만 120일 MA 전략이 안정적으로 매년 수익이 발생하기 때문이다. 올해도 2월 24일 94,000불이 매도시그널이었다.
120일 MA 전략 | Buy&Hold 전략 | |
2020 | 108% | 148% |
2021 | 97% | 79% |
2022 | 70% | -82% |
2023 | 46% | 103% |
2024 | 58% | 94% |
2025 | 7% | -8% |
숫자로 보는 매수/매도 구간
아래 초록색으로 표시한 구간이 매수 후 hold 한 구간이다. 최근 매수시그널이 발생한 2024.10.11에 62,000에 매수하여 매도시그널이 발생한 2025.02.24에 91,000원에 매도하였다면 수익률이 거의 50%에 달한다. (이 숫자만 보아도 120일 이동평균선 아래에서는 매도하는 것은 자명해 보인다.)
매수 시그널 | 종가 | 매도 시그널 | 종가 | |
2020-04-04 | 6,868 | 2020-03-08 | 8,108 | |
2020-04-06 | 7,272 | 2020-04-05 | 6,791 | |
2020-04-12 | 6,971 | 2020-04-10 | 6,865 | |
2020-04-16 | 7,117 | 2020-04-13 | 6,845 | |
2020-04-22 | 7,117 | 2020-04-20 | 6,882 | |
2020-09-24 | 10,760 | 2020-09-23 | 10,246 | |
2021-08-06 | 42,817 | 2021-05-12 | 49,151 | |
2022-03-24 | 43,961 | 2021-12-04 | 49,201 | |
2022-11-04 | 21,147 | 2022-04-08 | 42,288 | |
2023-01-12 | 18,870 | 2022-11-07 | 20,603 | |
2023-06-06 | 27,239 | 2023-06-05 | 25,760 | |
2023-06-08 | 26,508 | 2023-06-07 | 26,346 | |
2023-06-19 | 26,851 | 2023-06-09 | 26,480 | |
2023-10-16 | 28,519 | 2023-08-17 | 26,665 | |
2024-07-16 | 65,097 | 2024-06-18 | 65,141 | |
2024-07-19 | 66,710 | 2024-07-17 | 64,119 | |
2024-08-01 | 65,358 | 2024-07-31 | 64,619 | |
2024-08-23 | 64,094 | 2024-08-02 | 61,415 | |
2024-09-19 | 62,940 | 2024-08-26 | 62,881 | |
2024-10-04 | 62,067 | 2024-10-01 | 60,837 | |
2024-10-11 | 62,445 | 2024-10-09 | 60,582 | |
2025-02-24 | 91,418 |
혹시 검증이 필요한 분들을 위해 파이썬 코드는 아래 참조하면 된다.
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
# 1. 비트코인 10년치 데이터 가져오기
btc = yf.download('BTC-USD', start='2020-03-01', end='2025-02-28')
# 2. MultiIndex 문제 해결 (두 번째 레벨 제거)
if isinstance(btc.columns, pd.MultiIndex):
btc.columns = btc.columns.droplevel(1)
# 3. 이동평균선 계산 (NaN 방지)
btc['MA30'] = btc['Close'].rolling(window=30, min_periods=1).mean()
btc['MA60'] = btc['Close'].rolling(window=60, min_periods=1).mean()
btc['MA120'] = btc['Close'].rolling(window=120, min_periods=1).mean()
# 4. 이동평균선 컬럼 존재 여부 확인
print("컬럼 목록:", btc.columns) # 컬럼 확인
print("이동평균선 확인:\n", btc[['Close', 'MA120']].head()) # MA120 존재 확인
# 5. NaN 값 제거 (이제 확실히 존재하는 MA120을 기준으로)
btc.dropna(subset=['MA120'], inplace=True)
# 6. 이동평균선 그래프 그리기
plt.figure(figsize=(14,7))
plt.plot(btc['Close'], label='Bitcoin Price', color='black')
plt.plot(btc['MA30'], label='30-day MA', color='blue', linestyle='dashed')
plt.plot(btc['MA60'], label='60-day MA', color='red', linestyle='dashed')
plt.plot(btc['MA120'], label='120-day MA', color='green', linestyle='dashed')
# 7. 매수/매도 시점 계산
buy_signals = btc[(btc['Close'].shift(1) < btc['MA120'].shift(1)) & (btc['Close'] > btc['MA120'])]
sell_signals = btc[(btc['Close'].shift(1) > btc['MA120'].shift(1)) & (btc['Close'] < btc['MA120'])]
plt.scatter(buy_signals.index, buy_signals['Close'], marker='^', color='green', label='Buy Signal', alpha=1, s=100)
plt.scatter(sell_signals.index, sell_signals['Close'], marker='v', color='red', label='Sell Signal', alpha=1, s=100)
# 8. 보유 구간 색칠하기
holding_periods = btc['Close'] > btc['MA120']
plt.fill_between(btc.index, btc['Close'], btc['MA120'], where=holding_periods, color='lightgreen', alpha=0.3)
plt.title('Bitcoin Price and Moving Averages with Buy/Sell Signals and Holding Periods')
plt.legend()
plt.show()
# 9. 매수/매도 전략 구현
btc['Position'] = 0
btc.loc[btc['Close'] > btc['MA120'], 'Position'] = 1 # 매수
btc.loc[btc['Close'] < btc['MA120'], 'Position'] = -1 # 매도
# 10. 수익률 계산
btc['Returns'] = btc['Close'].pct_change()
btc['Strategy'] = btc['Position'].shift(1) * btc['Returns']
# 11. Buy and Hold 수익률 계산
btc['BuyHold'] = btc['Returns'].cumsum()
btc['StrategyCumulative'] = btc['Strategy'].cumsum()
# 12. 연간 수익률 계산 함수
def calculate_annual_returns(df):
df['Year'] = df.index.year
annual_strategy_returns = df.groupby('Year')['Strategy'].sum()
annual_buyhold_returns = df.groupby('Year')['Returns'].sum()
return annual_strategy_returns, annual_buyhold_returns
# 13. 연간 수익률 비교
annual_strategy_returns, annual_buyhold_returns = calculate_annual_returns(btc)
print("\n연간 수익률 (전략 vs Buy & Hold):")
print(pd.DataFrame({'Strategy': annual_strategy_returns, 'Buy & Hold': annual_buyhold_returns}))
'투자 > 투자생각' 카테고리의 다른 글
금 프리미엄 차익거래 시도하기 (0) | 2025.03.06 |
---|---|
차이나 항셍테크 ETF 비교 / 주요종목 정보 (0) | 2025.03.02 |
GPT로 보험공부해서 돈 천만원 아끼기 (0) | 2025.02.01 |
일본반도체 주요종목 정리 (0) | 2024.03.31 |
비만치료제 정리 (1) | 2024.03.31 |
댓글