OPEN-SOURCE SCRIPT

jaems_Double BB[Alert]/W-Bottom/Dashboard

85
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org/MPL/2.0/
// © Kingjmaes

//version=6
strategy("jaems_Double BB[Alert]/W-Bottom/Dashboard", shorttitle="jaems_Double BB[Alert]/W-Bottom/Dashboard", overlay=true, commission_type=strategy.commission.percent, commission_value=0.05, slippage=1, process_orders_on_close=true)

// ==========================================
// 1. 사용자 입력 (Inputs)
// ==========================================
group_date = "📅 백테스트 기간 설정"
startTime = input.time(timestamp("2024-01-01 00:00"), "시작일", group=group_date)
endTime = input.time(timestamp("2099-12-31 23:59"), "종료일", group=group_date)

group_bb = "📊 더블 볼린저 밴드 설정"
bb_len = input.int(20, "길이 (Length)", minval=5, group=group_bb)
bb_mult_inner = input.float(1.0, "내부 밴드 승수 (Inner A)", step=0.1, group=group_bb)
bb_mult_outer = input.float(2.0, "외부 밴드 승수 (Outer B)", step=0.1, group=group_bb)

group_w = "📉 W 바닥 패턴 설정"
pivot_left = input.int(3, "피벗 좌측 봉 수", minval=1, group=group_w)
pivot_right = input.int(1, "피벗 우측 봉 수", minval=1, group=group_w)

group_dash = "🖥️ 대시보드 설정"
show_dash = input.bool(true, "대시보드 표시", group=group_dash)
comp_sym = input.symbol("NASDAQ:NDX", "비교 지수 (GS Trend)", group=group_dash, tooltip="S&P500은 'SP:SPX', 비트코인은 'BINANCE:BTCUSDT' 등을 입력하세요.")
rsi_len = input.int(14, "RSI 길이", group=group_dash)

group_risk = "🛡 리스크 관리"
use_sl_tp = input.bool(true, "손절/익절 사용", group=group_risk)
sl_pct = input.float(2.0, "손절매 (%)", step=0.1, group=group_risk) / 100
tp_pct = input.float(4.0, "익절매 (%)", step=0.1, group=group_risk) / 100

// ==========================================
// 2. 데이터 처리 및 계산 (Calculations)
// ==========================================
// 기간 필터
inDateRange = time >= startTime and time <= endTime

// [지표 1] 더블 볼린저 밴드
basis = ta.sma(close, bb_len)
dev_inner = ta.stdev(close, bb_len) * bb_mult_inner
dev_outer = ta.stdev(close, bb_len) * bb_mult_outer

upper_A = basis + dev_inner
lower_A = basis - dev_inner
upper_B = basis + dev_outer
lower_B = basis - dev_outer
percent_b = (close - lower_B) / (upper_B - lower_B)

// [지표 2] W 바닥형 (W-Bottom) - 리페인팅 방지
pl = ta.pivotlow(low, pivot_left, pivot_right)
var float p1_price = na
var float p1_pb = na
var float p2_price = na
var float p2_pb = na
var bool is_w_setup = false

if not na(pl)
p1_price := p2_price
p1_pb := p2_pb
p2_price := low[pivot_right]
p2_pb := percent_b[pivot_right]

// 패턴 감지
bool cond_w = (p1_price < lower_B[pivot_right]) and (p2_price > p1_price) and (p2_pb > p1_pb)
is_w_setup := cond_w ? true : false

w_bottom_signal = is_w_setup and close > open and close > lower_A
if w_bottom_signal
is_w_setup := false

// [지표 3] GS 트렌드 (나스닥 상대 강도)
ndx_close = request.security(comp_sym, timeframe.period, close)
rs_ratio = close / ndx_close
rs_sma = ta.sma(rs_ratio, 20)
gs_trend_bull = rs_ratio > rs_sma

// [지표 4] RSI & MACD
rsi_val = ta.rsi(close, rsi_len)
[macd_line, signal_line, _] = ta.macd(close, 12, 26, 9)
macd_bull = macd_line > signal_line

// ==========================================
// 3. 전략 로직 (Strategy Logic)
// ==========================================
long_cond = (ta.crossover(close, lower_A) or ta.crossover(close, basis) or w_bottom_signal) and inDateRange and barstate.isconfirmed
short_cond = (ta.crossunder(close, upper_B) or ta.crossunder(close, upper_A) or ta.crossunder(close, basis)) and inDateRange and barstate.isconfirmed

// 진입 실행 및 알람 발송
if long_cond
strategy.entry("Long", strategy.long, comment="Entry Long")
alert("Long Entry Triggered | Price: " + str.tostring(close), alert.freq_once_per_bar_close)

if short_cond
strategy.entry("Short", strategy.short, comment="Entry Short")
alert("Short Entry Triggered | Price: " + str.tostring(close), alert.freq_once_per_bar_close)

// 청산 실행
if use_sl_tp
if strategy.position_size > 0
strategy.exit("Exit Long", "Long", stop=strategy.position_avg_price * (1 - sl_pct), limit=strategy.position_avg_price * (1 + tp_pct), comment_loss="L-SL", comment_profit="L-TP")
if strategy.position_size < 0
strategy.exit("Exit Short", "Short", stop=strategy.position_avg_price * (1 + sl_pct), limit=strategy.position_avg_price * (1 - tp_pct), comment_loss="S-SL", comment_profit="S-TP")

// 별도 알람: W 패턴 감지 시
if w_bottom_signal
alert("W-Bottom Pattern Detected!", alert.freq_once_per_bar_close)

// ==========================================
// 4. 대시보드 시각화 (Dashboard Visualization)
// ==========================================
c_bg_head = color.new(color.black, 20)
c_bg_cell = color.new(color.black, 40)
c_text = color.white
c_bull = color.new(#00E676, 0)
c_bear = color.new(#FF5252, 0)
c_neu = color.new(color.gray, 30)

get_trend_color(is_bull) => is_bull ? c_bull : c_bear
get_pos_text() => strategy.position_size > 0 ? "LONG 🟢" : strategy.position_size < 0 ? "SHORT 🔴" : "FLAT ⚪"
get_pos_color() => strategy.position_size > 0 ? c_bull : strategy.position_size < 0 ? c_bear : c_neu

var table dash = table.new(position.top_right, 2, 7, border_width=1, border_color=color.gray, frame_color=color.gray, frame_width=1)

if show_dash and (barstate.islast or barstate.islastconfirmedhistory)
table.cell(dash, 0, 0, "METRIC", bgcolor=c_bg_head, text_color=c_text, text_size=size.small)
table.cell(dash, 1, 0, "STATUS", bgcolor=c_bg_head, text_color=c_text, text_size=size.small)

table.cell(dash, 0, 1, "GS Trend", bgcolor=c_bg_cell, text_color=c_text, text_halign=text.align_left, text_size=size.small)
table.cell(dash, 1, 1, gs_trend_bull ? "Bullish" : "Bearish", bgcolor=c_bg_cell, text_color=get_trend_color(gs_trend_bull), text_size=size.small)

rsi_col = rsi_val > 70 ? c_bear : rsi_val < 30 ? c_bull : c_neu
table.cell(dash, 0, 2, "RSI (14)", bgcolor=c_bg_cell, text_color=c_text, text_halign=text.align_left, text_size=size.small)
table.cell(dash, 1, 2, str.tostring(rsi_val, "#.##"), bgcolor=c_bg_cell, text_color=rsi_col, text_size=size.small)

table.cell(dash, 0, 3, "MACD", bgcolor=c_bg_cell, text_color=c_text, text_halign=text.align_left, text_size=size.small)
table.cell(dash, 1, 3, macd_bull ? "Bullish" : "Bearish", bgcolor=c_bg_cell, text_color=get_trend_color(macd_bull), text_size=size.small)

w_status = w_bottom_signal ? "DETECTED!" : is_w_setup ? "Setup Ready" : "Waiting"
w_col = w_bottom_signal ? c_bull : is_w_setup ? color.yellow : c_neu
table.cell(dash, 0, 4, "W-Bottoms", bgcolor=c_bg_cell, text_color=c_text, text_halign=text.align_left, text_size=size.small)
table.cell(dash, 1, 4, w_status, bgcolor=c_bg_cell, text_color=w_col, text_size=size.small)

table.cell(dash, 0, 5, "Position", bgcolor=c_bg_cell, text_color=c_text, text_halign=text.align_left, text_size=size.small)
table.cell(dash, 1, 5, get_pos_text(), bgcolor=c_bg_cell, text_color=get_pos_color(), text_size=size.small)

last_sig = long_cond ? "BUY SIGNAL" : short_cond ? "SELL SIGNAL" : "HOLD"
last_col = long_cond ? c_bull : short_cond ? c_bear : c_neu
table.cell(dash, 0, 6, "Signal", bgcolor=c_bg_cell, text_color=c_text, text_halign=text.align_left, text_size=size.small)
table.cell(dash, 1, 6, last_sig, bgcolor=c_bg_cell, text_color=last_col, text_size=size.small)

// ==========================================
// 5. 시각화 (Visualization)
// ==========================================
p_upper_B = plot(upper_B, "Upper B", color=color.new(color.red, 50))
p_upper_A = plot(upper_A, "Upper A", color=color.new(color.red, 0))
p_basis = plot(basis, "Basis", color=color.gray)
p_lower_A = plot(lower_A, "Lower A", color=color.new(color.green, 0))
p_lower_B = plot(lower_B, "Lower B", color=color.new(color.green, 50))
fill(p_upper_B, p_upper_A, color=color.new(color.red, 90))
fill(p_lower_A, p_lower_B, color=color.new(color.green, 90))

plotshape(long_cond, title="Long", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
plotshape(short_cond, title="Short", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.small)

면책사항

해당 정보와 게시물은 금융, 투자, 트레이딩 또는 기타 유형의 조언이나 권장 사항으로 간주되지 않으며, 트레이딩뷰에서 제공하거나 보증하는 것이 아닙니다. 자세한 내용은 이용 약관을 참조하세요.