
이 전략은 마치 시장의 ‘정서 인식기’와 같습니다. 이 전략은 소매업자들이 예상하지 못했던 중요한 전환점을 잡을 수 있습니다. 만약 당신이 주가가 언제 ‘얼굴을 바꾼다’는 것을 미리 알 수 있다면, 마치 거래하는 초능력을 가지고 있다고 상상해보세요.
이 전략의 핵심 아이디어는 아주 간단합니다. 가격이 중요한 고위점이나 낮은점을 넘어서면 시장 구조가 변합니다. 마치 여러분이 산을 오르다가 갑자기 내리막길이 앞에 있다는 것을 발견하는 것처럼, 트렌드의 변화는 종종 바로 그 순간입니다!
1. 윙 포인트 인식 시스템 🎢 전략은 지난 기간 동안의 중요한 최고점과 최저점을 자동으로 찾아내고, 시장에 “산”과 “골짜기”를 그려주는 것과 같습니다. 가격이 이러한 중요한 위치를 돌파하면, 트렌드가 변할 수 있다는 신호입니다!
2. ATR 필터 📏 이 전략은 작은 변동에 의해 무시되지 않으며, ATR의 특정 배수를 달성해야 합니다. 이것은 “최저의 임계”를 설정하여 가짜 돌파구를 필터링하는 것과 같습니다.
3. 프리미엄/비상구간 프레임워크 💎 가장 재미있는 것은! 전략은 가격대에서 “가격대”와 “가격대”를 구분합니다. 저렴한 지역에서 구매하고 비싼 지역에서 판매하는 것이 투자의 황금률이 아닌가요?
갱도 1이 전략은 트렌드 변동의 첫 번째 시간에 집중하여 “지혜있는 돈”이 아니라 “수수꾼”이 될 수 있도록합니다.
갱도 안내 2: 리스크 관리가 아주 편리합니다! 계정 비율에 따라 자동으로 포지션 크기를 계산할 수 있고, 분기 기반의 스톱 로스를 설정할 수 있습니다.
웅덩이 피하기 위한 지침 3이 그래프는 자동으로 전환점을 표시하고, 배경의 색이 바뀌어 현재 가격이 저렴하고 비싼 지역인지 알려줍니다.
이 전략은 특히 중장기 거래자들에게 적합합니다. 왜냐하면 이 전략은 단기적인 소음보다는 시장 구조의 근본적인 변화에 초점을 맞추기 때문입니다.
기억하세요, 최고의 전략은 매일매일 거래하는 것이 아니라, 적절한 시기에 적절한 일을 하는 것입니다!
/*backtest
start: 2024-12-04 00:00:00
end: 2025-12-02 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=6
strategy(title="Trendshift [CHE] Strategy", shorttitle="TrShStr", overlay=true)
// ——— SECTION: Constants & Enums
string GROUP_MARKET_STRUCTURE = "Market Structure"
string GROUP_FRAMEWORK = "Premium/Discount Framework"
string GROUP_VISUAL = "Visuals"
string GROUP_RISK = "Execution and Risk"
// ——— SECTION: Inputs (grouped; tooltips; one-row via inline)
swing_len_input = input.int(5, "Swing length", minval=1, group=GROUP_MARKET_STRUCTURE, inline="msw", tooltip="Bars left and right for major swing highs and lows.")
is_use_atr_filter_input = input.bool(true, "Use ATR filter", group=GROUP_MARKET_STRUCTURE, inline="msw", tooltip="Require breakout to exceed swing level by an ATR multiple.")
atr_len_input = input.int(14, "ATR length", minval=1, group=GROUP_MARKET_STRUCTURE, inline="atr", tooltip="ATR length for conviction and band checks.")
atr_mult_break_input = input.float(1.0, "Break ATR mult", minval=0.0, step=0.1, group=GROUP_MARKET_STRUCTURE, inline="atr", tooltip="Distance beyond swing, in ATR units, to confirm a structure shift.")
is_enable_framework_input = input.bool(true, "Enable framework", group=GROUP_FRAMEWORK, inline="fw", tooltip="Enable premium and discount band logic.")
is_persist_last_band_input = input.bool(true, "Persist band on timeout", group=GROUP_FRAMEWORK, inline="fw", tooltip="Keep last band after regime timeout.")
min_band_atr_mult_input = input.float(0.5, "Min band ATR mult", minval=0.0, step=0.1, group=GROUP_FRAMEWORK, inline="band", tooltip="Minimum band height relative to ATR.")
regime_timeout_bars_input = input.int(200, "Regime timeout bars", minval=0, group=GROUP_FRAMEWORK, inline="band", tooltip="Bars since last shift before regime reset. Zero disables timeout.")
is_invert_colors_input = input.bool(false, "Invert colors", group=GROUP_FRAMEWORK, inline="col", tooltip="Swap premium and discount colors.")
show_zone_tint_input = input.bool(true, "Show zone tint", group=GROUP_VISUAL, inline="vis", tooltip="Tint background in discount or premium bands.")
show_structure_marks_input = input.bool(true, "Show shift markers", group=GROUP_VISUAL, inline="vis", tooltip="Show first bullish and first bearish structure shift markers.")
risk_percent_input = input.float(1.0, "Risk per trade percent", minval=0.0, maxval=100.0, step=0.1, group=GROUP_RISK, inline="risk", tooltip="Account percent used to size position.")
is_use_band_for_size_input = input.bool(false, "Use band for size", group=GROUP_RISK, inline="risk", tooltip="If enabled, band height is used to scale position size.")
is_close_on_opposite_input = input.bool(true, "Flat on opposite shift", group=GROUP_RISK, inline="exit", tooltip="Close and reverse on opposite first shift.")
is_use_stop_band_input = input.bool(false, "Use stop at band", group=GROUP_RISK, inline="exit", tooltip="If enabled, band edge is used as stop distance.")
stop_band_side_input = input.string("Opposite band edge", "Stop band side", options=["Opposite band edge", "Same band edge"], group=GROUP_RISK, inline="exit", tooltip="Defines which band edge is used as stop reference.")
// ——— SECTION: Types
// (no custom types)
// ——— SECTION: Persistent Vars → Runtime Vars
var float last_swing_high = na
var float last_swing_low = na
var int last_swing_high_bar = na
var int last_swing_low_bar = na
var int regime = 0
var float band_low = na
var float band_high = na
var float struct_level = na
var int last_shift_bar = na
var bool is_last_shift_bullish = false
// ——— SECTION: Helpers (pure, no side effects)
stop_from_band(is_long, band_low_value, band_high_value, stop_side) =>
float stop_price = na
if is_long
stop_price := stop_side == "Opposite band edge" ? band_low_value : band_high_value
else
stop_price := stop_side == "Opposite band edge" ? band_high_value : band_low_value
stop_price
// ——— SECTION: Core Calculations
// Swings and ATR
pivot_high_value = ta.pivothigh(high, swing_len_input, swing_len_input)
pivot_low_value = ta.pivotlow(low, swing_len_input, swing_len_input)
if not na(pivot_high_value)
last_swing_high := pivot_high_value
last_swing_high_bar := bar_index - swing_len_input
if not na(pivot_low_value)
last_swing_low := pivot_low_value
last_swing_low_bar := bar_index - swing_len_input
atr_value = ta.atr(atr_len_input)
// Structure shifts
has_major_high = not na(last_swing_high)
has_major_low = not na(last_swing_low)
is_bullish_break_base = has_major_high and close > last_swing_high
is_bearish_break_base = has_major_low and close < last_swing_low
is_bullish_break = is_bullish_break_base
is_bearish_break = is_bearish_break_base
if is_use_atr_filter_input and atr_value > 0.0
is_bullish_break := is_bullish_break_base and (close - last_swing_high) >= atr_mult_break_input * atr_value
is_bearish_break := is_bearish_break_base and (last_swing_low - close) >= atr_mult_break_input * atr_value
is_bullish_shift = is_bullish_break and has_major_low
is_bearish_shift = is_bearish_break and has_major_high
if is_bullish_shift and is_bearish_shift
is_bullish_shift := close >= open
is_bearish_shift := not is_bullish_shift
is_bullish_shift_first = is_bullish_shift and (na(last_shift_bar) or not is_last_shift_bullish)
is_bearish_shift_first = is_bearish_shift and (na(last_shift_bar) or is_last_shift_bullish)
// Regime and band update
if is_bullish_shift
regime := 1
band_low := last_swing_low
band_high := high
struct_level := last_swing_high
last_shift_bar := bar_index
is_last_shift_bullish := true
if is_bearish_shift
regime := -1
band_low := low
band_high := last_swing_high
struct_level := last_swing_low
last_shift_bar := bar_index
is_last_shift_bullish := false
// Regime timeout and band clear
if regime_timeout_bars_input > 0 and regime != 0 and not is_bullish_shift and not is_bearish_shift and not na(last_shift_bar) and bar_index - last_shift_bar > regime_timeout_bars_input
regime := 0
if not is_persist_last_band_input
band_low := na
band_high := na
struct_level := na
// Premium and discount band
is_base_valid_band = is_enable_framework_input and not na(band_low) and not na(band_high) and band_high > band_low
price_span = is_base_valid_band ? band_high - band_low : na
is_band_not_tiny = is_base_valid_band and atr_value > 0.0 and min_band_atr_mult_input > 0.0 and price_span >= min_band_atr_mult_input * atr_value or is_base_valid_band and (min_band_atr_mult_input == 0.0 or atr_value <= 0.0)
is_valid_band = is_base_valid_band and is_band_not_tiny
discount_threshold = is_valid_band ? band_low + 0.25 * price_span : na
premium_threshold = is_valid_band ? band_low + 0.75 * price_span : na
is_in_discount = is_valid_band and close <= discount_threshold
is_in_premium = is_valid_band and close >= premium_threshold
// Execution sizing and stops
acc_value = strategy.equity
base_qty = risk_percent_input > 0.0 ? acc_value * risk_percent_input * 0.01 / nz(close, 1.0) : 0.0
band_qty_factor = is_use_band_for_size_input and is_valid_band and atr_value > 0.0 ? math.min(2.0, math.max(0.25, price_span / atr_value)) : 1.0
trade_qty = base_qty * band_qty_factor
is_long_entry = is_bullish_shift_first
is_short_entry = is_bearish_shift_first
float long_stop = na
float short_stop = na
if is_use_stop_band_input and is_valid_band
long_stop := stop_from_band(true, band_low, band_high, stop_band_side_input)
short_stop := stop_from_band(false, band_low, band_high, stop_band_side_input)
// Strategy entries and exits
if is_long_entry and trade_qty > 0.0
if is_close_on_opposite_input and strategy.position_size < 0
strategy.close("Short")
if is_use_stop_band_input and not na(long_stop)
strategy.entry("Long", strategy.long, qty=trade_qty)
strategy.exit("Long SL", "Long", stop=long_stop)
else
strategy.entry("Long", strategy.long, qty=trade_qty)
if is_short_entry and trade_qty > 0.0
if is_close_on_opposite_input and strategy.position_size > 0
strategy.close("Long")
if is_use_stop_band_input and not na(short_stop)
strategy.entry("Short", strategy.short, qty=trade_qty)
strategy.exit("Short SL", "Short", stop=short_stop)
else
strategy.entry("Short", strategy.short, qty=trade_qty)
// ——— SECTION: Rendering/UI (GLOBAL ONLY; single-line calls)
discount_zone_color = is_invert_colors_input ? color.new(color.red, 30) : color.new(color.green, 30)
premium_zone_color = is_invert_colors_input ? color.new(color.green, 30) : color.new(color.red, 30)
discount_bg_color = show_zone_tint_input and is_in_discount ? color.new(discount_zone_color, 85) : na
premium_bg_color = show_zone_tint_input and is_in_premium ? color.new(premium_zone_color, 85) : na
bgcolor(discount_bg_color, title="Discount zone tint")
bgcolor(premium_bg_color, title="Premium zone tint")
plotshape(show_structure_marks_input and is_bullish_shift_first ? low : na, title="Bullish structure shift first", style=shape.triangleup, location=location.belowbar, size=size.small, color=color.new(color.lime, 0), text="Shift Up", textcolor=color.white)
plotshape(show_structure_marks_input and is_bearish_shift_first ? high : na, title="Bearish structure shift first", style=shape.triangledown, location=location.abovebar, size=size.small, color=color.new(color.red, 0), text="Shift Down", textcolor=color.white)