Chiến lược giao thoa MA Mondrian đa khung thời gian


Ngày tạo: 2023-11-16 17:28:43 sửa đổi lần cuối: 2023-11-16 17:28:43
sao chép: 0 Số nhấp chuột: 661
1
tập trung vào
1617
Người theo dõi

Chiến lược giao thoa MA Mondrian đa khung thời gian

Chiến lược này chủ yếu sử dụng đường chéo MA của khung thời gian đa dạng (MTF) để xác định hướng xu hướng và kết hợp với các tín hiệu lọc điều kiện cụ thể, chọn mua nhiều hoặc bán ít khi hướng xu hướng rõ ràng hơn, thuộc loại chiến lược theo dõi xu hướng.

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

  1. Nhập phạm vi thời gian phản hồi tùy chỉnh của người dùng.

  2. Nhập biểu đồ Heikin-Ashi có sử dụng tổng hợp âm và dương hay không, mặc định dùng .

  3. Định nghĩa đường MA chậm, đường MA nhanh và đường MA sử dụng khi treo xung động thứ ba.

  4. Bạn có thể tùy chỉnh kiểu MA, chu kỳ thời gian và tham số cho mỗi dòng MA.

  5. Dựa trên đường MA nhanh, đường MA chậm tạo ra tín hiệu mua, đường MA thấp tạo ra tín hiệu bán.

  6. Có thể sử dụng đường MA thứ ba như một bộ lọc đa hướng, chỉ tạo ra tín hiệu mua khi giá đóng cửa vượt quá MA thứ ba.

  7. Sử dụng mô-đun strategy.entry để tự động giao dịch.

  8. Có thể tùy chỉnh số lượng giao dịch cho mỗi tay hoặc sử dụng số lượng giao dịch cố định.

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

  1. Sử dụng kiến trúc MTF, các đường MA khác nhau có thể sử dụng các chu kỳ khác nhau để xác định các đặc điểm xu hướng trên nhiều quy mô thời gian.

  2. Có thể tùy chỉnh loại MA, có thể chọn loại MA trơn để tăng sự ổn định, cũng có thể chọn MA đáp ứng nhanh.

  3. Kết hợp với Heikin-Ashi có thể lọc các đột phá giả.

  4. Có thể thêm một đường MA thứ ba để làm bộ lọc đa hướng, tránh giao dịch biến động.

  5. Các tham số chu kỳ MA có thể được điều chỉnh linh hoạt để phù hợp với các môi trường thị trường khác nhau.

  6. Sử dụng mô-đun strategy.entry để đặt hàng tự động, không cần can thiệp thủ công vào giao dịch.

  7. Hỗ trợ tra lại các tham số tối ưu hóa để tìm kiếm sự kết hợp tham số tốt nhất.

Rủi ro chiến lược

  1. Chiến lược giao dịch MA nhạy cảm với các tín hiệu giả mạo đột phá, có thể tạo ra các giao dịch không cần thiết. Bạn có thể điều chỉnh chu kỳ MA thích hợp hoặc tăng điều kiện lọc để giảm nguy cơ.

  2. Trong tình huống chấn động, đường MA giao nhau thường xuyên và dễ gây mất mát. Các khoảng cách MA có thể được mở rộng thích hợp hoặc kéo dài chu kỳ MA để giảm nguy cơ.

  3. Lượng giao dịch cố định không thể kiểm soát rủi ro, bạn có thể xem xét đặt khối lượng giao dịch theo tỷ lệ phần trăm của số tiền tài khoản.

  4. Chi phí giao dịch và điểm trượt cũng ảnh hưởng đến lợi nhuận của chiến lược. Các tham số có thể được điều chỉnh thích hợp để đảm bảo tỷ lệ chiến thắng đủ cao.

Hướng tối ưu hóa

  1. Kiểm tra các loại MA khác nhau để tìm ra sự kết hợp tốt nhất. MA mịn giúp tăng sự ổn định, MA nhanh giúp tăng sự nhanh nhẹn.

  2. Tối ưu hóa các tham số của MA, kéo dài chu kỳ thích hợp có lợi cho việc nhận ra xu hướng, rút ngắn chu kỳ có thể nâng cao độ nhạy. Tìm điểm cân bằng tối ưu.

  3. Tối ưu hóa điều kiện mở kho, có thể cân nhắc tăng cường lọc đa đầu, tránh mở kho trong thị trường chấn động.

  4. Bạn có thể tối ưu hóa các tham số chu kỳ MA cho một giống cụ thể để tìm các tham số phù hợp nhất với môi trường giao dịch của giống đó.

  5. Có thể xem xét kết hợp với các chỉ số khác như bộ lọc để tăng sự ổn định của chiến lược, chẳng hạn như chỉ số năng lượng khối lượng giao dịch.

  6. Tối ưu hóa các tham số cho dữ liệu phản hồi, tìm các tham số tốt nhất để tăng hiệu quả chiến lược.

Tóm tắt

Chiến lược MA chéo đa khung thời gian nói chung là một trong những chiến lược theo dõi xu hướng phổ biến hơn. Ưu điểm của nó là thực hiện đơn giản, điều chỉnh tham số linh hoạt, có thể thích ứng với các môi trường thị trường khác nhau. Nhưng cũng có một số rủi ro tín hiệu giả.

Mã nguồn chiến lược
/*backtest
start: 2023-11-08 00:00:00
end: 2023-11-15 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(shorttitle="MZ MA Cross",title="MA MTF Cross Strategy", overlay=true, calc_on_order_fills=false, calc_on_every_tick=false, default_qty_type=strategy.fixed, default_qty_value=5,commission_value=0.1)

timeFrameticker  = input('D',type=input.resolution, title="Chart Timeframe")
uha   =input(true, title="Use Heikin Ashi Candles")

// Use only Heikinashi Candles for all calculations
haclose = uha ? security(heikinashi(syminfo.tickerid), timeFrameticker, close) : security(syminfo.tickerid, timeFrameticker, close)
haopen = uha ? security(heikinashi(syminfo.tickerid), timeFrameticker, open) : security(syminfo.tickerid, timeFrameticker, open)
hahigh = uha ? security(heikinashi(syminfo.tickerid), timeFrameticker, high) : security(syminfo.tickerid, timeFrameticker, high)
halow = uha ?security(heikinashi(syminfo.tickerid), timeFrameticker, low) : security(syminfo.tickerid, timeFrameticker, low)

//Backtest dates
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 2021, title = "From Year",       type = input.integer, minval = 1970)
thruMonth = input(defval = 12,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12)
thruDay   = input(defval = 30,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31)
thruYear  = input(defval = 2021, title = "Thru Year",       type = input.integer, minval = 1970)

showDate  = input(defval = true, title = "Show Date Range", type = input.bool)

start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => true

src = security(heikinashi(syminfo.tickerid), timeFrameticker, close)

//  INPUT MA TYPE
slowMAtype = input(title="Slow MA Type", type=input.string, defval="LRC", options=["SMA","EMA","DEMA","TEMA","LRC","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"])
fastMAtype = input(title="Fast MA Type", type=input.string, defval="EDSMA", options=["SMA","EMA","DEMA","TEMA","LRC","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"])
upMAcond =input(false, title="Use Uptrend Conditional 3rd MA for Confirmation")
upMAtype=input(title="Uptrend Conditional MA Type", type=input.string, defval="HMA", options=["SMA","EMA","DEMA","TEMA","LRC","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"])


//  INPUT RESOLUTION
slowMAresolution = input("D",type=input.resolution, title="Slow MA Resolution")
fastMAresolution = input("D",type=input.resolution, title="Fast MA Resolution")
upMAresolution = input("D",type=input.resolution, title="Uptrend Conditional MA Resolution")
haMAslow = uha ? security(heikinashi(syminfo.tickerid), slowMAresolution, close) : security(syminfo.tickerid, slowMAresolution, close)
haMAfast = uha ?security(heikinashi(syminfo.tickerid), fastMAresolution, close) : security(syminfo.tickerid, fastMAresolution, close)
haMAup =  uha ?security(heikinashi(syminfo.tickerid), upMAresolution, close) : security(syminfo.tickerid, upMAresolution, close)

//  INPUT LENGTHS
slowMAlength = input(50, minval=1, title="Slow MA Length")
fastMAlength = input(30, minval=1, title="Fast MA Length")
upMAlength =  input(200, minval=1, title="Uptrend Conditional MA Length")

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////                      MA Function                         //////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

//           Pre-reqs
//
tema(src, len) =>
    ema1 = ema(src, len)
    ema2 = ema(ema1, len)
    ema3 = ema(ema2, len)
    (3 * ema1) - (3 * ema2) + ema3
kidiv = input(defval=1,maxval=4,  title="Kijun MOD Divider")

jurik_phase = input(title="* Jurik (JMA) Only - Phase", type=input.integer, defval=3)
jurik_power = input(title="* Jurik (JMA) Only - Power", type=input.integer, defval=1)
volatility_lookback = input(10, title="* Volatility Adjusted (VAMA) Only - Volatility lookback length")
//                  MF
beta = input(0.8,minval=0,maxval=1,step=0.1,  title="Modular Filter, General Filter Only - Beta")
feedback = input(false, title="Modular Filter Only - Feedback")
z = input(0.5,title="Modular Filter Only - Feedback Weighting",step=0.1, minval=0, maxval=1)
//EDSMA
ssfLength = input(title="EDSMA - Super Smoother Filter Length", type=input.integer, minval=1, defval=20)
ssfPoles = input(title="EDSMA - Super Smoother Filter Poles", type=input.integer, defval=2, options=[2, 3])

//----
//                  EDSMA
get2PoleSSF(src, length) =>
    PI = 2 * asin(1)
    arg = sqrt(2) * PI / length
    a1 = exp(-arg)
    b1 = 2 * a1 * cos(arg)
    c2 = b1
    c3 = -pow(a1, 2)
    c1 = 1 - c2 - c3
    
    ssf = 0.0
    ssf := c1 * src + c2 * nz(ssf[1]) + c3 * nz(ssf[2])

get3PoleSSF(src, length) =>
    PI = 2 * asin(1)

    arg = PI / length
    a1 = exp(-arg)
    b1 = 2 * a1 * cos(1.738 * arg)
    c1 = pow(a1, 2)

    coef2 = b1 + c1
    coef3 = -(c1 + b1 * c1)
    coef4 = pow(c1, 2)
    coef1 = 1 - coef2 - coef3 - coef4

    ssf = 0.0
    ssf := coef1 * src + coef2 * nz(ssf[1]) + coef3 * nz(ssf[2]) + coef4 * nz(ssf[3])

//          MA Main function
ma(type, src, len) =>
    float result = 0
    if type=="TMA"
        result := sma(sma(src, ceil(len / 2)), floor(len / 2) + 1)
    if type=="MF"
        ts=0.,b=0.,c=0.,os=0.
        //----
        alpha = 2/(len+1)
        a = feedback ? z*src + (1-z)*nz(ts[1],src) : src
        //----
        b := a > alpha*a+(1-alpha)*nz(b[1],a) ? a : alpha*a+(1-alpha)*nz(b[1],a)
        c := a < alpha*a+(1-alpha)*nz(c[1],a) ? a : alpha*a+(1-alpha)*nz(c[1],a)
        os := a == b ? 1 : a == c ? 0 : os[1]
        //----
        upper = beta*b+(1-beta)*c
        lower = beta*c+(1-beta)*b 
        ts := os*upper+(1-os)*lower
        result := ts
    if type=="LRC"
        result := linreg(src, len, 0)
    if type=="SMA" // Simple
        result := sma(src, len)
    if type=="EMA" // Exponential
        result := ema(src, len)
    if type=="DEMA" // Double Exponential
        e = ema(src, len)
        result := 2 * e - ema(e, len)
    if type=="TEMA" // Triple Exponential
        e = ema(src, len)
        result := 3 * (e - ema(e, len)) + ema(ema(e, len), len)
    if type=="WMA" // Weighted
        result := wma(src, len)
    if type=="VAMA" // Volatility Adjusted
        /// Copyright © 2019 to present, Joris Duyck (JD)
        mid=ema(src,len)
        dev=src-mid
        vol_up=highest(dev,volatility_lookback)
        vol_down=lowest(dev,volatility_lookback)
        result := mid+avg(vol_up,vol_down)
    if type=="HMA" // Hull
        result := wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))
    if type=="JMA" // Jurik
        /// Copyright © 2018 Alex Orekhov (everget)
        /// Copyright © 2017 Jurik Research and Consulting.
        phaseRatio = jurik_phase < -100 ? 0.5 : jurik_phase > 100 ? 2.5 : jurik_phase / 100 + 1.5
        beta = 0.45 * (len - 1) / (0.45 * (len - 1) + 2)
        alpha = pow(beta, jurik_power)
        jma = 0.0
        e0 = 0.0
        e0 := (1 - alpha) * src + alpha * nz(e0[1])
        e1 = 0.0
        e1 := (src - e0) * (1 - beta) + beta * nz(e1[1])
        e2 = 0.0
        e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
        jma := e2 + nz(jma[1])
        result := jma
    if type=="Kijun v2"
        kijun = avg(lowest(len), highest(len))//, (open + close)/2)
        conversionLine = avg(lowest(len/kidiv), highest(len/kidiv))
        delta = (kijun + conversionLine)/2
        result :=delta
    if type=="McGinley"
        mg = 0.0
        mg := na(mg[1]) ? ema(src, len) : mg[1] + (src - mg[1]) / (len * pow(src/mg[1], 4))
        result :=mg
    if type=="EDSMA"
    
        zeros = src - nz(src[2])
        avgZeros = (zeros + zeros[1]) / 2
        
        // Ehlers Super Smoother Filter 
        ssf = ssfPoles == 2
             ? get2PoleSSF(avgZeros, ssfLength)
             : get3PoleSSF(avgZeros, ssfLength)
        
        // Rescale filter in terms of Standard Deviations
        stdev = stdev(ssf, len)
        scaledFilter = stdev != 0
             ? ssf / stdev
             : 0
        
        alpha = 5 * abs(scaledFilter) / len
        
        edsma = 0.0
        edsma := alpha * src + (1 - alpha) * nz(edsma[1])
        result :=  edsma
    result
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////


//  MA DEFINITION
slowMA = ma(slowMAtype, haMAslow , slowMAlength)
//fastMA = ma(fastMAtype, slowMA , fastMAlength)
fastMA = ma(fastMAtype, haMAfast , fastMAlength)
upMA = ma(upMAtype, haMAup , upMAlength)
closeMA = ma('SMA', src , 2)

//  Strategy Conditions
L1 = crossover(fastMA,slowMA)
L2 = close > upMA
S1 = crossunder(fastMA,slowMA)
S2 = close < upMA
longcondition = upMAcond ? L1 and L2 : L1
shortcondition = upMAcond ? S1 or S2 : S1

//  Plots
color_fill_uptrend = color.new(#4caf50, 80)
color_fill_downtrend = color.new(#c2185b, 80)
plot(slowMA, title='Slow MA', color=color.olive, linewidth=2)
plot(fastMA, title='Fast MA', color=color.teal, linewidth=2)
cls=plot(closeMA, title='Source Line', color=na, linewidth=1)
up = plot(upMA, title='Uptrend Conditional MA', color=color.purple, linewidth=2)
fill(up,cls, color = close > upMA ? color_fill_uptrend : color_fill_downtrend )

//plotshape(longcondition, style = shape.triangleup, color = color.green, location = location.belowbar, text = "Long", size = size.small)
//plotshape(shortcondition, style = shape.triangledown, color = color.red, location = location.abovebar, text = "Short", size = size.small)


strategy.entry(id="long", long = true, when = longcondition and window())
strategy.close("long", when = shortcondition and window())

//if (longcondition)
//    strategy.entry("BUY", strategy.long, when = window())

//if (shortcondition)
//    strategy.entry("SELL", strategy.short, when = window())