#공통 지표
Range Breakout은 트레이딩뷰의 BigBeluga라는 개발자가 만든 지표입니다.
이 지표는 가격 범위 내에서 저항수준 돌파나 지지수준 이탈과 같은
브레이크아웃 기회를 포착하기 위해 고안되 지표입니다.
ATR(변동성)을 이용해서 상단 밴드 / 하단 밴드 / 기준선(midline)을 만듭니다.
가격이 이 채널 안에서 움직일 때는 “박스(range)” 구간으로 보고,
박스의 폭은 시장 변동성(ATR)에 따라 자동 조정됩니다.
가격이 채널을 명확하게 돌파하거나,
혹은 일정 바 수(예: count == 100)가 지나면
그 시점의 HL2((고+저)/2)를 기준으로 새로운 채널을 다시 계산합니다.
그래서 현재 시장 상태에 맞는 “최신 박스”를 계속 유지하게 됩니다.
변동성이 크면 채널이 넓어지고, 작으면 채널이 좁아지는 형태입니다.
즉 가격이 어떤 박스(채널)를 형성한 뒤, 그 박스를 뚫고 나가는 구간과 되돌림,
페이크 브레이크까지 한 번에 보여주는 동적 채널/브레이크아웃 지표입니다.
// ===== 입력값 설정 =====
input : length(100); // 채널/평균 계산에 사용할 기본 길이
input : multi(4); // 채널 폭을 조절하는 배수
input : filter_sig(False); // 추세 필터 사용 여부 (True 시 추세 방향만 진입)
input : show_x(true); // 페이크아웃 신호(×) 표시 여부
input : color1(Green); // 상단 박스 및 매수 관련 색상
input : color3(Red); // 하단 박스 및 매도 관련 색상
input : color2(Black); // 예비 색상(현재 코드에서는 사용 안 함)
// ===== 변수 선언 =====
var : value(nan); // 기준 밴드(중심선) 값
var : value_upper(nan); // 상단 밴드 값
var : value_lower(nan); // 하단 밴드 값
var : value_upper_mid(nan); // 기준선과 상단 밴드의 중간 값
var : value_lower_mid(nan); // 기준선과 하단 밴드의 중간 값
var : trend(False); // 현재 추세 방향(예: True = 상승, False = 하락)
var : count(0),hl2(0); // count: 재계산 카운터, hl2: (고+저)/2
var : alpha(0),sum(0), A(0); // alpha: EMA 가중치, sum: TrueRange 지수평균, A: 채널 폭
var : cross_upper(False),cross_lower(False); // 상단/하단 밴드 돌파 여부
var : chage(False),buy_(false),sell_(False),fakeout_up(False),fakeout_dn(False);
// chage: 기준선 업데이트 여부 플래그
// buy_: 매수 신호
// sell_: 매도 신호
// fakeout_up: 상단 페이크아웃(가짜 돌파)
// fakeout_dn: 하단 페이크아웃(가짜 이탈)
var : upper_mid(0),lower_mid(0); // 상단/하단 박스의 중간값
var : upperbox(0),TL(0),lowerbox(0); // 그려지는 상단 박스, 중심 TL, 하단 박스 객체 핸들
// ===== 채널 폭 계산에 사용할 변수들 =====
alpha = 1/200; // TrueRange 평활화를 위한 EMA 가중치 설정
sum = iff(IsNaN(sum[1]) == true ,
ma(TrueRange, length) ,
alpha * TrueRange + (1 - alpha) * IFf(IsNaN(sum[1])==true,0,sum[1]));
// sum: TrueRange의 지수이동평균(초기에는 length 구간 단순 이동평균 사용)
A = ma(sum, 100) * multi; // sum의 이동평균에 multi를 곱해 채널 폭 A 산출
hl2 = (H+L)/2; // 현재 봉의 (고+저)/2 중앙값
// ===== 채널 초기화 (인덱스 301 봉에서 초기 기준 설정) =====
if index == 301 Then
{
value = hl2; // 기준선 = 현재 hl2
value_upper = hl2 + A; // 상단 밴드 = hl2 + A
value_lower = hl2 - A; // 하단 밴드 = hl2 - A
value_upper_mid = avg(value, value_upper); // 기준선과 상단 밴드 중간값
value_lower_mid = avg(value, value_lower); // 기준선과 하단 밴드 중간값
}
// ===== 밴드 돌파 체크 =====
cross_upper = CrossUp(low, value_upper); // 저가가 상단 밴드를 하향->상향으로 돌파했는지
cross_lower = CrossDown(high, value_lower); // 고가가 하단 밴드를 상향->하향으로 돌파했는지
// ===== 채널 밖에서 머무르는 카운트 =====
if low > value_upper or high < value_lower Then
count = count + 1; // 봉이 밴드 밖에 있으면 count 증가
// ===== 밴드 재계산 조건 (돌파 발생 또는 일정 봉 수 경과) =====
if cross_upper or cross_lower or count == 100 Then
{
count = 0; // 카운터 리셋
value = hl2; // 기준선 재설정
value_upper = hl2 + A; // 상단 밴드 재설정
value_lower = hl2 - A; // 하단 밴드 재설정
value_upper_mid = avg(value, value_upper); // 상단 중간선 재계산
value_lower_mid = avg(value, value_lower); // 하단 중간선 재계산
}
// ===== 기준선 고정 여부(업데이트 여부) 플래그 =====
chage = !(value != value[1]);
// value가 전 봉과 같으면 True (즉, 기준선이 고정된 상태일 때 True)
// ===== 매수/매도 및 페이크아웃 신호 정의 =====
buy_ = CrossUp(low, value_lower_mid) and low[10] > value_lower_mid and chage;
// 매수 신호:
// 1) 저가가 하단 중간선(value_lower_mid)을 상향 돌파
// 2) 10봉 전 저가가 여전히 하단 중간선 위에 있었음
// 3) 기준선이 고정(chage=True) 상태
sell_ = CrossDown(high, value_upper_mid) and high[10] < value_upper_mid and chage;
// 매도 신호:
// 1) 고가가 상단 중간선(value_upper_mid)을 하향 돌파
// 2) 10봉 전 고가가 상단 중간선 아래에 있었음
// 3) 기준선이 고정(chage=True) 상태
fakeout_up = CrossDown(high, value_upper) and chage;
// 상단 페이크아웃: 고가가 상단 밴드를 하향 재돌파(위로 살짝 뚫고 다시 내려오는 형태)
fakeout_dn = crossup(low, value_lower) and chage;
// 하단 페이크아웃: 저가가 하단 밴드를 상향 재돌파(밑으로 살짝 이탈 후 다시 올라오는 형태)
// ===== 박스(채널) 중간선 계산 =====
upper_mid = avg(value_upper, value); // 기준선과 상단 밴드 중간값
lower_mid = avg(value_lower, value); // 기준선과 하단 밴드 중간값
// ===== 채널/박스 및 TL 그리기 =====
if value_upper != value_upper[1] Then
{
// 기준선이 새로 설정된 시점에서 새로운 박스와 TL 생성
upperbox = Box_New(sDate,sTime,upper_mid,Sdate,sTime,value_upper); // 상단 박스 시작
Box_SetColor(upperbox,color1); // 상단 박스 색상
Box_SetFill(upperbox,true); // 상단 박스 채우기
TL = TL_new(sDate,sTime,value,sDate,sTime,value); // 기준선 TL 생성
TL_SetStyle(TL,3); // 기준선 스타일 (점선 등)
TL_SetColor(TL,Gray); // 기준선 색상
lowerbox = Box_New(sDate,sTime,lower_mid,Sdate,sTime,value_lower); // 하단 박스 시작
Box_SetColor(lowerbox,color3); // 하단 박스 색상
Box_SetFill(lowerbox,true); // 하단 박스 채우기
}
Else
{
// 기준선이 그대로일 때 기존 박스를 현재 봉까지 연장
Box_SetEnd(upperbox,sDate,sTime,value_upper); // 상단 박스 끝점을 현재 봉으로 연장
Box_SetEnd(lowerbox,sDate,sTime,value_lower); // 하단 박스 끝점을 현재 봉으로 연장
TL_SetEnd(TL,sdate,sTime,value); // 기준선 TL 끝점 연장
}
// ===== 텍스트 객체 핸들 =====
var : tx1(0),tx2(0),tx3(0); // tx1: 상/하단 돌파표시, tx2: 매수/매도 화살표, tx3: 페이크아웃 표시
// ===== 상단/하단 밴드 돌파 표시(⊙) =====
if cross_upper Then
{
trend = true; // 상단 돌파 발생 시 추세를 상승으로 표시
tx1 = Text_New(sDate[1],sTime[1],value_upper[1],"⊙"); // 상단 밴드 돌파 지점에 표시
Text_SetStyle(tx1,2,2);
Text_SetSize(tx1,20);
Text_SetColor(tx1,color1);
}
if cross_lower Then
{
tx1 = Text_New(sDate[1],sTime[1],value_lower[1],"⊙"); // 하단 밴드 돌파 지점에 표시
Text_SetStyle(tx1,2,2);
Text_SetSize(tx1,20);
Text_SetColor(tx1,color3);
}
// ===== 매수 신호(▲) 표시 =====
if buy_ and IFf(filter_sig , trend == true , true) Then
{
// filter_sig = True 이면 상승 추세(trend=True)에서만 매수 표시
tx2 = Text_New(sDate[1],sTime[1],L[1],"▲"); // 이전 봉 저가 부근에 ▲ 표시
Text_SetStyle(tx2,2,0);
Text_SetSize(tx2,20);
Text_SetColor(tx2,color1);
}
// ===== 매도 신호(▼) 표시 =====
if sell_ and IFf(filter_sig , trend == False , true) Then
{
// filter_sig = True 이면 하락 추세(trend=False)에서만 매도 표시
tx2 = Text_New(sDate[1],sTime[1],H[1],"▼"); // 이전 봉 고가 부근에 ▼ 표시
Text_SetStyle(tx2,2,1);
Text_SetSize(tx2,20);
Text_SetColor(tx2,color3);
}
// ===== 상단 페이크아웃 신호(×) 표시 =====
if fakeout_up and show_x Then
{
tx3 = Text_New(sDate[1],sTime[1],H[1],"×"); // 상단 페이크아웃 시 고가 부근에 × 표시
Text_SetStyle(tx3,2,1);
Text_SetSize(tx3,20);
Text_SetBold(tx3,1);
Text_SetColor(tx3,color3);
}
// ===== 하단 페이크아웃 신호(×) 표시 =====
if fakeout_dn and show_x Then
{
tx3 = Text_New(sDate[1],sTime[1],L[1],"×"); // 하단 페이크아웃 시 저가 부근에 × 표시
Text_SetStyle(tx3,2,0);
Text_SetSize(tx3,20);
Text_SetBold(tx3,1);
Text_SetColor(tx3,color1);
}
JavaScript
복사
