Chiến lược giao dịch xu hướng động lượng trung bình động hàm mũ nâng cao

EMA ATR RRR GMT
Ngày tạo: 2024-12-11 17:50:14 sửa đổi lần cuối: 2024-12-11 17:50:14
sao chép: 0 Số nhấp chuột: 406
1
tập trung vào
1617
Người theo dõi

Chiến lược giao dịch xu hướng động lượng trung bình động hàm mũ nâng cao

Tổng quan

Chiến lược này là một chiến lược theo dõi xu hướng dựa trên chỉ số di chuyển trung bình (EMA) và chỉ số động lực. Nó kết hợp các tín hiệu phá vỡ động lực và bộ lọc xu hướng EMA để giao dịch khi xu hướng thị trường rõ ràng. Chiến lược bao gồm mô-đun quản lý rủi ro hoàn chỉnh, bộ lọc thời gian giao dịch linh hoạt và tính năng phân tích thống kê chi tiết để nâng cao tính ổn định và độ tin cậy của chiến lược.

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

Logic cốt lõi của chiến lược này dựa trên các yếu tố chính sau:

  1. Nhận dạng tín hiệu động lượng: Bằng cách tính giá trị động lượng trong chu kỳ thời gian tùy chỉnh của người dùng, tạo ra tín hiệu đa khi động lượng vượt ngưỡng hàng trên và tín hiệu trống khi vượt ngưỡng hàng dưới.
  2. Bộ lọc xu hướng EMA: Sử dụng 200 chu kỳ EMA làm cơ sở phán đoán xu hướng, giá được phép làm nhiều hơn trên EMA và giá được phép làm trống dưới EMA.
  3. Bộ lọc thời gian: Có thể thiết lập thời gian giao dịch cụ thể và hỗ trợ điều chỉnh múi giờ GMT để chiến lược phù hợp hơn với thời gian giao dịch của các thị trường khác nhau.
  4. Kiểm soát rủi ro: hỗ trợ thiết lập dừng và dừng dựa trên ATR hoặc tỷ lệ phần trăm cố định và giới hạn số lần giao dịch tối đa mỗi ngày.

Lợi thế chiến lược

  1. Khả năng theo dõi xu hướng mạnh mẽ: thông qua xác nhận kép của EMA và động lực, có thể nắm bắt hiệu quả các xu hướng chính.
  2. Quản lý rủi ro: cung cấp nhiều phương án dừng lỗ, có thể sử dụng dừng động ATR hoặc dừng phần trăm cố định.
  3. Phân tích thống kê toàn diện: theo dõi nhiều chỉ số hiệu suất trong thời gian thực, bao gồm tỷ lệ chiến thắng trên nhiều chuyến bay, tỷ lệ lợi nhuận rủi ro.
  4. Các tham số có thể được điều chỉnh linh hoạt: Các tham số chính có thể được điều chỉnh tối ưu hóa theo các đặc điểm thị trường khác nhau.

Rủi ro chiến lược

  1. Rủi ro của thị trường chấn động: Trong thị trường chấn động ngang có thể tạo ra các tín hiệu phá vỡ giả thường xuyên. Giải pháp được đề xuất: Tăng bộ lọc cho chỉ số rung động hoặc tăng ngưỡng đột phá.

  2. Rủi ro trượt: có thể có một trượt lớn trong thời gian biến động mạnh. Giải pháp được đề xuất: thiết lập phạm vi dừng hợp lý và tránh giao dịch trong thời gian biến động cao.

  3. Nguy cơ giao dịch quá mức: tín hiệu quá thường xuyên có thể dẫn đến giao dịch quá mức. Giải pháp được đề xuất: Thiết lập giới hạn giao dịch tối đa mỗi ngày một cách hợp lý.

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

  1. Tối ưu hóa tham số động: có thể tự động điều chỉnh giảm giá động và chu kỳ EMA theo biến động của thị trường.
  2. Phân tích nhiều chu kỳ thời gian: xác nhận xu hướng bằng cách thêm nhiều chu kỳ thời gian, tăng độ tin cậy tín hiệu.
  3. Nhận biết môi trường thị trường: Thêm mô-đun phân tích tỷ lệ dao động, sử dụng các thiết lập tham số khác nhau trong các môi trường thị trường khác nhau.
  4. Dạng cường độ tín hiệu: Dạng cường độ tín hiệu đột phá, điều chỉnh quy mô nắm giữ tùy theo động lực cường độ tín hiệu.

Tóm tắt

Đây là một chiến lược theo dõi xu hướng được thiết kế hoàn hảo để nắm bắt cơ hội thị trường bằng cách kết hợp động lực phá vỡ và xu hướng EMA. Hệ thống quản lý rủi ro của chiến lược được hoàn chỉnh, có tính năng phân tích thống kê mạnh mẽ, có tính thực tiễn tốt và khả năng mở rộng.

Mã nguồn chiến lược
/*backtest
start: 2019-12-23 08:00:00
end: 2024-12-09 08:00:00
period: 2d
basePeriod: 2d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=6
strategy("[Mustang Algo] EMA Momentum Strategy", 
         shorttitle="[Mustang Algo] Mom Strategy", 
         overlay=true, 
         initial_capital=10000,
         default_qty_type=strategy.fixed,
         default_qty_value=1,
         pyramiding=0,
         calc_on_every_tick=false,
         max_bars_back=5000)

// Momentum Parameters
len = input.int(10, minval=1, title="Length")
src = input(close, title="Source")
momTimeframe = input.timeframe("", title="Momentum Timeframe")
timeframe_gaps = input.bool(true, title="Autoriser les gaps de timeframe")
momFilterLong = input.float(5, title="Filtre Momentum Long", minval=0)
momFilterShort = input.float(-5, title="Filtre Momentum Short", maxval=0)

// EMA Filter
useEmaFilter = input.bool(true, title="Utiliser Filtre EMA")
emaLength = input.int(200, title="EMA Length", minval=1)

// Position Size
contractSize = input.float(1.0, title="Taille de position", minval=0.01, step=0.01)

// Time filter settings
use_time_filter = input.bool(false, title="Utiliser le Filtre de Temps")
start_hour = input.int(9, title="Heure de Début", minval=0, maxval=23)
start_minute = input.int(30, title="Minute de Début", minval=0, maxval=59)
end_hour = input.int(16, title="Heure de Fin", minval=0, maxval=23)
end_minute = input.int(30, title="Minute de Fin", minval=0, maxval=59)
gmt_offset = input.int(0, title="Décalage GMT", minval=-12, maxval=14)

// Risk Management
useAtrSl = input.bool(false, title="Utiliser ATR pour SL/TP")
atrPeriod = input.int(14, title="Période ATR", minval=1)
atrMultiplier = input.float(1.5, title="Multiplicateur ATR pour SL", minval=0.1, step=0.1)
stopLossPerc = input.float(1.0, title="Stop Loss (%)", minval=0.01, step=0.01)
tpRatio = input.float(2.0, title="Take Profit Ratio", minval=0.1, step=0.1)

// Daily trade limit
maxDailyTrades = input.int(2, title="Limite de trades par jour", minval=1)

// Variables for tracking daily trades
var int dailyTradeCount = 0

// Reset daily trade count
if dayofweek != dayofweek[1]
    dailyTradeCount := 0

// Time filter function
is_within_session() =>
    current_time = time(timeframe.period, "0000-0000:1234567", gmt_offset)
    start_time = timestamp(year, month, dayofmonth, start_hour, start_minute, 0)
    end_time = timestamp(year, month, dayofmonth, end_hour, end_minute, 0)
    in_session = current_time >= start_time and current_time <= end_time
    not use_time_filter or in_session

// EMA Calculation
ema200 = ta.ema(close, emaLength)

// Momentum Calculation
gapFillMode = timeframe_gaps ? barmerge.gaps_on : barmerge.gaps_off
mom = request.security(syminfo.tickerid, momTimeframe, src - src[len], gapFillMode)

// ATR Calculation
atr = ta.atr(atrPeriod)

// Signal Detection with Filters
crossoverUp = ta.crossover(mom, momFilterLong)
crossoverDown = ta.crossunder(mom, momFilterShort)

emaUpTrend = close > ema200
emaDownTrend = close < ema200

// Trading Conditions
longCondition = crossoverUp and (not useEmaFilter or emaUpTrend) and is_within_session() and dailyTradeCount < maxDailyTrades and barstate.isconfirmed
shortCondition = crossoverDown and (not useEmaFilter or emaDownTrend) and is_within_session() and dailyTradeCount < maxDailyTrades and barstate.isconfirmed

// Calcul des niveaux de Stop Loss et Take Profit
float stopLoss = useAtrSl ? (atr * atrMultiplier) : (close * stopLossPerc / 100)
float takeProfit = stopLoss * tpRatio

// Modification des variables pour éviter les erreurs de repainting
var float entryPrice = na
var float currentStopLoss = na
var float currentTakeProfit = na

// Exécution des ordres avec gestion des positions
if strategy.position_size == 0
    if longCondition
        entryPrice := close
        currentStopLoss := entryPrice - stopLoss
        currentTakeProfit := entryPrice + takeProfit
        strategy.entry("Long", strategy.long, qty=contractSize)
        strategy.exit("Exit Long", "Long", stop=currentStopLoss, limit=currentTakeProfit)
        dailyTradeCount += 1

    if shortCondition
        entryPrice := close
        currentStopLoss := entryPrice + stopLoss
        currentTakeProfit := entryPrice - takeProfit
        strategy.entry("Short", strategy.short, qty=contractSize)
        strategy.exit("Exit Short", "Short", stop=currentStopLoss, limit=currentTakeProfit)
        dailyTradeCount += 1

// Plot EMA
plot(ema200, color=color.yellow, linewidth=2, title="EMA 200")

// Plot Signals
plotshape(longCondition, title="Long Signal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(shortCondition, title="Short Signal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)

// // Performance Statistics
// var int longWins = 0
// var int longLosses = 0
// var int shortWins = 0
// var int shortLosses = 0

// if strategy.closedtrades > 0
//     trade = strategy.closedtrades - 1
//     isLong = strategy.closedtrades.entry_price(trade) < strategy.closedtrades.exit_price(trade)
//     isWin = strategy.closedtrades.profit(trade) > 0
    
//     if isLong and isWin
//         longWins += 1
//     else if isLong and not isWin
//         longLosses += 1
//     else if not isLong and isWin
//         shortWins += 1
//     else if not isLong and not isWin
//         shortLosses += 1

// longTrades = longWins + longLosses
// shortTrades = shortWins + shortLosses

// longWinRate = longTrades > 0 ? (longWins / longTrades) * 100 : 0
// shortWinRate = shortTrades > 0 ? (shortWins / shortTrades) * 100 : 0
// overallWinRate = strategy.closedtrades > 0 ? (strategy.wintrades / strategy.closedtrades) * 100 : 0

// avgRR = strategy.grossloss != 0 ? math.abs(strategy.grossprofit / strategy.grossloss) : 0

// // Display Statistics
// var table statsTable = table.new(position.top_right, 4, 7, border_width=1)
// if barstate.islastconfirmedhistory
//     table.cell(statsTable, 0, 0, "Type", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 0, "Win", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 0, "Lose", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 3, 0, "Daily Trades", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 0, 1, "Long", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 1, str.tostring(longWins), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 1, str.tostring(longLosses), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 3, 1, str.tostring(dailyTradeCount) + "/" + str.tostring(maxDailyTrades), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 0, 2, "Short", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 2, str.tostring(shortWins), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 2, str.tostring(shortLosses), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 0, 3, "Win Rate", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 3, "Long: " + str.tostring(longWinRate, "#.##") + "%", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 3, "Short: " + str.tostring(shortWinRate, "#.##") + "%", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 0, 4, "Overall", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 4, "Win Rate: " + str.tostring(overallWinRate, "#.##") + "%", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 4, "Total: " + str.tostring(strategy.closedtrades) + " | RR: " + str.tostring(avgRR, "#.##"), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 0, 5, "Trading Hours", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 5, "Start: " + str.format("{0,time,HH:mm}", start_hour * 60 * 60 * 1000 + start_minute * 60 * 1000), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 5, "End: " + str.format("{0,time,HH:mm}", end_hour * 60 * 60 * 1000 + end_minute * 60 * 1000), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 3, 5, "GMT: " + (gmt_offset >= 0 ? "+" : "") + str.tostring(gmt_offset), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 0, 6, "SL/TP Method", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 1, 6, useAtrSl ? "ATR-based" : "Percentage-based", bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 2, 6, useAtrSl ? "ATR: " + str.tostring(atrPeriod) : "SL%: " + str.tostring(stopLossPerc), bgcolor=color.new(color.blue, 90))
//     table.cell(statsTable, 3, 6, "TP Ratio: " + str.tostring(tpRatio), bgcolor=color.new(color.blue, 90))