콘텐츠로 이동
3 posts with the tag “변동성”

기술적 분석 5장: 볼린저 밴드 하단 돌파의 효과

볼린저 밴드 분석

3장의 RSI 회복과 이번 볼린저 하단 반등은 모두 “많이 하락했으니 되돌아오지 않을까?”라는 평균회귀 가설에서 출발합니다. RSI 회복은 20일 중앙값 -0.91%였고, 이번 장에서는 가격이 밴드 안으로 돌아온 사건도 같은 약점을 보이는지 확인합니다.

볼린저 밴드 하단에 닿으면 주가가 싸졌다고 생각하기 쉽습니다. 그러나 하단 밴드를 따라 내려가는 강한 하락 추세에서는 하단 접촉만으로 반등을 예측할 수 없습니다. 이번 글에서는 전일 종가가 하단 밴드 아래였고 당일 종가가 다시 밴드 안으로 들어온 경우를 반등 신호로 정의했습니다.

g = df.sort_values(["code", "date"]).copy()
g["bb_middle"] = g.groupby("code")["close"].transform(
lambda x: x.rolling(20).mean()
)
std20 = g.groupby("code")["close"].transform(lambda x: x.rolling(20).std())
g["bb_upper"] = g["bb_middle"] + 2 * std20
g["bb_lower"] = g["bb_middle"] - 2 * std20
previous_close = g.groupby("code")["close"].shift(1)
previous_lower = g.groupby("code")["bb_lower"].shift(1)
g["bb_rebound"] = (previous_close <= previous_lower) & (
g["close"] > g["bb_lower"]
)

검증 구간에서 볼린저 하단 반등은 1,015회 발생했습니다.

신호발생 횟수20일 양수 비율평균 수익률중앙값
볼린저 하단 반등1,015회49.4%+4.94%-0.27%

평균은 +4.94%였지만 중앙값은 -0.27%, 양수 비율은 49.4%였습니다. 25% 분위수도 -13.11%였습니다. 일부 큰 반등 사례가 평균을 높였지만, 절반 이상의 전형적인 사례가 안정적인 수익으로 이어졌다고 보기는 어렵습니다. RSI 회복의 평균 +2.14%보다 높아 보이지만, 중앙값과 양수 비율은 모두 약해 평균 차이만으로 우위를 주장할 수 없습니다.

이번 결과에서 볼린저 밴드는 가격의 절대적인 고평가·저평가를 알려주는 지표가 아니라, 최근 20일 가격 분포에서 현재 위치가 어디인지 보여주는 변동성 도구로 해석해야 합니다. 밴드 안으로 복귀했다는 사건만으로는 추세가 끝났다는 증거가 부족합니다.

따라서 하단 반등 신호를 사용할 때는 다음을 추가해야 합니다.

  • 밴드 폭이 줄어들고 있는가
  • 거래량이 동반되었는가
  • 종가가 MA20을 회복했는가
  • 시장과 산업 지수가 상승 중인가

하단 밴드에 닿았다는 이유만으로 매수하면 “싼 가격”이 아니라 “하락 중인 가격”을 매수하게 될 수 있습니다. 위 조건들은 개선 가능성을 제시할 뿐, 이 장에서 추가 검증한 결과는 아닙니다. 다음 장에서는 평균회귀 신호의 손실 폭을 변동성에 맞춰 관리하는 ATR을 확인합니다.

결과는 신호별 결과 CSV에 공개했습니다.

기술적 분석 6장: ATR로 손절선 최적화

ATR과 변동성 분석

저변동성 대형주와 변동성이 큰 바이오주에 똑같이 -7% 손절선을 적용하면 어떤 종목에는 너무 좁고, 다른 종목에는 너무 넓을 수 있습니다. ATR은 최근 가격 범위를 이용해 종목별 변동성을 비교하는 방법입니다.

previous_close = df.groupby("code")["close"].shift(1)
true_range = pd.concat(
[
df["high"] - df["low"],
(df["high"] - previous_close).abs(),
(df["low"] - previous_close).abs(),
],
axis=1,
).max(axis=1)
df["true_range"] = true_range
df["atr14_pct"] = df.groupby("code")["true_range"].transform(
lambda x: x.rolling(14).mean()
) / df["close"]

실제 공개 코드에서는 종목별 그룹 안에서 True Range를 계산합니다. atr14_pct는 ATR을 현재 가격으로 나눈 값이므로 종목 가격이 달라도 변동성을 비교할 수 있습니다.

복합 신호를 변동성별로 나누기

섹션 제목: “복합 신호를 변동성별로 나누기”

MA20·MA60·RSI·MACD·거래량 조건을 동시에 만족한 진입 신호 중 20일 이후 수익률을 계산할 수 있는 1,601건을 ATR 기준 세 그룹으로 나누었습니다. 각 그룹의 실제 20일 결과는 다음과 같습니다.

변동성 그룹신호 수평균 ATR14/가격양수 비율평균 수익률중앙값
낮은 변동성5344.08%59.4%+7.73%+3.76%
중간 변동성5336.41%53.7%+9.00%+2.24%
높은 변동성53410.01%47.0%+4.36%-1.83%

평균 수익률만 보면 중간 변동성이 가장 높습니다. 그러나 낮은 변동성 그룹의 양수 비율은 59.4%, 중앙값은 +3.76%로 가장 안정적이었습니다. 높은 변동성 그룹은 평균이 +4.36%였지만 양수 비율은 47.0%, 중앙값은 -1.83%였습니다.

ATR은 매수 신호가 아니라 포지션 크기와 손절 폭을 정하는 도구입니다.

target_risk = 100_000
stop_distance = df["atr14_pct"] * df["close"] * 2
df["shares"] = (target_risk / stop_distance).fillna(0).astype(int)

이번 결과에서 중요한 것은 평균수익률 1위인 중간 변동성 그룹을 그대로 고르는 것이 아닙니다. 낮은 변동성은 양수 비율과 중앙값이 좋았고, 중간 변동성은 평균만 높았으며, 높은 변동성은 전형적인 결과가 손실이었습니다. 변동성이 높은 종목을 무조건 제외할 필요는 없지만, 같은 금액을 매수하지 않고 손실 금액이 일정하도록 수량을 조절해야 합니다. ATR은 매수 신호를 강화하는 지표가 아니라, 신호를 실행할 때 위험을 먼저 제한하는 도구입니다.

다음 장에서는 가격이 MA20 위에 있다는 조건에 OBV를 추가했을 때 거래량 확인이 실제로 수익률의 일관성을 높이는지 살펴봅니다.

원자료는 변동성 그룹 결과에서 확인할 수 있습니다.

ETF 상관계수만으로 분산효과를 판단하면 안 되는 이유

서로 다른 자산의 움직임과 상관관계를 표현한 연구 공간

ETF를 여러 개 담으면 포트폴리오가 자동으로 안전해질까요? 흔히 ETF 사이의 상관계수가 낮으면 분산효과가 크다고 설명합니다. 방향은 맞지만, 상관계수 하나만으로 실제 위험을 판단하기에는 부족합니다. 평소에는 서로 다르게 움직이던 자산도 시장 충격이 발생하면 함께 하락할 수 있기 때문입니다.

이 글에서는 상관계수의 의미와 한계를 살펴보고, ETF 포트폴리오를 구성할 때 함께 확인해야 할 지표를 정리합니다.

두 ETF의 수익률을 , 라고 할 때 피어슨 상관계수는 다음과 같이 계산합니다.

값이 1에 가까우면 같은 방향으로, -1에 가까우면 반대 방향으로 움직이는 경향이 있다는 뜻입니다. 0에 가까우면 선형적인 동조화가 뚜렷하지 않습니다.

문제는 이 값이 어떤 기간과 수익률 간격을 사용했는지에 따라 달라진다는 점입니다. 일간 수익률로 계산한 상관계수와 월간 수익률로 계산한 상관계수는 서로 다를 수 있습니다. 상승장, 하락장, 금리 변동기처럼 시장 국면을 나누면 결과가 더 크게 달라질 수 있습니다.

낮은 상관계수가 항상 낮은 위험은 아니다

섹션 제목: “낮은 상관계수가 항상 낮은 위험은 아니다”

포트폴리오의 분산은 각 자산의 변동성과 자산 사이의 공분산에 의해 결정됩니다.

따라서 상관계수는 중요한 요소이지만 전체가 아닙니다. 상관계수가 낮아도 한 자산의 변동성이 매우 크면 포트폴리오 위험이 커질 수 있습니다. 반대로 상관계수가 다소 높더라도 변동성이 낮고 비중이 적절하면 전체 변동성을 완화할 수 있습니다.

예를 들어 주식 ETF와 원자재 ETF를 섞었다고 해도, 두 상품의 가격 변동폭과 환율 민감도가 크게 다르면 단순 상관계수만으로 체감 위험을 설명하기 어렵습니다. ETF의 기초자산뿐 아니라 환헤지 여부, 선물 롤오버, 분배금 정책도 함께 봐야 합니다.

위기 때 상관관계가 높아지는 현상

섹션 제목: “위기 때 상관관계가 높아지는 현상”

평상시에는 서로 다른 자산군으로 보이던 상품이 급락장에서 동시에 하락하는 현상을 흔히 관찰할 수 있습니다. 투자자가 위험자산을 한꺼번에 줄이거나, 유동성이 낮은 자산부터 매도하기 때문입니다.

이런 현상을 확인하려면 전체 기간의 상관계수 하나보다 다음 결과를 나누어 보는 편이 낫습니다.

  • 전체 기간의 상관계수
  • 하락한 날만 추린 하방 상관계수
  • 최근 60일 또는 120일 이동 상관계수
  • 두 ETF가 같은 날 손실을 기록한 비율
  • 포트폴리오의 최대낙폭과 회복 기간

특히 하방 상관계수가 전체 상관계수보다 높다면, 평소에는 분산되어 보여도 손실이 커지는 시점에 함께 움직일 가능성을 경계해야 합니다.

ETF 분산효과를 확인하는 실전 순서

섹션 제목: “ETF 분산효과를 확인하는 실전 순서”

먼저 비교할 ETF의 총수익률 기준을 통일해야 합니다. 분배금을 제외한 가격 수익률만 비교하면 실제 투자자가 경험하는 결과와 차이가 생길 수 있습니다. 그다음 동일한 기간과 빈도의 수익률로 상관계수와 변동성을 계산합니다.

returns = prices.pct_change().dropna()
summary = returns[['etf_a', 'etf_b', 'etf_c']].agg(['mean', 'std'])
correlation = returns[['etf_a', 'etf_b', 'etf_c']].corr()
downside_correlation = returns[returns[['etf_a', 'etf_b', 'etf_c']].min(axis=1) < 0].corr()

마지막으로 동일한 비중을 가정한 포트폴리오 수익률을 계산하고, 월별 또는 분기별 리밸런싱을 적용해 결과가 어떻게 바뀌는지 확인합니다. 상관계수가 낮더라도 한 상품이 계속 상승해 비중이 커지면, 시간이 지나면서 포트폴리오의 위험 구조가 달라질 수 있습니다.

상관계수 외에 확인할 체크리스트

섹션 제목: “상관계수 외에 확인할 체크리스트”
  • 기초자산과 지역이 실제로 얼마나 겹치는가
  • 상위 보유종목의 중복 비중은 얼마인가
  • 환율과 환헤지 여부가 성과에 어떤 영향을 주는가
  • 하락장에서 동시 손실 빈도는 어느 정도인가
  • 최대낙폭과 회복 기간이 감당 가능한 수준인가
  • 거래량과 스프레드가 리밸런싱 비용을 키우지 않는가

ETF 이름이 다르거나 운용사가 달라도 상위 보유종목이 비슷하면 실질적인 분산효과는 작을 수 있습니다. 반대로 상관계수가 낮아 보이는 상품도 구조가 복잡하거나 거래비용이 크면 장기 보유에 적합하지 않을 수 있습니다.

상관계수는 ETF 포트폴리오를 분석하는 좋은 출발점이지만, 분산효과의 최종 답은 아닙니다. 기간과 수익률 빈도를 바꾸어도 결과가 유지되는지 확인하고, 하락장 상관관계·변동성·최대낙폭·보유종목 중복도를 함께 살펴야 합니다.

좋은 분산 포트폴리오는 단순히 서로 다른 이름의 ETF를 모은 포트폴리오가 아닙니다. 손실이 커지는 국면에서 위험이 어떻게 겹치는지 설명할 수 있는 포트폴리오에 가깝습니다.

이 글은 ETF와 포트폴리오 분석 방법을 설명하기 위한 자료이며, 특정 상품의 매수·매도를 권유하지 않습니다.