본문 바로가기
투자/투자생각

비트코인 120일 이동평균선 아래에서 무조건 매도해야 하는 이유

by thomasito 2025. 3. 1.

비트코인 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}))

댓글