Chiến lược giao dịch định lượng theo xu hướng trung bình động

SMMA MA EMA DEMA TEMA WMA VWMA HullMA LSMA ALMA SSMA TMA SL TP
Ngày tạo: 2025-02-20 10:59:37 sửa đổi lần cuối: 2025-02-27 17:49:25
sao chép: 2 Số nhấp chuột: 383
2
tập trung vào
319
Người theo dõi

Chiến lược giao dịch định lượng theo xu hướng trung bình động Chiến lược giao dịch định lượng theo xu hướng trung bình động

Tổng quan

Đây là một chiến lược giao dịch định lượng dựa trên nhiều tín hiệu chéo đường trung bình di chuyển. Chiến lược sử dụng chéo đường trung bình di chuyển của giá mở và giá đóng làm tín hiệu giao dịch và hỗ trợ nhiều loại đường trung bình di chuyển, bao gồm SMMA, EMA, DEMA, v.v.. Chiến lược có khả năng cấu hình cao và có thể tối ưu hóa tham số theo môi trường thị trường và nhu cầu giao dịch khác nhau.

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

Cốt lõi của chiến lược là để xác định điểm chuyển đổi của xu hướng thị trường bằng cách giám sát sự giao thoa giữa đường trung bình di chuyển của giá mở và đường trung bình di chuyển của giá đóng. Khi giá đóng trên đường trung bình mở, tạo ra nhiều tín hiệu; Khi giá đóng dưới đường trung bình mở, tạo ra tín hiệu đóng.

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

  1. Lựa chọn đường trung bình linh hoạt: hỗ trợ 11 loại đường trung bình di động khác nhau, có thể chọn loại đường trung bình phù hợp nhất theo các đặc điểm thị trường khác nhau.
  2. Quản lý rủi ro tốt: Có hệ thống dừng lỗ tích hợp, có thể kiểm soát rủi ro của mỗi giao dịch một cách hiệu quả.
  3. Khả năng thích ứng nhiều chu kỳ: hỗ trợ nhiều chu kỳ thời gian từ phút đến tháng, và có thể tối ưu hóa số lần chu kỳ bằng cách điều chỉnh tham số.
  4. Hỗ trợ hình ảnh: cung cấp chức năng đánh dấu xu hướng màu sắc, giúp dễ dàng hiểu trực quan xu hướng thị trường.

Rủi ro chiến lược

  1. Rủi ro tụt hậu: Đường trung bình di chuyển là một chỉ số tụt hậu, có thể tạo ra tín hiệu tụt hậu trong thị trường biến động mạnh.
  2. Rủi ro thị trường biến động: Trong thị trường biến động ngang, các tín hiệu giao thoa thường xuyên có thể dẫn đến giao dịch quá mức.
  3. Tùy thuộc vào tham số: hiệu quả của chiến lược phụ thuộc rất nhiều vào sự lựa chọn tham số, và các môi trường thị trường khác nhau có thể yêu cầu các kết hợp tham số khác nhau.

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

  1. Chèn tín hiệu: Bạn có thể thêm các chỉ số phụ trợ như số lượng giao thông, tỷ lệ dao động để lọc tín hiệu giả.
  2. Các tham số động: giới thiệu cơ chế tham số thích ứng, điều chỉnh chu kỳ và loại đường trung bình theo động lực của tình trạng thị trường.
  3. Quản lý vị trí: Tối ưu hóa hệ thống quản lý vị trí, điều chỉnh tỷ lệ giữ vị trí theo biến động của thị trường và cường độ xu hướng.

Tóm tắt

Chiến lược này có khả năng cấu hình và quản lý rủi ro mạnh mẽ, nắm bắt các điểm chuyển đổi của xu hướng thị trường thông qua các tín hiệu chéo của nhiều đường trung bình di chuyển. Bằng cách tối ưu hóa tham số và lọc tín hiệu hợp lý, có thể duy trì hiệu suất ổn định trong các môi trường thị trường khác nhau.

Mã nguồn chiến lược
/*backtest
start: 2024-08-01 00:00:00
end: 2025-02-18 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
*/

//@version=6
strategy("Open Close Cross Strategy v6", 
     overlay=true, 
     pyramiding=0, 
     default_qty_type=strategy.percent_of_equity, 
     default_qty_value=10,
     calc_on_every_tick=false)

// === INPUTS ===
var bool useRes = input.bool(true, "Use Alternate Resolution?")
var int intRes = input.int(3, "Multiplier for Alternate Resolution")
var string basisType = input.string("SMMA", "MA Type: ", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "HullMA", "LSMA", "ALMA", "SSMA", "TMA"])
var int basisLen = input.int(8, "MA Period", minval=1)
var int offsetSigma = input.int(6, "Offset for LSMA / Sigma for ALMA", minval=0)
var float offsetALMA = input.float(0.85, "Offset for ALMA", minval=0, step=0.01)
var bool scolor = input.bool(false, "Show coloured Bars to indicate Trend?")
var int delayOffset = input.int(0, "Delay Open/Close MA (Forces Non-Repainting)", minval=0, step=1)
var string tradeType = input.string("BOTH", "What trades should be taken : ", options=["LONG", "SHORT", "BOTH", "NONE"])
var float slPoints = input.float(0, "Initial Stop Loss Points (zero to disable)", minval=0)
var float tpPoints = input.float(0, "Initial Target Profit Points (zero for disable)", minval=0)
var int ebar = input.int(10000, "Number of Bars for Back Testing", minval=0)
var bool dummy = input.bool(false, "- SET to ZERO for Daily or Longer Timeframes")

// Определение таймфрейма для alternate resolution
getAlternateResolution() =>
    timeframe.ismonthly ? str.tostring(timeframe.multiplier * intRes) + "M" :
         timeframe.isweekly ? str.tostring(timeframe.multiplier * intRes) + "W" :
         timeframe.isdaily ? str.tostring(timeframe.multiplier * intRes) + "D" :
         timeframe.isintraday ? str.tostring(timeframe.multiplier * intRes) : "60"

stratRes = getAlternateResolution()

// === MA Functions ===
variant(type, src, len, offSig, offALMA) =>
    float result = switch type
        "EMA" => ta.ema(src, len)
        "DEMA" => 2 * ta.ema(src, len) - ta.ema(ta.ema(src, len), len)
        "TEMA" => 3 * (ta.ema(src, len) - ta.ema(ta.ema(src, len), len)) + ta.ema(ta.ema(ta.ema(src, len), len), len)
        "WMA" => ta.wma(src, len)
        "VWMA" => ta.vwma(src, len)
        "SMMA" => ta.sma(src, len)  // Упрощенная версия SMMA
        "HullMA" => ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len)))
        "LSMA" => ta.linreg(src, len, offSig)
        "ALMA" => ta.alma(src, len, offALMA, offSig)
        "TMA" => ta.sma(ta.sma(src, len), len)
        "SSMA" => 
            a1 = math.exp(-1.414 * math.pi / len)
            b1 = 2 * a1 * math.cos(1.414 * math.pi / len)
            c2 = b1
            c3 = -a1 * a1
            c1 = 1 - c2 - c3
            c1 * (src + nz(src[1])) / 2 + c2 * nz(ta.sma(src, len)[1]) + c3 * nz(ta.sma(src, len)[2])
        => ta.sma(src, len)

// === Series Setup ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma, offsetALMA)
openSeries = variant(basisType, open[delayOffset], basisLen, offsetSigma, offsetALMA)

// Get Alternate resolution Series
closeSeriesAlt = useRes ? request.security(syminfo.tickerid, stratRes, closeSeries, barmerge.gaps_off, barmerge.lookahead_on) : closeSeries
openSeriesAlt = useRes ? request.security(syminfo.tickerid, stratRes, openSeries, barmerge.gaps_off, barmerge.lookahead_on) : openSeries

// === Plotting ===
color trendColor = closeSeriesAlt > openSeriesAlt ? color.green : color.red
color barColor = closeSeries > openSeriesAlt ? color.new(color.lime, 0) : color.new(color.red, 0)

// Перемещаем barcolor в глобальную область видимости
barcolor(scolor ? barColor : na)

var closePlot = plot(closeSeriesAlt, "Close Series", trendColor, 2, plot.style_line)
var openPlot = plot(openSeriesAlt, "Open Series", trendColor, 2, plot.style_line)
fill(closePlot, openPlot, color=trendColor)

// === Trade Conditions ===
xlong = ta.crossover(closeSeriesAlt, openSeriesAlt)
xshort = ta.crossunder(closeSeriesAlt, openSeriesAlt)
longCond = xlong
shortCond = xshort

// === Strategy Logic ===
float tp = tpPoints > 0 ? tpPoints : na
float sl = slPoints > 0 ? slPoints : na

var int lastPositionType = 0  // 1 для long, -1 для short, 0 для нет позиции

if ebar == 0 or (timenow - time) / (timeframe.multiplier * 60000) <= ebar and tradeType != "NONE"
    // Закрытие позиций
    if lastPositionType == 1 and shortCond
        strategy.close("long")
        lastPositionType := 0
        label.new(bar_index, high, "Exit Long", color=color.red, style=label.style_label_down, textcolor=color.white)
    
    if lastPositionType == -1 and longCond
        strategy.close("short")
        lastPositionType := 0
        label.new(bar_index, low, "Exit Short", color=color.green, style=label.style_label_up, textcolor=color.white)
    
    // Открытие новых позиций
    if longCond and tradeType != "SHORT" and lastPositionType == 0
        strategy.entry("long", strategy.long)
        lastPositionType := 1
        label.new(bar_index, low, "Long", color=color.green, style=label.style_label_up, textcolor=color.white)
    
    if shortCond and tradeType != "LONG" and lastPositionType == 0
        strategy.entry("short", strategy.short)
        lastPositionType := -1
        label.new(bar_index, high, "Short", color=color.red, style=label.style_label_down, textcolor=color.white)
    
    // Take Profit и Stop Loss
    if lastPositionType != 0
        strategy.exit("TP/SL", profit=tp, loss=sl)