Tài nguyên đang được tải lên... tải...

Chiến lược giao dịch theo xu hướng giá đa cân bằng và đảo ngược

Tác giả:ChaoZhang, Ngày: 2024-12-13 10:23:12
Tags:ATRSLTP

img

Tổng quan chiến lược

Chiến lược này là một hệ thống giao dịch theo xu hướng và đảo ngược dựa trên các điểm cân bằng giá. Nó xác định giá cân bằng bằng cách tính điểm giữa giữa các điểm cao nhất và thấp nhất trên các thanh X, và đánh giá hướng xu hướng dựa trên vị trí của giá đóng đối với giá cân bằng. Khi giá duy trì ở một bên của sự cân bằng cho một số thanh, hệ thống xác nhận xu hướng. Nó tìm kiếm các cơ hội nhập vào lần rút đầu tiên (cân bằng giá). Chiến lược có thể được cấu hình cho cả hai chế độ giao dịch theo xu hướng hoặc đảo ngược.

Nguyên tắc chiến lược

  1. Tính toán giá cân bằng: Sử dụng điểm giữa giữa giá cao nhất và thấp nhất trên các thanh X như giá cân bằng, giống hệt với tính toán đường cơ sở trong Ichimoku Cloud.
  2. Xác định xu hướng: Một xu hướng được xác nhận khi giá ở trên cùng một bên của sự cân bằng cho X thanh liên tiếp (bất định 7).
  3. Tín hiệu nhập cảnh: Khởi động nhập cảnh khi giảm đầu tiên (thăng bằng giá vượt qua) sau khi xác nhận xu hướng.
  4. Dừng lỗ và lấy lợi nhuận: Sử dụng phần trăm 60 của ATR để điều chỉnh năng động khoảng cách dừng lỗ và lấy lợi nhuận, cung cấp kiểm soát rủi ro linh hoạt.
  5. Bảo vệ chuyển động lớn: Tự động đóng các vị trí khi giá lệch khỏi trạng thái cân bằng vượt quá một số ATR.

Ưu điểm chiến lược

  1. Khả năng thích nghi cao: Chuyển đổi linh hoạt giữa các chế độ giao dịch theo xu hướng và đảo ngược dựa trên đặc điểm thị trường.
  2. Kiểm soát rủi ro toàn diện: Sử dụng các điểm dừng ATR năng động và các cơ chế bảo vệ chuyển động lớn.
  3. Các giao dịch rõ ràng: Các tín hiệu giao dịch rõ ràng và không dựa trên các kết hợp chỉ số kỹ thuật phức tạp.
  4. Hiển thị tốt: Sử dụng đèn chùm màu và nền cho hiển thị tình trạng thị trường trực quan.
  5. Tự động hóa thân thiện: Dễ dàng giao diện với các nền tảng giao dịch như MT5 để giao dịch tự động.

Rủi ro chiến lược

  1. Rủi ro thị trường hỗn loạn: Có thể tạo ra các tín hiệu sai thường xuyên trong thị trường bên cạnh.
  2. Tác động trượt: Có thể phải đối mặt với trượt đáng kể trong các biến động thị trường dữ dội.
  3. Độ nhạy của các thông số: Các thông số cốt lõi như thời gian cân bằng và thời gian xác định xu hướng cần tối ưu hóa cẩn thận cho các thị trường khác nhau.
  4. Rủi ro chuyển đổi thị trường: Chuyển đổi từ xu hướng sang các thị trường dao động có thể gây ra giảm đáng kể.

Hướng dẫn tối ưu hóa chiến lược

  1. Nhận dạng môi trường thị trường: Thêm mô-đun xác định môi trường thị trường để điều chỉnh động các tham số chiến lược trong các điều kiện thị trường khác nhau.
  2. Bộ lọc tín hiệu: Xem xét thêm khối lượng, biến động và các chỉ số phụ trợ khác để lọc các tín hiệu sai.
  3. Quản lý vị thế: Đưa ra các cơ chế quản lý vị thế phức tạp hơn, chẳng hạn như điều chỉnh năng động dựa trên biến động.
  4. Nhiều khung thời gian: Tích hợp các tín hiệu từ nhiều khung thời gian để cải thiện độ chính xác giao dịch.
  5. Tối ưu hóa chi phí giao dịch: Tối ưu hóa thời gian vào và ra dựa trên các đặc điểm chi phí của các công cụ giao dịch khác nhau.

Tóm lại

Đây là một hệ thống giao dịch xu hướng được thiết kế tốt cung cấp logic giao dịch rõ ràng thông qua khái niệm cốt lõi về giá cân bằng. Sức mạnh lớn nhất của chiến lược là tính linh hoạt của nó, phù hợp với cả việc theo xu hướng và đảo ngược giao dịch trong khi duy trì các cơ chế kiểm soát rủi ro toàn diện. Mặc dù nó có thể phải đối mặt với những thách thức trong điều kiện thị trường nhất định, thông qua tối ưu hóa liên tục và điều chỉnh linh hoạt, chiến lược có tiềm năng duy trì hiệu suất ổn định trong các môi trường thị trường khác nhau.


/*backtest
start: 2019-12-23 08:00:00
end: 2024-12-11 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Honestcowboy

//@version=5
strategy("Equilibrium Candles + Pattern [Honestcowboy]", overlay=false)

// ================================== //
// ---------> User Input <----------- //
// ================================== //

candleSmoothing = input.int(9, title="Equilibrium Length", tooltip="The lookback for finding equilibrium.\nIt is same calculation as the Baseline in Ichimoku Cloud and is the mid point between highest and lowest value over this length.", group="Base Settings")
candlesForTrend = input.int(7, title="Candles needed for Trend", tooltip="The amount of candles in one direction (colored) before it's considered a trend.\nOrders get created on the first candle in opposite direction.", group="Base Settings")
maxPullbackCandles = input.int(2, title="Max Pullback (candles)", tooltip="The amount of candles can go in opposite direction until a pending trade order is cancelled.", group="Base Settings")
candle_bull_c1 = input.color(color.rgb(0,255,0), title="", inline="1", group="Candle Coloring")
candle_bull_c2 = input.color(color.rgb(0,100,0), title="", inline="1", group="Candle Coloring")
candle_bear_c1 = input.color(color.rgb(238,130,238), title="", inline="2", group="Candle Coloring")
candle_bear_c2 = input.color(color.rgb(75,0,130), title="", inline="2", group="Candle Coloring")
highlightClosePrices = input.bool(defval=true, title="Highlight close prices", group="Candle Coloring", tooltip="Will put small yellow dots where closing price would be.")
useBgColoring = input.bool(defval=true, title="color main chart Bg based on trend and entry point", tooltip="colors main chart background based on trend and entry points", group="Chart Background")
trend_bull_c = input.color(color.rgb(0,100,0,50), title="Trend Bull Color", group="Chart Background")
trend_bear_c = input.color(color.rgb(75,0,130, 50), title="Trend Bear Color", group="Chart Background")
long_zone_c = input.color(color.rgb(0,255,0,60), title="Long Entry Zone Color", group="Chart Background")
short_zone_c = input.color(color.rgb(238,130,238,60), title="Short Entry Zone Color", group="Chart Background")
atrLenghtScob = input.int(14, title="ATR Length", group = "Volatility Settings")
atrAverageLength = input.int(200, title="ATR percentile averages lookback", group = "Volatility Settings")
atrPercentile    = input.int(60, minval=0, maxval=99, title="ATR > bottom X percentile", group = "Volatility Settings", tooltip="For the Final ATR value in which percentile of last X bars does it need to be a number. At 60 it's the lowest ATR in top 40% of ATR over X bars")
useReverse = input.bool(true, title="Use Reverse", group="Strategy Inputs", tooltip="The Strategy will open short orders where normal strategy would open long orders. It will use the SL as TP and the TP as SL. So would create the exact opposite in returns as the normal strategy.")
stopMultiplier = input.float(2, title="stop+tp atr multiplier", group="Strategy Inputs")
useTPSL = input.bool(defval=true, title="use stop and TP", group="Strategy Inputs")
useBigCandleExit = input.bool(defval=true, title="Big Candle Exit", group="Strategy Inputs", inline="1", tooltip="Closes all open trades whenever price closes too far from the equilibrium")
bigCandleMultiplier = input.float(defval=1, title="Exit Multiplier", group="Strategy Inputs", inline="1", tooltip="The amount of times in ATR mean candle needs to close outside of equilibrium for it to be a big candle exit.")

tvToQPerc = input.float(defval=1, title="Trade size in Account risk %", group="Tradingview.to Connection (MT5)", tooltip="Quantity as a percentage with stop loss in the commands; the lot size is calculated based on the percentage to lose in case sl is hit. If SL is not specified, the Lot size will be calculated based on account balance.")
tvToOverrideSymbol = input.bool(defval=false, title="Override Symbol?", group="Tradingview.to Connection (MT5)")
tvToSymbol = input.string(defval="EURUSD", title="", group="Tradingview.to Connection (MT5)")
// ================================== //
// -----> Immutable Constants <------ //
// ================================== // 

var bool isBullTrend = false
var bool isBearTrend = false
var bool isLongCondition = false
var bool isShortCondition = false
var int bullCandleCount = 0
var int bearCandleCount = 0
var float longLine = na
var float shortLine = na

// ================================== //
// ---> Functional Declarations <---- //
// ================================== //

baseLine(len) =>
    math.avg(ta.lowest(len), ta.highest(len))

// ================================== //
// ----> Variable Calculations <----- //
// ================================== //

longSignal = false
shortSignal = false

equilibrium = baseLine(candleSmoothing)
atrEquilibrium = ta.atr(atrLenghtScob)
atrAveraged = ta.percentile_nearest_rank(atrEquilibrium, atrAverageLength, atrPercentile)
equilibriumTop  = equilibrium + atrAveraged*bigCandleMultiplier
equilibriumBottom = equilibrium - atrAveraged*bigCandleMultiplier

// ================================== //
// -----> Conditional Variables <---- //
// ================================== //
if not isBullTrend and close>equilibrium
    bullCandleCount := bullCandleCount + 1
    bearCandleCount := 0
    isBearTrend := false

if not isBearTrend and close<equilibrium
    bearCandleCount := bearCandleCount + 1
    bullCandleCount := 0
    isBullTrend := false

if bullCandleCount >= candlesForTrend
    isBullTrend := true
    isBearTrend := false
    bullCandleCount := 0
    bearCandleCount := 0
if bearCandleCount >= candlesForTrend
    isBearTrend := true
    isBullTrend := false
    bullCandleCount := 0
    bearCandleCount := 0

// ================================== //
// ------> Strategy Execution <------ //
// ================================== //

if isBullTrend[1] and close<equilibrium
    if useReverse and (not na(atrAveraged))
        strategy.entry("short", strategy.short, limit=high)
        alert("Sell " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " Q=" + str.tostring(tvToQPerc) + "% P=" + str.tostring(high) + " TP=" + str.tostring(high-stopMultiplier*atrAveraged)+ " SL=" + str.tostring(high+stopMultiplier*atrAveraged), freq=alert.freq_once_per_bar)
    if (not useReverse) and (not na(atrAveraged))
        strategy.entry("long", strategy.long, stop=high)
        alert("Buy " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " Q=" + str.tostring(tvToQPerc) + "% P=" + str.tostring(high) + " TP=" + str.tostring(high+stopMultiplier*atrAveraged) + " SL=" + str.tostring(high+stopMultiplier*atrAveraged), freq=alert.freq_once_per_bar)
    isLongCondition := true
    isBullTrend := false
    longLine := high

if isBearTrend[1] and close>equilibrium
    if useReverse and (not na(atrAveraged))
        strategy.entry("long", strategy.long, limit=low)
        alert("Buy " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " Q=" + str.tostring(tvToQPerc) + "% P=" + str.tostring(low) + " TP=" + str.tostring(low+stopMultiplier*atrAveraged) + " SL=" + str.tostring(low-stopMultiplier*atrAveraged), freq=alert.freq_once_per_bar)
    if (not useReverse) and (not na(atrAveraged))
        strategy.entry("short", strategy.short, stop=low)
        alert("Sell " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " Q=" + str.tostring(tvToQPerc) + "% P=" + str.tostring(low) + " TP=" + str.tostring(low-stopMultiplier*atrAveraged) + " SL=" + str.tostring(low+stopMultiplier*atrAveraged), freq=alert.freq_once_per_bar)
    isShortCondition := true
    isBearTrend := false
    shortLine := low

if isLongCondition and (bearCandleCount >= maxPullbackCandles)[1]
    if useReverse
        strategy.cancel("short")
        alert("Cancel " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " t=sell")
    if not useReverse
        strategy.cancel("long")
        alert("Cancel " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " t=buy")
    isLongCondition := false
    bullCandleCount := 0
    longLine := na

if isShortCondition and (bullCandleCount >= maxPullbackCandles)[1]
    if useReverse
        strategy.cancel("long")
        alert("Cancel " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " t=buy")
    if not useReverse
        strategy.cancel("short")
        alert("Cancel " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)) + " t=sell")
    isShortCondition := false
    bearCandleCount := 0
    shortLine := na
    
// ---- Save for graphical display that there is a longcondition + reset other variables
if high>longLine
    longSignal := true
    longLine := na
    isLongCondition := false

if low<shortLine
    shortSignal := true
    shortLine := na
    isShortCondition := false
// ---- Get Stop loss and Take Profit in there
if useReverse
    if useTPSL
        if strategy.position_size < 0 and strategy.position_size[1] >= 0
            strategy.exit("short exit", "short", limit=longLine[1]-stopMultiplier*atrAveraged, stop=longLine[1]+stopMultiplier*atrAveraged)
        if strategy.position_size > 0 and strategy.position_size[1] <= 0
            strategy.exit("long exit", "long", limit=shortLine[1]+stopMultiplier*atrAveraged, stop=shortLine[1]-stopMultiplier*atrAveraged)
if not useReverse
    if useTPSL
        if strategy.position_size > 0 and strategy.position_size[1] <= 0
            strategy.exit("long exit", "long", limit=longLine[1]+stopMultiplier*atrAveraged, stop=longLine[1]-stopMultiplier*atrAveraged)
        if strategy.position_size < 0 and strategy.position_size[1] >=0
            strategy.exit("short exit", "short", limit=shortLine[1]-stopMultiplier*atrAveraged, stop=shortLine[1]+stopMultiplier*atrAveraged)
// ----- Logic for closing positions on a big candle in either direction
if (strategy.position_size[1]>0 or strategy.position_size[1]<0) and useBigCandleExit
    if close>equilibriumTop or close<equilibriumBottom
        strategy.close_all("Big Candle Stop")
        alert("close " + str.tostring((tvToOverrideSymbol ? tvToSymbol : syminfo.ticker)))

// ================================== //
// ------> Graphical Display <------- //
// ================================== //

// Deviation from equilibrium using smoothed ATR and percentile nearest rank to rank the coloring of the candles
candle_c2 = close>equilibrium ? close>open ? candle_bull_c1 : candle_bull_c2 : close<open ? candle_bear_c1 : candle_bear_c2
// 
plotcandle(equilibrium, high, low, close, title="Equilibrium Candles", color=candle_c2, wickcolor=candle_c2, bordercolor=candle_c2)
plotshape(highlightClosePrices ? close : na, title="Closing Bubble", style=shape.circle, location=location.absolute, color=color.yellow)
bgcolor(useBgColoring ? (isBullTrend ? trend_bull_c : isBearTrend ? trend_bear_c : isLongCondition ? long_zone_c : isShortCondition ? short_zone_c : na) : na, force_overlay=true)
plot(longLine, color=candle_bull_c1, title="Long Line", style=plot.style_linebr, linewidth=4)
plot(shortLine, color=candle_bear_c1, title="Short Line", style=plot.style_linebr, linewidth=4)
plotshape(longSignal ? math.min(equilibrium, low)+(-0.5*atrAveraged) : na, title="Long Signal", color=candle_bull_c1, style=shape.diamond, size=size.tiny, location=location.absolute)
plotshape(shortSignal ? math.max(equilibrium, high)+(0.5*atrAveraged) : na, title="Short Signal", color=candle_bear_c1, style=shape.diamond, size=size.tiny, location=location.absolute)

// =================================== //
// ------> Simple Form Alerts <------- //
// =================================== //

alertcondition(longSignal, "Simple Long Signal")
alertcondition(shortSignal, "Simple Short Signal")

Có liên quan

Thêm nữa