본문으로 바로가기
트레이더 스님 - 파인스크립트 전략 개발자

스퀴즈 모멘텀 완벽 가이드 | TTM Squeeze·Firing 신호·변동성 돌파 전략 2026 최신

파인스크립트

반응형

볼린저 밴드를 사용하다 보면 이런 경험이 있을 겁니다.

"스퀴즈 패턴은 확인했는데, 언제 돌파할지 모르겠어."
"밴드 터치했다고 매매했더니 거짓 신호였어."

스퀴즈 모멘텀 (Squeeze Momentum Indicator)은 이 문제를 해결하기 위해 존 카터(John Carter)가 개발한 고급 지표입니다.


볼린저 밴드만으로는 부족하다

볼린저 밴드는 훌륭한 지표지만, 치명적인 한계가 있습니다.

볼린저 밴드만으로는 부족하다 거짓 신호 거짓 신호 볼린저 밴드의 한계 1. 거짓 신호 빈번 • 밴드 터치만으로는 반전 확신 어려움 • 강한 추세에서 계속 밴드 타고 움직임 2. 타이밍 불명확 • 스퀴즈 후 언제 돌파할지 모름 • 어느 방향으로 갈지 예측 불가 3. 모멘텀 측정 없음 • 단순히 변동성만 측정 • 추세 강도를 알 수 없음 스퀴즈 모멘텀의 해결책 1. 스퀴즈 상태 명확화 • ON/OFF 상태를 점으로 표시 • Firing 신호로 돌파 시점 포착 2. 방향성 제공 • 모멘텀 히스토그램으로 방향 확인 • 색상 변화로 추세 강도 측정 3. 켈트너 채널 추가 • 2개 지표 조합으로 정확도 UP • ATR 기반으로 신뢰도 향상

볼린저 밴드의 3가지 한계

  1. 거짓 신호 빈번 - 밴드 터치만으로는 반전 확신 어려움
  2. 타이밍 불명확 - 스퀴즈 후 언제, 어느 방향으로 갈지 모름
  3. 모멘텀 측정 없음 - 단순히 변동성만 측정할 뿐 추세 강도는 알 수 없음

스퀴즈 모멘텀은 여기에 켈트너 채널모멘텀 히스토그램을 추가하여 이 문제들을 해결합니다.


켈트너 채널이란?

스퀴즈 모멘텀을 이해하려면 먼저 켈트너 채널을 알아야 합니다.

켈트너 채널 vs 볼린저 밴드 BB Upper KC Upper Basis (EMA) KC Lower BB Lower 볼린저 밴드 (BB) 계산 방식: 중심선: 20일 SMA 상단/하단: ± (표준편차 × 2) 특징: • 변동성에 따라 밴드 폭 변화 • 급등/급락 시 밴드 급격히 확장 • 표준편차 기반 (통계적) 장점: • 변동성 측정에 최적화 • 과매수/과매도 판단 켈트너 채널 (KC) 계산 방식: 중심선: 20일 EMA 상단/하단: ± (ATR × 승수) 특징: • ATR 기반으로 더 부드러움 • 밴드 폭 변화가 안정적 • 실제 가격 범위 반영 장점: • 추세 판단에 유리 • 거짓 신호 감소

켈트너 채널 vs 볼린저 밴드

구분 볼린저 밴드 (BB) 켈트너 채널 (KC)
중심선 20일 SMA 20일 EMA
상단/하단 ± (표준편차 × 2) ± (ATR × 1.5)
변동성 반응 급격히 확장/축소 부드럽게 변화
특징 변동성 측정 추세 판단

핵심 아이디어: 볼린저 밴드가 켈트너 채널 안으로 들어가면 변동성이 극도로 축소된 상태입니다.


스퀴즈의 4가지 상태

스퀴즈 모멘텀의 가장 큰 장점은 스퀴즈 상태를 명확히 구분한다는 것입니다.

스퀴즈 모멘텀의 4가지 상태 OFF ON Firing OFF Normal 상태: BB가 KC보다 넓음 의미: 정상 변동성 표시: 초록 빈 점 전략: 추세 추종 Squeeze ON 상태: BB가 KC 안쪽 의미: 변동성 축소 에너지 축적 중 표시: 빨간 점 전략: 대기, 돌파 준비 Firing 상태: 스퀴즈 해제 직후 BB가 KC 돌파 의미: 폭발 시작 표시: 초록 점 (처음) 전략: 진입 타이밍! Squeeze OFF 상태: BB가 KC보다 계속 넓음 의미: 추세 진행 중 표시: 초록 빈 점 전략: 추세 유지 핵심 포인트 1. Squeeze ON (빨간 점) → 볼린저 밴드가 켈트너 채널 안으로 들어감 = 변동성 극도로 축소 2. Firing (첫 번째 초록 점) → 스퀴즈 해제 직후 = 가장 중요한 진입 타이밍! 3. Squeeze OFF (초록 빈 점) → 정상 변동성 = 추세 추종 또는 관망

1. Normal (정상)

상태: BB가 KC보다 넓음
표시: 초록 빈 점
의미: 정상 변동성, 추세 진행 중
전략: 추세 추종

2. Squeeze ON (스퀴즈 발생)

상태: BB가 KC 안쪽에 있음
표시: 빨간 점
의미: 변동성 극도로 축소, 에너지 축적 중
전략: 대기, 돌파 준비

3. Firing (점화)

상태: 스퀴즈 해제 직후 (ON → OFF 전환)
표시: 첫 번째 초록 점
의미: 폭발 시작, 가장 중요한 신호
전략: 진입 타이밍!

4. Squeeze OFF (스퀴즈 해제)

상태: BB가 KC보다 계속 넓음
표시: 초록 빈 점
의미: 추세 진행 중
전략: 추세 유지

핵심: Firing 신호 (첫 번째 초록 점)가 가장 중요합니다. 이때가 진입 타이밍입니다.


모멘텀 히스토그램 색상 해석

스퀴즈 상태만으로는 방향을 알 수 없습니다. 모멘텀 히스토그램이 어느 방향으로 갈지 알려줍니다.

모멘텀 히스토그램 색상 해석 0 Cyan 하락 약화 Light Green 상승 시작 Dark Green 강한 상승 Light Green 상승 약화 Light Red 하락 시작 Dark Red 강한 하락 Light Red 하락 약화 양수 모멘텀 (상승) Dark Green (진한 초록) • 강한 상승 모멘텀 • 막대가 길고 색이 진함 → 매수 유지, 추격 매수 Light Green (연한 초록) • 상승 모멘텀 약화 • 막대가 짧아지거나 색이 연함 → 청산 고려, 신규 진입 자제 Cyan (청록) • 하락 모멘텀 약화 • 음수지만 0으로 수렴 중 → 반등 준비, 매수 대기 Cyan → Green 전환 시 매수 음수 모멘텀 (하락) Dark Red (진한 빨강) • 강한 하락 모멘텀 • 막대가 길고 색이 진함 → 관망, 숏 포지션 유지 Light Red (연한 빨강) • 하락 모멘텀 약화 • 막대가 짧아지거나 색이 연함 → 숏 청산 고려 색상 전환 시점 • Red → Cyan: 하락 → 반등 • Cyan → Green: 반등 → 상승 • Green → Red: 상승 → 하락 색상 전환 = 추세 전환 신호 실전 활용 팁 1. 색상 변화 주시 막대 색이 진해지면 추세 강화 막대 색이 연해지면 추세 약화 2. 막대 길이 확인 긴 막대 = 강한 모멘텀 짧은 막대 = 약한 모멘텀 3. 0선 교차 관찰 음수 → 양수: 추세 전환 양수 → 음수: 추세 전환 4. Squeeze와 조합 Firing + Dark Green = 최고의 매수 타이밍

양수 모멘텀 (상승)

  • Dark Green (진한 초록) - 강한 상승 모멘텀, 매수 유지
  • Light Green (연한 초록) - 상승 모멘텀 약화, 청산 고려

음수 모멘텀 (하락)

  • Dark Red (진한 빨강) - 강한 하락 모멘텀, 관망
  • Light Red (연한 빨강) - 하락 모멘텀 약화, 숏 청산
  • Cyan (청록) - 하락 약화 중, 반등 준비

색상 전환의 의미

  • Red → Cyan: 하락 → 반등 시작
  • Cyan → Green: 반등 → 상승 전환 (매수 타이밍)
  • Dark Green → Light Green: 상승 약화 (청산 고려)
  • Green → Red: 상승 → 하락 전환 (매도 타이밍)

실전 진입 & 청산 타이밍

이론은 충분합니다. 실전에서 어떻게 매매하는지 보겠습니다.

실전 진입 & 청산 타이밍 매수 진입 청산 Firing 매수 진입 조건 1. Squeeze ON 상태 확인 (빨간 점) → 최소 3~4개 이상의 빨간 점 필요 2. Firing 신호 발생 (첫 초록 점) → 스퀴즈 해제 직후 3. 모멘텀 히스토그램 양수 + Green → 상승 방향 확인 청산 조건 1. 모멘텀 색상이 Light Green으로 변함 → 상승 모멘텀 약화 시작 2. 모멘텀이 0선 하향 돌파 → 추세 전환 신호 3. 또는 목표가 도달 → 스퀴즈 해제 후 평균 10~20% 수익

매수 진입 조건 (3가지 모두 충족)

  1. Squeeze ON 상태 확인 (빨간 점 3~4개 이상)
  2. Firing 신호 발생 (첫 번째 초록 점)
  3. 모멘텀 히스토그램 양수 + Green (상승 방향 확인)

청산 조건 (하나라도 충족 시)

  1. 모멘텀 색상이 Light Green으로 변함 (상승 약화)
  2. 모멘텀이 0선 하향 돌파 (추세 전환)
  3. 목표가 도달 (스퀴즈 해제 후 평균 10~20% 수익)

매도 진입 조건 (숏 포지션)

  1. Squeeze ON 상태 확인
  2. Firing 신호 발생
  3. 모멘텀 히스토그램 음수 + Red (하락 방향 확인)

Pine Script v5 코드

실제로 트레이딩뷰에서 사용할 수 있는 파인스크립트 코드입니다.

Pine Script v5 코드 미리보기 SqueezeMomentum.pine 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // TTM Squeeze Momentum Indicator //@version=5 indicator("Squeeze Momentum") // Bollinger Bands basis = ta.sma(close, 20) dev = ta.stdev(close, 20) * 2.0 // Keltner Channel kcBasis = ta.ema(close, 20) atrValue = ta.atr(20) * 1.5 // Squeeze Detection upperBB = basis + dev lowerBB = basis - dev upperKC = kcBasis + atrValue lowerKC = kcBasis - atrValue sqzOn = lowerBB > lowerKC and upperBB < upperKC sqzOff = lowerBB < lowerKC and upperBB > upperKC

주요 기능:

  • 볼린저 밴드 + 켈트너 채널 자동 계산
  • 스퀴즈 ON/OFF 상태 점으로 표시
  • Firing 신호 라벨 자동 표시
  • 모멘텀 히스토그램 5가지 색상 자동 변경
  • 선형 회귀 기반 모멘텀 계산
  • 알림(Alert) 기능 내장
  • 우측 상단 정보 테이블
// This Pine Script code is subject to the terms of the Mozilla Public License 2.0
// trader-min.tistory.com
// Based on TTM Squeeze by John Carter

//@version=5
indicator("Squeeze Momentum", shorttitle="Squeeze", overlay=false)

// ========== INPUTS ==========
length = input.int(20, "Length", minval=1, tooltip="BB and KC period")
bbMult = input.float(2.0, "BB Mult", minval=0.1, step=0.1)
kcMult = input.float(1.5, "KC Mult", minval=0.1, step=0.1)

momLength = input.int(20, "Momentum Length", minval=1, group="Momentum")
momSource = input.source(close, "Momentum Source", group="Momentum")

// Colors
sqzOnColor = input.color(color.new(#ff6b6b, 0), "Squeeze ON", group="Colors")
sqzOffColor = input.color(color.new(#00d26a, 0), "Squeeze OFF", group="Colors")
darkGreen = input.color(color.new(#00c853, 0), "Dark Green", group="Colors")
lightGreen = input.color(color.new(#69f0ae, 0), "Light Green", group="Colors")
cyanCol = input.color(color.new(#00d9ff, 0), "Cyan", group="Colors")
lightRed = input.color(color.new(#ff8a80, 0), "Light Red", group="Colors")
darkRed = input.color(color.new(#ff5252, 0), "Dark Red", group="Colors")

// Display
showLabels = input.bool(true, "Show Firing Labels", group="Display")
enableAlerts = input.bool(true, "Enable Alerts", group="Alerts")

// ========== BOLLINGER BANDS ==========
basis = ta.sma(momSource, length)
dev = bbMult * ta.stdev(momSource, length)
upperBB = basis + dev
lowerBB = basis - dev

// ========== KELTNER CHANNEL ==========
kcBasis = ta.ema(momSource, length)
atrValue = ta.atr(length)
upperKC = kcBasis + (kcMult * atrValue)
lowerKC = kcBasis - (kcMult * atrValue)

// ========== SQUEEZE DETECTION ==========
sqzOn = (lowerBB > lowerKC) and (upperBB < upperKC)
sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC)
noSqz = not sqzOn and not sqzOff

wasSqzOn = sqzOn[1]
firing = not sqzOn and wasSqzOn

// ========== MOMENTUM ==========
highestVal = ta.highest(high, momLength)
lowestVal = ta.lowest(low, momLength)
avgHL = (highestVal + lowestVal) / 2
momentum = ta.linreg(momSource - avgHL, momLength, 0)

momUp = momentum > momentum[1]
momDown = momentum < momentum[1]

// ========== COLORS ==========
posDarkGreen = momentum > 0 and momUp
posLightGreen = momentum > 0 and momDown
negCyan = momentum < 0 and momUp
negLightRed = momentum < 0 and momDown and momentum > momentum[2]
negDarkRed = momentum < 0 and momDown and momentum <= momentum[2]

momColor = posDarkGreen ? darkGreen : posLightGreen ? lightGreen : negCyan ? cyanCol : negLightRed ? lightRed : negDarkRed ? darkRed : color.gray

// ========== PLOTS ==========
plot(momentum, "Momentum", color=momColor, style=plot.style_histogram, linewidth=4)
hline(0, "Zero", color=color.new(color.gray, 50), linewidth=2)

sqzColor = sqzOn ? sqzOnColor : sqzOff ? sqzOffColor : color.gray
plotshape(true, "Squeeze", location=location.top, style=shape.circle, color=sqzColor, size=size.tiny)

if showLabels and firing
    label.new(bar_index, momentum, "FIRE", color=sqzOffColor, textcolor=color.white, style=label.style_label_down, size=size.small)

// ========== ALERTS ==========
if enableAlerts and sqzOn and not sqzOn[1]
    alert("Squeeze ON", alert.freq_once_per_bar_close)

if enableAlerts and firing
    alert("Firing", alert.freq_once_per_bar_close)

if enableAlerts and momentum > 0 and momentum[1] <= 0
    alert("Momentum Bullish", alert.freq_once_per_bar_close)

if enableAlerts and momentum < 0 and momentum[1] >= 0
    alert("Momentum Bearish", alert.freq_once_per_bar_close)

// ========== INFO TABLE ==========
var table infoTable = table.new(position.top_right, 2, 6, bgcolor=color.new(color.black, 85), border_width=1)

if barstate.islast
    table.cell(infoTable, 0, 0, "Squeeze", text_color=color.white, text_size=size.normal)
    sqzText = sqzOn ? "ON" : sqzOff ? "OFF" : "-"
    table.cell(infoTable, 1, 0, sqzText, text_color=sqzOn ? sqzOnColor : sqzOff ? sqzOffColor : color.gray, text_size=size.normal)

    table.cell(infoTable, 0, 1, "Momentum", text_color=color.white, text_size=size.small)
    table.cell(infoTable, 1, 1, str.tostring(momentum, "#.####"), text_color=momColor, text_size=size.small)

    table.cell(infoTable, 0, 2, "Direction", text_color=color.white, text_size=size.small)
    dirText = momentum > 0 ? "UP" : momentum < 0 ? "DOWN" : "FLAT"
    table.cell(infoTable, 1, 2, dirText, text_color=momentum > 0 ? darkGreen : momentum < 0 ? darkRed : color.gray, text_size=size.small)

    table.cell(infoTable, 0, 3, "Strength", text_color=color.white, text_size=size.small)
    strText = momUp ? "INC" : momDown ? "DEC" : "HOLD"
    table.cell(infoTable, 1, 3, strText, text_color=momUp ? darkGreen : momDown ? darkRed : color.gray, text_size=size.small)

    table.cell(infoTable, 0, 4, "Color", text_color=color.white, text_size=size.small)
    colName = posDarkGreen ? "DarkGreen" : posLightGreen ? "LightGreen" : negCyan ? "Cyan" : negLightRed ? "LightRed" : negDarkRed ? "DarkRed" : "Gray"
    table.cell(infoTable, 1, 4, colName, text_color=momColor, text_size=size.small)

    table.cell(infoTable, 0, 5, "Settings", text_color=color.white, text_size=size.small)
    table.cell(infoTable, 1, 5, str.tostring(length) + "/" + str.tostring(bbMult, "#.#") + "/" + str.tostring(kcMult, "#.#"), text_color=color.gray, text_size=size.small)

사용 방법

  1. 트레이딩뷰 Pine Editor 열기
  2. 위 코드 복사 → 붙여넣기
  3. Add to chart 클릭
  4. 설정에서 BB 승수, KC 승수 조절
  5. 색상 및 표시 옵션 설정

스퀴즈 모멘텀 실전 시나리오

시나리오 1: 상승 돌파

  1. 빨간 점 4개 확인 (스퀴즈 진행 중)
  2. 첫 번째 초록 점 발생 (Firing)
  3. 모멘텀 Dark Green 전환 → 매수 진입
  4. Light Green 전환 시 → 청산

시나리오 2: 하락 돌파

  1. 빨간 점 4개 확인
  2. 첫 번째 초록 점 발생
  3. 모멘텀 Dark Red 전환 → 관망 또는 숏
  4. Cyan 전환 시 → 숏 청산

시나리오 3: 거짓 신호 회피

  1. 빨간 점이 1~2개만 나타남 → 스퀴즈 불충분, 진입 자제
  2. Firing 후 모멘텀이 0선 근처 횡보 → 방향 불명확, 대기
  3. Light Green 또는 Light Red 색상 → 약한 모멘텀, 진입 자제

볼린저 밴드와의 차이점

구분 볼린저 밴드 스퀴즈 모멘텀
스퀴즈 확인 육안으로 판단 점으로 명확히 표시
돌파 시점 불명확 Firing 신호로 명확
방향 판단 없음 모멘텀 색상으로 확인
거짓 신호 빈번 2중 필터로 감소
추세 강도 측정 불가 색상으로 측정

주의사항

스퀴즈 모멘텀도 완벽하지 않습니다.

  • 스퀴즈가 짧으면 효과 감소: 빨간 점이 3개 이상 나와야 신뢰도 높음
  • 횡보장에서 무력화: 방향성 없는 시장에서는 Firing 후에도 횡보 가능
  • 모멘텀 약할 때 진입 자제: Light Green/Light Red 색상일 때는 신규 진입 자제
  • 단독 사용 지양: RSI, 이동평균선 등 다른 지표와 함께 사용
  • 손절선 필수: 모든 신호에 대해 손절선 설정 필요

가장 중요한 것: 자금 관리와 손절 규칙입니다.


마무리

스퀴즈 모멘텀은 볼린저 밴드의 약점을 보완한 고급 지표입니다.

스퀴즈 모멘텀을 배워야 하는 이유:

  • 스퀴즈 상태를 명확히 구분 (ON/OFF/Firing)
  • 돌파 타이밍을 정확히 포착 (Firing 신호)
  • 방향과 강도를 동시에 측정 (색상 변화)
  • 2중 필터로 거짓 신호 감소
  • 볼린저 밴드를 이미 사용 중이라면 쉽게 적응 가능

오늘 배운 내용을 바탕으로 직접 트레이딩뷰에서 테스트해보세요!


더 궁금한 점이 있으시다면 댓글로 남겨주세요.

맞춤형 스퀴즈 모멘텀 전략이나 자동매매 시스템이 필요하시면
크몽에서 문의해 주세요.

반응형
TODAY
TOTAL
트레이더 스님
트레이더 스님

파인스크립트 전략가

크몽에서 만나기