Chiến lược Double Inside Bar & Trend

Tác giả:ChaoZhang, Ngày: 2024-01-30 15:11:48
Tags:

img

Chiến lược Double Inside Bar & Trend

Tổng quan

Chiến lược Double Inside Bar & Trend là một chiến lược giao dịch định lượng sử dụng mô hình double inside bar kết hợp với moving average để xác định xu hướng. Nó cung cấp các tín hiệu giao dịch xác suất cao với double inside bars, và đi dài hoặc ngắn tùy theo xu hướng được đánh giá bởi đường trung bình động.

Chiến lược logic

  1. Sử dụng Hull Moving Average (HMA) như một chỉ số để đánh giá xu hướng.
  2. Khi một mẫu thanh bên trong hai lần xảy ra, nó được coi là một tín hiệu giao dịch có khả năng cao.
  3. Nếu giá đóng ở trên MA và một thanh bên trong tăng, đặt lệnh dừng mua xung quanh mức cao của thanh bên trong. Nếu đóng ở dưới MA và một thanh bên trong giảm, đặt lệnh dừng bán xung quanh mức thấp của thanh bên trong.
  4. Một khi lệnh dừng được kích hoạt, đặt lệnh dừng lỗ và lấy lợi nhuận dựa trên tỷ lệ tỷ lệ dừng lỗ và lấy lợi nhuận được xác định trước.

Phân tích lợi thế

  1. Các thanh bên trong cung cấp tín hiệu đảo ngược có khả năng cao. Sự xuất hiện của các thanh bên trong kép có thể chỉ ra sự đảo ngược giá ngắn hạn.
  2. Được sử dụng với các đường trung bình động để theo hướng xu hướng chính, nó cải thiện xác suất lợi nhuận.
  3. Sử dụng lệnh dừng xung quanh các điểm đột phá trong xu hướng có cơ hội nhập cảnh tốt.

Phân tích rủi ro

  1. Trong các thị trường dao động, các tín hiệu giao dịch từ bên trong các thanh thường có thể dẫn đến tổn thất.
  2. Mức trung bình động như một chỉ số xu hướng cũng có thể cung cấp tín hiệu sai, dẫn đến tổn thất từ giao dịch chống xu hướng.
  3. Nếu mức dừng lỗ được đặt quá chặt chẽ, nó có thể được kích hoạt bởi các tờ giá nhỏ.

Hướng dẫn tối ưu hóa

  1. Kiểm tra các thông số khác nhau của các đường trung bình động như chỉ số đánh giá xu hướng.
  2. Kết hợp các chỉ số khác để lọc các thị trường khác nhau, tránh giao dịch mù nếu không có xu hướng rõ ràng.
  3. Nhận kết hợp tham số tối ưu hơn thông qua phân tích dữ liệu lớn, chẳng hạn như thời gian trung bình động, nhân dừng lỗ, tỷ lệ lợi nhuận vv
  4. Thêm bộ lọc trên các phiên giao dịch và sản phẩm để thích nghi với các khung thời gian và đặc điểm sản phẩm khác nhau.

Tóm lại

Chiến lược Double Inside Bar & Trend sử dụng các tín hiệu giao dịch xác suất cao từ các thanh bên trong kép, được hỗ trợ bởi các đường trung bình động để xác định hướng xu hướng chính để đi dài hoặc ngắn, làm cho nó trở thành một chiến lược đột phá tương đối ổn định.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Kaspricci

//@version=5
strategy(
     title = "Double Inside Bar & Trend Strategy - Kaspricci", 
     shorttitle = "Double Inside Bar & Trend", 
     overlay=true, 
     initial_capital = 100000, 
     currency = currency.USD, 
     default_qty_type = strategy.percent_of_equity, 
     default_qty_value = 100, 
     calc_on_every_tick = true, 
     close_entries_rule = "ANY")

// ================================================ Entry Inputs ======================================================================
headlineEntry   = "Entry Seettings"

maSource        = input.source(defval = close,             group = headlineEntry, title = "MA Source")
maType          = input.string(defval = "HMA",             group = headlineEntry, title = "MA Type", options = ["EMA", "HMA", "SMA", "SWMA", "VWMA", "WMA"])
maLength        = input.int(   defval = 45,    minval = 1, group = headlineEntry, title = "HMA Length")

float ma = switch maType 
    "EMA"  => ta.ema(maSource,  maLength)
    "HMA"  => ta.hma(maSource,  maLength)
    "SMA"  => ta.sma(maSource,  maLength)
    "SWMA" => ta.swma(maSource)
    "VWMA" => ta.vwma(maSource, maLength)
    "WMA"  => ta.wma(maSource,  maLength)

plot(ma, "Trend MA", color.purple)

// ================================================ Trade Inputs ======================================================================
headlineTrade   = "Trade Seettings"

stopLossType    = input.string(defval = "ATR",                         group = headlineTrade,                 title = "Stop Loss Type",            options = ["ATR", "FIX"])
atrLength       = input.int(   defval = 50,   minval = 1,              group = headlineTrade, inline = "ATR", title = "   ATR: Length                 ")
atrFactor       = input.float( defval =  2.5, minval = 0, step = 0.05, group = headlineTrade, inline = "ATR", title = "Factor       ",             tooltip = "multiplier for ATR value")
takeProfitRatio = input.float( defval =  2.0, minval = 0, step = 0.05, group = headlineTrade,                 title = "            TP Ration",     tooltip = "Multiplier for Take Profit calculation")
fixStopLoss     = input.float( defval = 10.0, minval = 0, step = 0.5,  group = headlineTrade, inline = "FIX", title = "   FIX: Stop Loss             ") * 10 // need this in ticks
fixTakeProfit   = input.float( defval = 20.0, minval = 0, step = 0.5,  group = headlineTrade, inline = "FIX", title = "Take Profit",               tooltip = "in pips") * 10 // need this in ticks
useRiskMagmt    = input.bool(  defval = true,                          group = headlineTrade, inline = "RM",  title = "")
riskPercent     = input.float( defval = 1.0,  minval = 0., step = 0.5, group = headlineTrade, inline = "RM",  title = "Risk in %                ", tooltip = "This will overwrite quantity from startegy settings and calculate the trade size based on stop loss and risk percent") / 100

// ================================================ Filter Inputs =====================================================================
headlineFilter  = "Filter Setings"

// date filter
filterDates     = input.bool(defval = false,                                 group = headlineFilter, title = "Filter trades by dates")
startDateTime   = input(defval = timestamp("2022-01-01T00:00:00+0000"), group = headlineFilter, title = "       Start Date & Time")
endDateTime     = input(defval = timestamp("2099-12-31T23:59:00+0000"), group = headlineFilter, title = "       End Date & Time  ")

dateFilter      = not filterDates or (time >= startDateTime and time <= endDateTime)

// session filter
filterSession   = input.bool(title = "Filter trades by session", defval = false, group = headlineFilter)
session         = input(title = "       Session", defval = "0045-2245", group = headlineFilter)

sessionFilter   = not filterSession or time(timeframe.period, session, timezone = "CET")

// ================================================ Trade Entries and Exits =====================================================================

// calculate stop loss
stopLoss        = switch stopLossType
    "ATR" => nz(math.round(ta.atr(atrLength) * atrFactor / syminfo.mintick, 0), 0)
    "FIX" => fixStopLoss

// calculate take profit
takeProfit      = switch stopLossType
    "ATR" => math.round(stopLoss * takeProfitRatio, 0)
    "FIX" => fixTakeProfit


doubleInsideBar = high[2] > high[1] and high[2] > high[0] and low[2] < low[1] and low[2] < low[0]

// highlight mother candel and inside bar candles
bgcolor(doubleInsideBar ? color.rgb(33, 149, 243, 80) : na)
bgcolor(doubleInsideBar ? color.rgb(33, 149, 243, 80) : na, offset = -1)
bgcolor(doubleInsideBar ? color.rgb(33, 149, 243, 80) : na, offset = -2)

var float buyStopPrice  = na
var float sellStopPrice = na

if (strategy.opentrades == 0 and doubleInsideBar and barstate.isconfirmed)
    buyStopPrice  := high[0] // high of recent candle (second inside bar)
    sellStopPrice := low[0] // low of recent candle (second inside bar)

    tradeID = str.tostring(strategy.closedtrades + strategy.opentrades + 1)

    quantity = useRiskMagmt ? math.round(strategy.equity * riskPercent / stopLoss, 2) / syminfo.mintick : na

    commentTemplate = "{0} QTY: {1,number,#.##} SL: {2} TP: {3}"

    if (close > ma)
        longComment = str.format(commentTemplate, tradeID + "L", quantity, stopLoss / 10, takeProfit / 10)
        strategy.entry(tradeID + "L", strategy.long, qty = quantity, stop = buyStopPrice, comment = longComment)
        strategy.exit(tradeID + "SL", tradeID + "L", profit = takeProfit, loss = stopLoss, comment_loss = "SL", comment_profit = "TP")

    if (close < ma)
        shortComment = str.format(commentTemplate, tradeID + "S", quantity, stopLoss / 10, takeProfit / 10)
        strategy.entry(tradeID + "S", strategy.short, qty = quantity, stop = sellStopPrice, comment = shortComment)
        strategy.exit(tradeID + "SL", tradeID + "S", profit = takeProfit, loss = stopLoss, comment_loss = "SL", comment_profit = "TP")

// as soon as the first pending order has been entered the remaing pending order shall be cancelled 
if strategy.opentrades > 0
    currentTradeID = str.tostring(strategy.closedtrades + strategy.opentrades)
    strategy.cancel(currentTradeID + "S")
    strategy.cancel(currentTradeID + "L")


Thêm nữa