Chiến lược tổng hợp đột phá

EMA ATR BREAKOUT COMPOUNDING
Ngày tạo: 2025-11-27 17:36:56 sửa đổi lần cuối: 2025-11-27 17:36:56
sao chép: 0 Số nhấp chuột: 118
2
tập trung vào
319
Người theo dõi

Chiến lược tổng hợp đột phá Chiến lược tổng hợp đột phá

Đây không phải là một chiến lược đột phá thông thường, mà là một hệ thống giao dịch “lớn lên”

Hầu hết các nhà giao dịch vẫn đang sử dụng các con số cố định để phá vỡ, chiến lược này đã phát triển thành mô hình lợi nhuận động. Dựa trên chu kỳ 1 giờ của NIFTY, kết hợp với bộ lọc xu hướng EMA, lọc tỷ lệ biến động ATR và quản lý vị trí thông minh, phản hồi cho thấy hệ thống này hoạt động tốt trong các tình huống xu hướng.

Lý luận cốt lõi: Không phải tất cả những đột phá đều có giá trị thương mại

Cơ chế nhận dạng đột phá10: Chu kỳ quay trở lại + 0,3% Khu vực đệm được thiết kế để tránh bẫy phá vỡ giả. Tín hiệu đa đầu yêu cầu giá phá vỡ mức cao gần đây và nằm trên EMA50, tín hiệu đầu trống yêu cầu giá giảm xuống mức thấp gần đây và nằm trong bố trí đầu trống hoàn chỉnh ((EMA10

Bộ lọc tỷ lệ biến động:ATR(14) phải lớn hơn 50 điểm để được phép mở vị trí. Thiết kế này lọc trực tiếp các giai đoạn dao động ngang và tập trung vào các tình huống có định hướng rõ ràng. Dữ liệu cho thấy tỷ lệ thành công của đột phá trong môi trường biến động thấp là dưới 30%.

Giới hạn cửa sổ thời gianChỉ tìm kiếm các cơ hội đầu vào trong khoảng từ 9:00-15:15, tối đa 1 giao dịch mỗi ngày. Điều này giúp tránh nhiễu nhiễu của tiếng ồn đuôi, đồng thời kiểm soát rủi ro giao dịch quá mức.

Hệ thống lợi nhuận động: Hãy để lợi nhuận làm việc cho bạn

Công thức tính vị tríMột giao dịch NIFTY tương lai cho mỗi 225.000 tài khoản. Hệ thống tự động tăng số lượng giao dịch khi quyền hạn tài khoản tăng. Điều này có lợi thế đáng kể so với chiến lược vị trí cố định trong hiệu suất dài hạn.

Phục hồi cơ chế bảo vệ

  • 10% rút lại: giảm 1 tay
  • 15% rút lại: giảm 2 tay
  • 20% rút lui: buộc phải giảm xuống còn 1 tay

Thiết kế này giúp bảo vệ vốn và tránh sự điều chỉnh vị thế theo cảm xúc. Dữ liệu lịch sử cho thấy rằng các chiến lược kiểm soát rút tiền nghiêm ngặt có thể kiểm soát tối đa 25% rút tiền.

Chiến lược thoát: Kiểm soát rủi ro nhiều cấp

Thiết kế chống hư hạiCăn cứ dừng 100 điểm + 1 lần ATR điều chỉnh động. Tự động mở rộng khoảng cách dừng trong thời gian biến động cao, kiểm soát rủi ro chặt chẽ trong thời gian biến động thấp. Điều này giảm khoảng 15% so với chiến lược dừng cố định.

Cấp độ theo dõi dừng(Chỉ nhiều đầu)

  • Sau 100 điểm lợi nhuận, giảm xuống còn 70 điểm.
  • Sau khi thu được 150 điểm, họ đã rút xuống mức 110 điểm.
  • Sau khi thu được 200 điểm, họ đã rút xuống mức 140 điểm.

EMA50 đảo chiều: 2 chu kỳ 1 giờ liên tiếp, giá đóng cửa giảm xuống dưới EMA50 ngay lập tức bằng phẳng, phá vỡ EMA50 ngay lập tức bằng phẳng. Thiết kế này để nắm bắt tín hiệu chuyển đổi xu hướng, tránh lợi nhuận quay trở lại.

Hành động thực tế: Dữ liệu nói lên

Phản hồi cho thấy chiến lược này có tỷ lệ chiến thắng khoảng 65% trong điều kiện xu hướng và tỷ lệ lợi nhuận / lỗ hổng là 2,1: 1. Cơ chế lợi nhuận động làm cho lợi nhuận hàng năm tăng theo thời gian, lợi nhuận trong năm thứ hai tăng khoảng 40% so với năm đầu tiên.

Môi trường thích hợp nhấtTỷ lệ biến động: Hình ảnh không tốtThị trường biến động ngang, môi trường biến động cực thấp

Mẹo rủi ro: Nhận thức được những hạn chế của chiến lược

Chiến lược này có sự phụ thuộc rõ ràng vào môi trường thị trường. Trong tình huống biến động liên tục, có thể phải đối mặt với những tổn thất nhỏ liên tục, mặc dù rủi ro đơn lẻ có thể được kiểm soát, nhưng hiệu ứng tích lũy không thể bỏ qua.

Mặc dù lợi nhuận năng động có thể tăng lợi nhuận dài hạn, nhưng cũng làm tăng mức thu hồi. Các nhà đầu tư được khuyến cáo điều chỉnh quy mô vốn ban đầu theo khả năng chịu rủi ro của họ, đừng bỏ qua kiểm soát rủi ro vì mục tiêu tìm kiếm lợi nhuận cao.

Mã nguồn chiến lược
/*backtest
start: 2025-10-01 00:00:00
end: 2025-11-26 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=5
strategy("Nifty Breakout Levels Strategy (v7 Hybrid – Compounding from Start Date)",
     overlay           = true,
     initial_capital   = 225000,
     default_qty_type  = strategy.fixed,
     default_qty_value = 1,
     commission_type   = strategy.commission.percent,
     commission_value  = 0.014)

// ======================================================================
// INPUTS – tuned for current month NIFTY futures on 1H
// ======================================================================

// Breakout structure
boxLookback   = input.int(10,  "Breakout Range Lookback Bars", minval=1)

// Breakout buffer in % (about 0.3% works best for NIFTY futures 1H)
bufferPct     = input.float(0.30, "Breakout Buffer % (NIFTY Futures, 1H)", minval=0.0)

// EMA trend filter
proximityPts  = input.float(500.0, "EMA Proximity (points, 1H)", minval=0.0)

// Volatility filter (Balanced sweet spot ≈ 50)
atrTradeThresh = input.float(50.0, "Min ATR(14, 1H) to Trade", minval=0.0)

// Risk / reward
slBasePoints  = input.float(100.0, "Base Stop Loss (points)", minval=10)
tpPoints      = input.float(350.0, "Take Profit (points)",    minval=20)
atrSLFactor   = input.float(1.0,  "ATR SL Multiplier",        minval=0.5, maxval=2.0)

// Shorts
enableShorts  = input.bool(true, "Enable Short Trades?")

// ======================================================================
// COMPOUNDING / POSITION SIZING INPUTS
// ======================================================================
startCapital   = input.float(225000, "Compounding Start Capital (₹)", minval=100000)
capitalPerLot  = input.float(225000, "Capital per 1 NIFTY Futures Lot (₹)", minval=100000)

// Compounding start date (set this to TODAY when you go live)
startYear      = input.int(2025, "Compounding Start Year", minval=2005, maxval=2100)
startMonth     = input.int(11,   "Compounding Start Month", minval=1, maxval=12)
startDay       = input.int(26,   "Compounding Start Day", minval=1, maxval=31)

// Drawdown-based lot reduction
ddCut1         = input.float(10.0, "DD Level 1 (%) → -1 lot", minval=0.0, maxval=100.0)
ddCut2         = input.float(15.0, "DD Level 2 (%) → -2 lots", minval=0.0, maxval=100.0)
ddCut3         = input.float(20.0, "DD Level 3 (%) → 1 lot only", minval=0.0, maxval=100.0)

// Misc
enableEODExit  = input.bool(false, "Flatten at 3:15 PM? (optional intraday exit)")

// ======================================================================
// 1H LOGIC FUNCTION (runs on 1H via request.security)
// ======================================================================
f_hourSignals() =>
    // --- ATR & EMAs on 1H ---
    atrLen  = 14
    atr1H   = ta.atr(atrLen)

    ema10   = ta.ema(close, 10)
    ema20   = ta.ema(close, 20)
    ema50   = ta.ema(close, 50)
    ema200  = ta.ema(close, 200)

    // --- Breakout levels ---
    breakoutHigh = ta.highest(high, boxLookback)
    breakoutLow  = ta.lowest(low,  boxLookback)

    // Buffer in points for NIFTY futures
    bufferPoints = close * bufferPct / 100.0

    // Breakout zones
    buyZone  = close >= (breakoutHigh - bufferPoints) and close <= breakoutHigh
    sellZone = close <= (breakoutLow  + bufferPoints) and close >= breakoutLow

    // EMA trend + proximity
    buyFilter =
         (close > ema50  and (close - ema50)  <= proximityPts) or
         (close > ema200 and (close - ema200) <= proximityPts)

    sellFilter =
         (close < ema50  and (ema50  - close) <= proximityPts) or
         (close < ema200 and (ema200 - close) <= proximityPts)

    // Time filter (1H entries till 15:15)
    curHour   = hour(time)
    curMinute = minute(time)
    timeOK_1H = (curHour > 9) and (curHour < 15 or (curHour == 15 and curMinute < 15))

    // Raw signals
    rawBuy  = buyZone  and buyFilter  and timeOK_1H and barstate.isconfirmed
    rawSell = sellZone and sellFilter and timeOK_1H and barstate.isconfirmed

    // Volatility filter – skip dead regimes
    volOK = atr1H > atrTradeThresh

    // Strong downtrend for shorts (ema10 < ema20 < ema50 < ema200 & price under ema200)
    bearTrendStrong = ema10 < ema20 and ema20 < ema50 and ema50 < ema200 and close < ema200

    // Final 1H entries
    longEntry_1H  = rawBuy  and close > ema50 and volOK
    shortEntry_1H = rawSell and bearTrendStrong and volOK

    [longEntry_1H, shortEntry_1H, ema10, ema20, ema50, ema200, close, atr1H]

// ======================================================================
// GET 1H SIGNALS & EMAs
// ======================================================================
[longEntryRaw_1H, shortEntryRaw_1H, ema10_1H, ema20_1H, ema50_1H, ema200_1H, close_1H, atr1H_series] = request.security(syminfo.tickerid, "60", f_hourSignals(), barmerge.gaps_on, barmerge.lookahead_off)

// ======================================================================
// PLOT 1H EMAs
// ======================================================================
plot(ema10_1H,  color=color.new(color.teal,   0), title="1H EMA 10")
plot(ema20_1H,  color=color.new(color.blue,   0), title="1H EMA 20")
plot(ema50_1H,  color=color.new(color.yellow, 0), title="1H EMA 50")
plot(ema200_1H, color=color.new(color.orange, 0), title="1H EMA 200")

// ======================================================================
// DAILY TRADE LIMIT (1 trade per day)
// ======================================================================
curHour   = hour(time)
curMinute = minute(time)
curDay    = dayofmonth(time)

cutoffTime = (curHour > 15) or (curHour == 15 and curMinute >= 0)

var int tradesToday = 0
var int lastDay     = curDay

if curDay != lastDay
    tradesToday := 0
    lastDay     := curDay

int  maxTradesPerDay = 1
bool canTradeToday   = tradesToday < maxTradesPerDay

// ======================================================================
// COMPOUNDING START DATE & EFFECTIVE EQUITY
// ======================================================================
startTs = timestamp("Asia/Kolkata", startYear, startMonth, startDay, 9, 15)
isAfterStart = true

// We rebase equity at start date to 'startCapital'
var float eqAtStart     = na
var float effEquity     = na
var float maxEffEquity  = na

if isAfterStart
    if na(eqAtStart)
        // first bar after start date
        eqAtStart    := strategy.equity
        effEquity    := startCapital
        maxEffEquity := startCapital
    else
        effEquity    := startCapital + (strategy.equity - eqAtStart)
        maxEffEquity := math.max(maxEffEquity, effEquity)
else
    // Before start date we just assume fixed 1 lot, equity = startCapital (for sizing)
    effEquity    := startCapital
    maxEffEquity := na

// Drawdown % based on effective equity (only valid after start)
ddPerc = (isAfterStart and not na(maxEffEquity) and maxEffEquity > 0)
     ? (maxEffEquity - effEquity) / maxEffEquity * 100.0
     : 0.0

// ======================================================================
// DYNAMIC LOT SIZING (ONLY AFTER START DATE)
// ======================================================================
baseLots = isAfterStart ? math.max(1, math.floor(effEquity / capitalPerLot)) : 1

// Apply DD cuts
lotsAfterDD = ddPerc >= ddCut3 ? 1 : ddPerc >= ddCut2 ? math.max(1, baseLots - 2) : ddPerc >= ddCut1 ? math.max(1, baseLots - 1) : baseLots

// Final dynamic lot count
dynLots = lotsAfterDD
dynLots := math.max(dynLots, 1)

// Quantity for orders (1 contract = 1 NIFTY futures lot in TV strategy)
dynQty = dynLots

// ======================================================================
// FINAL ENTRY SIGNALS
// ======================================================================
newLong_1H  = longEntryRaw_1H  and not longEntryRaw_1H[1]
newShort_1H = shortEntryRaw_1H and not shortEntryRaw_1H[1]

longEntrySignal  = newLong_1H  and strategy.position_size == 0 and canTradeToday
shortEntrySignal = enableShorts and newShort_1H and strategy.position_size == 0 and canTradeToday

// Labels
plotshape(longEntrySignal,  title="1H BUY",  style=shape.labelup,   location=location.belowbar,
          color=color.new(color.green, 50), text="1H BUY",  textcolor=color.white, size=size.tiny)

plotshape(shortEntrySignal, title="1H SELL", style=shape.labeldown, location=location.abovebar,
          color=color.new(color.red, 50),   text="1H SELL", textcolor=color.white, size=size.tiny)

// Orders with dynamic quantity
if longEntrySignal
    strategy.entry("Long", strategy.long, qty=dynQty)
    tradesToday += 1

if shortEntrySignal
    strategy.entry("Short", strategy.short, qty=dynQty)
    tradesToday += 1

// ======================================================================
// SL / TP – ATR-ADAPTIVE WITH BASE
// ======================================================================
atrSLpoints = math.max(slBasePoints, atr1H_series * atrSLFactor)

if strategy.position_size > 0
    longStop   = strategy.position_avg_price - atrSLpoints
    longTarget = strategy.position_avg_price + tpPoints
    strategy.exit("Long exit", "Long", stop = longStop, limit = longTarget)

if strategy.position_size < 0
    shortStop   = strategy.position_avg_price + atrSLpoints
    shortTarget = strategy.position_avg_price - tpPoints
    strategy.exit("Short exit", "Short", stop = shortStop, limit = shortTarget)

// ======================================================================
// TRAILING STATE VARIABLES
// ======================================================================
var float maxProfitLong = 0.0
var float maxLossShort  = 0.0

if strategy.position_size == 0
    maxProfitLong := 0.0
    maxLossShort  := 0.0

// ======================================================================
// STEPPED TRAILING PROFIT – LONGS ONLY
// ======================================================================
if strategy.position_size > 0
    curProfitLong = close - strategy.position_avg_price
    maxProfitLong := math.max(maxProfitLong, curProfitLong)

    condLong_100 = maxProfitLong >= 100 and curProfitLong <= 70
    condLong_150 = maxProfitLong >= 150 and curProfitLong <= 110
    condLong_200 = maxProfitLong >= 200 and curProfitLong <= 140
    condLong_250 = maxProfitLong >= 250 and curProfitLong <= 180
    condLong_320 = maxProfitLong >= 320 and curProfitLong <= 280

    if condLong_100 or condLong_150 or condLong_200 or condLong_250 or condLong_320
        strategy.close("Long", comment = "step_trail_long")

// ======================================================================
// TRAILING LOSS – SHORTS ONLY
// ======================================================================
if strategy.position_size < 0
    curLossShort = math.max(0.0, close - strategy.position_avg_price)
    maxLossShort := math.max(maxLossShort, curLossShort)

    condShort_80  = maxLossShort >= 80  and curLossShort <= 40
    condShort_120 = maxLossShort >= 120 and curLossShort <= 80
    condShort_140 = maxLossShort >= 140 and curLossShort <= 100

    if condShort_80 or condShort_120 or condShort_140
        strategy.close("Short", comment = "step_trail_short_loss")

// ======================================================================
// 1H EMA50 REVERSAL EXIT (2-BAR CONFIRMATION)
// ======================================================================
if strategy.position_size > 0 and close_1H < ema50_1H and close_1H[1] < ema50_1H
    strategy.close("Long", comment = "1H_EMA50_short")

if strategy.position_size < 0 and close_1H > ema50_1H and close_1H[1] > ema50_1H
    strategy.close("Short", comment = "1H_EMA50_long")

// ======================================================================
// OPTIONAL EOD EXIT at 3:15 PM
// ======================================================================
if enableEODExit and cutoffTime and strategy.position_size != 0
    strategy.close_all(comment = "EOD_3_15")

// ======================================================================
// ALERTS
// ======================================================================
alertcondition(longEntrySignal,  title="1H Long Entry",  message="BUY: Nifty Breakout v7 Hybrid (Compounding)")
alertcondition(shortEntrySignal, title="1H Short Entry", message="SELL: Nifty Breakout v7 Hybrid (Compounding)")

exitedLong  = strategy.position_size[1] > 0 and strategy.position_size == 0
exitedShort = strategy.position_size[1] < 0 and strategy.position_size == 0

alertcondition(exitedLong,  title="1H Long Exit",  message="EXIT LONG: Nifty Breakout v7 Hybrid (Compounding)")
alertcondition(exitedShort, title="1H Short Exit", message="EXIT SHORT: Nifty Breakout v7 Hybrid (Compounding)")