
지금까지 이동평균 시리즈를 통해 추세를 파악하는 방법을 다뤘습니다. 이번에는 관점을 바꿔서, 가격이 얼마나 움직이는지 — 즉 변동성을 측정하는 지표인 ATR을 소개합니다.
ATR은 매수/매도 타이밍을 알려주는 지표가 아닙니다. 그래서 처음 접하면 "이걸 왜 써야 하지?" 싶을 수 있는데, 실전에서는 가장 중요한 지표 중 하나입니다. 아무리 좋은 진입 신호를 잡아도 손절 라인을 잘못 잡거나 포지션 크기를 잘못 설정하면 결국 돈을 잃습니다. ATR은 바로 그 부분 — 리스크 관리 — 의 핵심 도구입니다.
지표 소개
ATR은 J. Welles Wilder가 1978년에 개발한 지표로, 일정 기간 동안의 평균적인 가격 변동 폭을 나타냅니다. 방향(상승/하락)은 고려하지 않고, 순수하게 "얼마나 움직였는가"만 측정합니다.
ATR을 계산하려면 먼저 TR(True Range)을 구해야 합니다. TR은 다음 세 값 중 가장 큰 값입니다.
TR = max(고가 - 저가, |고가 - 전일 종가|, |저가 - 전일 종가|)
단순히 당일 고가 - 저가만 보면 갭(전일 종가와 당일 시가 사이의 차이)을 놓칠 수 있기 때문에, 전일 종가와의 차이도 함께 비교하는 것입니다.
ATR은 이 TR을 일정 기간 동안 평활화한 값입니다. 기본 기간은 14일이며, Wilder's smoothing 방식을 사용합니다.
ATR = 전일 ATR × (N-1)/N + 당일 TR × 1/N
ATR 값이 크면 변동성이 크다는 뜻이고, 작으면 변동성이 낮다는 뜻입니다.
차트로 보기

상단은 BTC/USDT 가격, 하단은 ATR(14) 값입니다. 가격이 급등하거나 급락하는 구간에서 ATR이 함께 올라가는 것을 확인할 수 있습니다. 반대로 가격이 좁은 범위에서 횡보할 때는 ATR이 낮아집니다.
코드
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# ===== 설정 =====
DATA_FILE = "BTCUSDT_1d.csv"
ATR_PERIOD = 14
ZOOM_DAYS = 365
# ================
# 데이터 로드
df = pd.read_csv(DATA_FILE, index_col="timestamp", parse_dates=True)
# TR (True Range) 계산
df["h_l"] = df["high"] - df["low"]
df["h_pc"] = abs(df["high"] - df["close"].shift(1))
df["l_pc"] = abs(df["low"] - df["close"].shift(1))
df["tr"] = df[["h_l", "h_pc", "l_pc"]].max(axis=1)
# ATR 계산 (Wilder's smoothing)
df["atr"] = df["tr"].ewm(alpha=1/ATR_PERIOD, adjust=False).mean()
# 최근 구간
df_zoom = df.tail(ZOOM_DAYS).copy()
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8), height_ratios=[3, 1], sharex=True)
# 상단: 가격
ax1.plot(df_zoom.index, df_zoom["close"], color="#333333", linewidth=1)
ax1.set_title(f"BTC/USDT ATR {ATR_PERIOD} (Last {ZOOM_DAYS}D)", fontsize=14, fontweight="bold")
ax1.set_ylabel("Price")
ax1.grid(True, alpha=0.3)
# 하단: ATR
ax2.plot(df_zoom.index, df_zoom["atr"], color="#E53935", linewidth=1.5, label=f"ATR {ATR_PERIOD}")
ax2.fill_between(df_zoom.index, df_zoom["atr"], alpha=0.2, color="#E53935")
ax2.set_ylabel("ATR")
ax2.legend(fontsize=10)
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
활용법
ATR은 그 자체로 매수/매도 신호를 만들지는 않습니다. 대신 다른 전략과 함께 쓰면서 변동성에 맞게 조절하는 역할을 합니다. 대표적인 활용법 세 가지를 소개합니다.
1. 손절 라인 설정
가장 흔한 활용법입니다. 진입가에서 N × ATR만큼 떨어진 곳에 손절을 설정합니다.
예를 들어 BTC를 $90,000에 매수했고, 현재 ATR이 $3,000이라면 2 × ATR = $6,000, 손절 라인은 $84,000이 됩니다. 고정 금액(예: -5%)으로 손절하는 것보다, 현재 변동성에 맞게 자동으로 조절되는 것이 장점입니다. 변동성이 클 때는 손절을 넓게, 작을 때는 좁게 잡아서 불필요한 조기 손절을 줄여줍니다.
2. 포지션 사이징
자본의 일정 비율만 위험에 노출하도록 포지션 크기를 조절합니다.
예를 들어 자본이 $10,000이고 거래당 최대 손실을 자본의 1%($100)로 제한한다면, ATR이 $3,000일 때 매수 수량은 $100 / $3,000 ≈ 0.033 BTC가 됩니다. 변동성이 작아져서 ATR이 $1,500이 되면 같은 리스크로 0.066 BTC를 매수할 수 있습니다. 이렇게 하면 변동성에 상관없이 거래당 위험을 일정하게 유지할 수 있습니다.
3. 추세 강도 판단
ATR이 상승하면 현재 추세(상승이든 하락이든)가 강해지고 있다는 신호입니다. 반대로 ATR이 낮아지면 시장이 잠잠해지고 있다는 뜻이며, 조만간 새로운 움직임이 나올 수 있습니다. 이동평균의 추세 방향과 ATR의 변동성 크기를 함께 보면 더 입체적인 판단이 가능합니다.
참고: ATR의 절대값
ATR은 가격의 절대적인 변동 폭을 나타냅니다. 그래서 BTC처럼 가격이 높은 종목은 ATR 값 자체가 수천 달러에 달하고, 가격이 낮은 종목은 훨씬 작은 값이 나옵니다. ATR 절대값만으로는 종목 간 변동성을 비교할 수 없고, 비교하려면 ATR을 현재 가격으로 나눈 비율(ATR / Price)을 보는 것이 적절합니다.
정리
ATR은 방향이 아닌 크기를 측정하는 지표입니다. 매수/매도 신호를 직접 생성하지는 않지만, 손절 라인 설정이나 포지션 사이징 같은 리스크 관리에서 핵심적인 역할을 합니다. 이동평균이 "어디로 가고 있는가"를 알려준다면, ATR은 "얼마나 거칠게 움직이고 있는가"를 알려줍니다.
트레이딩에서 수익을 결정하는 건 진입 타이밍만이 아닙니다. 얼마를 걸고, 어디서 끊느냐가 결과를 크게 좌우합니다. 그 판단을 감이 아닌 데이터로 하게 해주는 것이 ATR입니다. 화려한 지표는 아니지만, 실전에서는 가장 자주, 가장 폭넓게 쓰이는 지표 중 하나입니다.
ATR을 활용한 전략 중에는 가격이 전일 종가 ± N×ATR을 돌파하면 진입하는 ATR 브레이크아웃 같은 것도 있지만, 단독 전략으로 흔하게 쓰이지는 않습니다. 실전에서 ATR은 주로 다른 전략의 보조 도구로 활용됩니다. 이후 다른 전략을 다룰 때 ATR을 활용하는 예시를 함께 살펴볼 예정입니다.
본 포스팅은 지표의 원리와 백테스트 과정을 정리한 기술 블로그이며, 특정 자산의 매매를 권유하지 않습니다.
백테스트 결과는 과거 데이터 기반이며 실제 수익을 보장하지 않습니다. 모든 투자의 책임은 본인에게 있습니다.
'Development > Indicator Lab' 카테고리의 다른 글
| 돈치안 채널 (Donchian Channel) (0) | 2026.03.09 |
|---|---|
| 같은 전략, 다른 설정 — MA 크로스 통합 비교 (2) | 2026.03.08 |
| HMA (Hull Moving Average, 헐 이동평균) (0) | 2026.03.06 |
| DEMA & TEMA (이중/삼중 지수이동평균) (0) | 2026.03.05 |
| EMA (Exponential Moving Average, 지수이동평균) (0) | 2026.03.04 |