피보나치 되돌림이란?
피보나치 되돌림(Fibonacci Retracement)은 가격이 추세 방향으로 움직인 뒤, 일정 비율만큼 되돌아오는 지점을 예측하는 기술적 분석 도구입니다. 23.6%, 38.2%, 50%, 61.8%, 78.6% 수준이 핵심 되돌림 레벨로, 전 세계 트레이더들이 지지·저항 판단에 활용합니다.
이 글에서는 파이썬으로 피보나치 되돌림 레벨을 자동 계산하고, 해당 레벨에서 매매 신호를 생성하는 자동매매 전략을 단계별로 구현합니다. 백테스트 결과까지 포함해 실전에 바로 적용할 수 있도록 안내합니다.
피보나치 되돌림 핵심 레벨
| 레벨 | 비율 | 의미 |
|---|---|---|
| Level 1 | 23.6% | 얕은 되돌림, 강한 추세 지속 시 첫 지지 |
| Level 2 | 38.2% | 일반적인 되돌림, 건강한 조정 구간 |
| Level 3 | 50.0% | 심리적 중간 지점, 많은 트레이더가 주시 |
| Level 4 | 61.8% | 황금 비율, 가장 강력한 되돌림 지지선 |
| Level 5 | 78.6% | 깊은 되돌림, 추세 전환 가능성 경고 |
전략 개요: 피보나치 되돌림 매매 로직
자동매매 전략의 핵심 로직은 다음과 같습니다:
- 스윙 하이·로우 자동 탐지: 일정 기간(lookback) 내 최고점과 최저점을 자동으로 찾습니다.
- 피보나치 레벨 계산: 스윙 포인트 기반으로 되돌림 레벨을 실시간 산출합니다.
- 매수 신호: 가격이 38.2%~61.8% 레벨에 도달하고 반등 캔들이 확인되면 매수합니다.
- 매도 신호: 가격이 스윙 하이 근처 또는 0% 레벨에 도달하면 익절합니다.
- 손절: 78.6% 레벨 하향 돌파 시 손절로 리스크를 관리합니다.
파이썬 구현: 스윙 포인트 탐지
먼저 가격 데이터에서 스윙 하이(Swing High)와 스윙 로우(Swing Low)를 자동으로 찾는 함수를 구현합니다.
import pandas as pd
import numpy as np
def find_swing_points(df, lookback=20):
"""스윙 하이·로우를 자동 탐지"""
highs = df['high'].rolling(window=lookback, center=True).max()
lows = df['low'].rolling(window=lookback, center=True).min()
swing_high_mask = df['high'] == highs
swing_low_mask = df['low'] == lows
# 가장 최근 스윙 포인트 반환
last_swing_high = df.loc[swing_high_mask, 'high'].iloc[-1]
last_swing_low = df.loc[swing_low_mask, 'low'].iloc[-1]
return last_swing_high, last_swing_low
lookback 파라미터를 조절하면 단기(10~15)·중기(20~30)·장기(50+) 스윙 포인트를 탐지할 수 있습니다.
피보나치 되돌림 레벨 계산
def calc_fib_levels(swing_high, swing_low):
"""피보나치 되돌림 레벨 계산"""
diff = swing_high - swing_low
levels = {
'0.0%': swing_high,
'23.6%': swing_high - diff * 0.236,
'38.2%': swing_high - diff * 0.382,
'50.0%': swing_high - diff * 0.500,
'61.8%': swing_high - diff * 0.618,
'78.6%': swing_high - diff * 0.786,
'100.0%': swing_low,
}
return levels
# 사용 예시
swing_high, swing_low = find_swing_points(df)
fib = calc_fib_levels(swing_high, swing_low)
for level, price in fib.items():
print(f"{level}: {price:,.2f}")
매매 신호 생성 로직
피보나치 레벨과 가격 액션을 결합해 실제 매매 신호를 생성합니다. 단순히 레벨 터치만으로 진입하면 위험하므로, 확인 캔들(confirmation candle) 조건을 추가합니다.
def generate_signals(df, fib_levels, tolerance=0.005):
"""피보나치 레벨 기반 매매 신호 생성"""
signals = pd.Series(0, index=df.index)
fib_382 = fib_levels['38.2%']
fib_618 = fib_levels['61.8%']
fib_786 = fib_levels['78.6%']
fib_0 = fib_levels['0.0%']
for i in range(2, len(df)):
price = df['close'].iloc[i]
prev_close = df['close'].iloc[i - 1]
prev_open = df['open'].iloc[i - 1]
# 매수: 38.2%~61.8% 구간 + 양봉 확인
in_buy_zone = fib_618 * (1 - tolerance) <= price <= fib_382 * (1 + tolerance)
bullish_candle = prev_close > prev_open # 이전 봉이 양봉
if in_buy_zone and bullish_candle:
signals.iloc[i] = 1 # 매수
# 매도: 0% 레벨(스윙 하이) 근처 도달
elif price >= fib_0 * (1 - tolerance):
signals.iloc[i] = -1 # 매도
# 손절: 78.6% 하향 돌파
elif price < fib_786 * (1 - tolerance):
signals.iloc[i] = -2 # 손절
return signals
백테스트 구현
생성된 신호를 기반으로 간단한 백테스트를 수행합니다. 포지션 관리와 수익률 계산을 포함합니다.
def backtest_fib_strategy(df, signals, initial_capital=10_000_000):
"""피보나치 되돌림 전략 백테스트"""
capital = initial_capital
position = 0
entry_price = 0
trades = []
for i in range(len(df)):
sig = signals.iloc[i]
price = df['close'].iloc[i]
if sig == 1 and position == 0:
# 매수 진입
position = capital / price
entry_price = price
capital = 0
elif sig in [-1, -2] and position > 0:
# 매도 또는 손절
capital = position * price
pnl_pct = (price - entry_price) / entry_price * 100
trades.append({
'entry': entry_price,
'exit': price,
'pnl_pct': pnl_pct,
'type': '익절' if sig == -1 else '손절'
})
position = 0
# 결과 요약
final_value = capital if position == 0 else position * df['close'].iloc[-1]
total_return = (final_value - initial_capital) / initial_capital * 100
trade_df = pd.DataFrame(trades)
win_rate = (trade_df['pnl_pct'] > 0).mean() * 100 if len(trades) > 0 else 0
return {
'total_return': total_return,
'num_trades': len(trades),
'win_rate': win_rate,
'avg_pnl': trade_df['pnl_pct'].mean() if len(trades) > 0 else 0,
'trades': trade_df
}
RSI 필터로 신호 정확도 높이기
피보나치 되돌림 단독으로 사용하면 허위 신호가 발생할 수 있습니다. RSI(상대강도지수)를 보조 필터로 추가하면 승률을 크게 개선할 수 있습니다.
def add_rsi_filter(df, period=14):
"""RSI 계산 후 필터 적용"""
delta = df['close'].diff()
gain = delta.where(delta > 0, 0).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
df['rsi'] = 100 - (100 / (1 + rs))
return df
def enhanced_signals(df, fib_levels, tolerance=0.005):
"""RSI 필터 적용된 강화 신호"""
df = add_rsi_filter(df)
base_signals = generate_signals(df, fib_levels, tolerance)
for i in range(len(df)):
# 매수 신호 + RSI 30~50 구간만 허용 (과매도 반등)
if base_signals.iloc[i] == 1:
if not (30 <= df['rsi'].iloc[i] <= 50):
base_signals.iloc[i] = 0 # 필터링
return base_signals
RSI가 30~50 구간일 때만 매수를 허용하면, 과매도 반등 타이밍과 피보나치 지지가 겹치는 고확률 진입점만 포착할 수 있습니다.
실전 적용 시 주의사항
- 추세 확인 필수: 피보나치 되돌림은 추세 시장에서만 유효합니다. 횡보장에서는 레벨이 무의미해집니다. 이동평균선이나 MACD 신호로 추세를 먼저 확인하세요.
- 다중 시간대 분석: 일봉 피보나치 레벨과 4시간봉 레벨이 겹치는 구간(confluence)은 더 강력한 지지·저항이 됩니다.
- 포지션 사이징: 한 번의 거래에 전체 자산의 1~2%만 리스크로 설정하세요. 포지션 사이징 전략을 함께 참고하면 리스크 관리가 훨씬 수월해집니다.
- 슬리피지 고려: 실제 거래에서는 호가 스프레드와 슬리피지가 수익률을 깎습니다. 백테스트 결과에 0.05~0.1% 슬리피지를 반영하세요.
- 과최적화 경계: lookback, tolerance 등 파라미터를 과도하게 튜닝하면 과거 데이터에만 맞는 전략이 됩니다. 아웃오브샘플 테스트를 반드시 수행하세요.
전체 코드: 피보나치 자동매매 봇
import ccxt
import pandas as pd
import time
def run_fib_bot(symbol='BTC/USDT', timeframe='4h', lookback=20):
"""피보나치 되돌림 자동매매 봇 메인 루프"""
exchange = ccxt.binance({'enableRateLimit': True})
while True:
# 1. OHLCV 데이터 수집
ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=100)
df = pd.DataFrame(ohlcv, columns=['ts','open','high','low','close','vol'])
# 2. 스윙 포인트 + 피보나치 계산
sh, sl = find_swing_points(df, lookback)
fib = calc_fib_levels(sh, sl)
# 3. RSI 강화 신호
signals = enhanced_signals(df, fib)
latest = signals.iloc[-1]
# 4. 주문 실행
current_price = df['close'].iloc[-1]
if latest == 1:
print(f"[매수] {symbol} @ {current_price:,.2f}")
print(f" 목표: {fib['0.0%']:,.2f} | 손절: {fib['78.6%']:,.2f}")
# exchange.create_market_buy_order(symbol, amount)
elif latest in [-1, -2]:
action = '익절' if latest == -1 else '손절'
print(f"[{action}] {symbol} @ {current_price:,.2f}")
# exchange.create_market_sell_order(symbol, amount)
# 5. 대기
time.sleep(60 * 15) # 15분 대기
if __name__ == '__main__':
run_fib_bot()
마무리
피보나치 되돌림은 단순하면서도 강력한 기술적 분석 도구입니다. 파이썬으로 자동화하면 감정 없이 일관된 매매가 가능해지고, RSI 같은 보조지표와 결합하면 승률을 더 높일 수 있습니다. 핵심은 38.2%~61.8% 골든 존에서의 확인 매수와, 78.6% 레벨의 엄격한 손절입니다. 백테스트로 전략을 검증한 뒤 소액으로 실전 테스트를 거쳐 안정적인 자동매매 시스템을 구축해 보세요.