Chiến lược chéo trung bình di chuyển

Tác giả:ChaoZhang, Ngày: 2023-10-27 16:19:00
Tags:

img

Tổng quan

Chiến lược chuyển động trung bình là một chiến lược động lực sử dụng các tín hiệu chéo của trung bình chuyển động kép để xác định hướng xu hướng và tạo ra các tín hiệu giao dịch. Nó sử dụng 2 trung bình chuyển động đơn giản và 1 trung bình chuyển động nhân tố, đánh giá dài và ngắn dựa trên sự chéo của chúng, thuộc về một chiến lược giao dịch trung hạn.

Chiến lược logic

Chiến lược sử dụng 3 đường trung bình động:

  • EMA1: Mức trung bình động theo cấp số nhân trong thời gian ngắn hơn, hoạt động như đường nhanh
  • SMA1: Một đường trung bình di chuyển đơn giản dài hơn, đóng vai trò là đường chậm
  • SMA2: Mức trung bình di chuyển đơn giản dài hơn, xác định hướng xu hướng

Chiến lược đánh giá xu hướng dựa trên mối quan hệ giữa EMA1, SMA1 và SMA2:

  • Xu hướng tăng: EMA1 > SMA1 > SMA2
  • Xu hướng giảm: EMA1 < SMA1 < SMA2

Nhãn hiệu nhập cảnh:

  • Nhập dài: Khi đường nhanh vượt qua đường chậm
  • Nhập ngắn: Khi đường nhanh vượt qua đường chậm

Nhãn ra:

  • Đóng dài: Khi đường nhanh vượt qua dưới đường chậm
  • Close short: Khi đường nhanh vượt qua đường chậm

Chiến lược cung cấp nhiều cấu hình tham số, với các đường trung bình động có thể tùy chỉnh để vào và ra.

Phân tích lợi thế

Những lợi thế của chiến lược này:

  1. Bắt được động lực: phát hiện sự thay đổi xu hướng, chiến lược động lực
  2. Cấu hình linh hoạt: Cung cấp nhiều lựa chọn MA, điều chỉnh tham số linh hoạt
  3. Bộ lọc xu hướng: Sử dụng MA dài hạn để xác định xu hướng, tránh giao dịch ngược xu hướng
  4. Quản lý rủi ro: Kiểm soát dừng lỗ và lấy lợi nhuận có thể cấu hình được rủi ro giao dịch duy nhất

Phân tích rủi ro

Những rủi ro của chiến lược này:

  1. Whipsaws: Chấn động kéo dài trước khi đột quỵ có thể gây ra nhiều tín hiệu sai
  2. Nhạy cảm đối với các thông số MA: Điều chỉnh không chính xác các khoảng thời gian MA có thể dẫn đến độ nhạy quá mức hoặc chậm.
  3. Trì trễ: Bản chất chậm vốn có của các đường trung bình động, có thể bỏ lỡ thời gian đầu vào tốt nhất
  4. Không có các chỉ số cơ bản: Chỉ dẫn kỹ thuật hoàn toàn, không xem xét các chỉ số cơ bản

Nguy cơ chọc thép có thể được giảm thiểu bằng cách điều chỉnh thời gian MA; Độ nhạy của tham số có thể được giải quyết bằng cách tối ưu hóa; Nguy cơ trì hoãn có thể được giảm bằng cách kết hợp các chỉ số hàng đầu khác.

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

Tối ưu hóa tiềm năng:

  1. Thêm các bộ lọc kỹ thuật khác như RSI, Bollinger Bands để cải thiện chất lượng tín hiệu
  2. Tối ưu hóa thời gian MA để tìm các thông số tối ưu
  3. Kết hợp các mô hình học máy để đánh giá xu hướng và độ tin cậy tín hiệu
  4. Xem xét khối lượng giao dịch để tránh phá vỡ sai trong điều kiện khối lượng thấp
  5. Bao gồm các yếu tố cơ bản để tránh giao dịch chống lại chu kỳ kinh tế

Kết luận

Chiến lược chuyển động trung bình chéo là thẳng thắn, đánh giá xu hướng và thời gian bằng cách vượt qua các MAs nhanh và chậm. Ưu điểm của nó là nắm bắt đà với các cấu hình linh hoạt, nhưng rủi ro như whipsaw và tụt lại tồn tại. Với các tối ưu hóa như bộ lọc bổ sung, nó có thể trở thành một chiến lược giao dịch định lượng rất thực tế.


/*backtest
start: 2023-09-26 00:00:00
end: 2023-10-26 00:00:00
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/
// © Decam9

//@version=5
strategy(title = "Moving Average Crossover", shorttitle = "MA Crossover Strategy", overlay=true,
     initial_capital = 100000,default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

//Moving Average Inputs
EMA1 = input.int(title="Fast EMA", group = "Moving Averages:", 
     inline = "EMAs", defval=5, minval = 1)
isDynamicEMA = input.bool(title = "Dynamic Exponential Moving Average?", defval = true,
     inline = "EMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")

SMA1 = input.int(title = "Slow SMA", group = "Moving Averages:",
     inline = "SMAs", defval = 10, minval = 1)
isDynamicSMA = input.bool(title = "Dynamic Simple Moving Average?", defval = false,
     inline = "SMAs", group = "Moving Averages:", tooltip = "Changes the source of the MA based on trend")

SMA2 = input.int(title="Trend Determining SMA", group = "Moving Averages:",
     inline = "MAs", defval=13, minval = 1)

//Moving Averages
Trend = ta.sma(close, SMA2)
Fast = ta.ema(isDynamicEMA ? (close > Trend ? low : high) : close, EMA1)
Slow = ta.sma(isDynamicSMA ? (close > Trend ? low : high) : close, SMA1)

//Allowed Entries
islong = input.bool(title = "Long", group = "Allowed Entries:",
     inline = "Entries",defval = true)
isshort = input.bool(title = "Short", group = "Allowed Entries:",
     inline = "Entries", defval= true)

//Entry Long Conditions
buycond = input.string(title="Buy when", group = "Entry Conditions:", 
     inline = "Conditions",defval="Fast-Slow Crossing", 
     options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     
intrendbuy = input.bool(title = "In trend", defval = true, group = "Entry Conditions:",
     inline = "Conditions", tooltip = "In trend if price is above SMA 2")

//Entry Short Conditions
sellcond = input.string(title="Sell when", group = "Entry Conditions:", 
     inline = "Conditions2",defval="Fast-Slow Crossing", 
     options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     
intrendsell = input.bool(title = "In trend",defval = true, group = "Entry Conditions:",
     inline = "Conditions2", tooltip = "In trend if price is below SMA 2?")

//Exit Long Conditions
closebuy = input.string(title="Close long when", group = "Exit Conditions:", 
     defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])

//Exit Short Conditions
closeshort = input.string(title="Close short when", group = "Exit Conditions:", 
     defval="Fast-Slow Crossing", options=["Fast-Slow Crossing", "Fast-Trend Crossing","Slow-Trend Crossing"])
     

//Filters
filterlong =input.bool(title = "Long Entries", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
filtershort =input.bool(title = "Short Entries", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
filterend =input.bool(title = "Exits", inline = 'linefilt', group = 'Apply Filters to', 
     defval = true)
usevol =input.bool(title = "", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = false)
rvol = input.int(title = "Volume >", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = 1)
len_vol = input.int(title = "Avg. Volume Over Period", inline = 'linefiltvol', group = 'Relative Volume Filter:', 
     defval = 30, minval = 1,
     tooltip="The current volume must be greater than N times the M-period average volume.")
useatr =input.bool(title = "", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = false)
len_atr1 = input.int(title = "ATR", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = 5, minval = 1)
len_atr2 = input.int(title = "> ATR", inline = 'linefiltatr', group = 'Volatility Filter:', 
     defval = 30, minval = 1,
     tooltip="The N-period ATR must be greater than the M-period ATR.")
usersi =input.bool(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = false)
rsitrhs1 = input.int(title = "", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = 0, minval=0, maxval=100)
rsitrhs2 = input.int(title = "< RSI (14) <", inline = 'linersi', group = 'Overbought/Oversold Filter:', 
     defval = 100, minval=0, maxval=100,
     tooltip="RSI(14) must be in the range between N and M.")
issl =  input.bool(title = "SL", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = false)
slpercent =  input.float(title = ", %", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = 10, minval=0.0)
istrailing =  input.bool(title = "Trailing", inline = 'linesl1', group = 'Stop Loss / Take Profit:', 
     defval = false)
istp =  input.bool(title = "TP", inline = 'linetp1', group = 'Stop Loss / Take Profit:', 
     defval = false)
tppercent =  input.float(title = ", %", inline = 'linetp1', group = 'Stop Loss / Take Profit:', 
     defval = 20)
     
//Conditions for Crossing
fscrossup = ta.crossover(Fast,Slow)
fscrossdw = ta.crossunder(Fast,Slow)
ftcrossup = ta.crossover(Fast,Trend)
ftcrossdw = ta.crossunder(Fast,Trend)
stcrossup = ta.crossover(Slow,Trend)
stcrossdw = ta.crossunder(Slow,Trend)

//Defining in trend
uptrend = Fast >= Slow and Slow >= Trend
downtrend = Fast <= Slow and Slow <= Trend
justCrossed = ta.cross(Fast,Slow) or ta.cross(Slow,Trend)


//Entry Signals
crosslong = if intrendbuy
    (buycond =="Fast-Slow Crossing" and uptrend ? fscrossup:(buycond =="Fast-Trend Crossing" and uptrend ? ftcrossup:(buycond == "Slow-Trend Crossing" and uptrend ? stcrossup : na))) 
else
    (buycond =="Fast-Slow Crossing"?fscrossup:(buycond=="Fast-Trend Crossing"?ftcrossup:stcrossup))

crossshort = if intrendsell
    (sellcond =="Fast-Slow Crossing" and downtrend ? fscrossdw:(sellcond =="Fast-Trend Crossing" and downtrend ? ftcrossdw:(sellcond == "Slow-Trend Crossing" and downtrend ? stcrossdw : na))) 
else
    (sellcond =="Fast-Slow Crossing"?fscrossdw:(buycond=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitlong = (closebuy =="Fast-Slow Crossing"?fscrossdw:(closebuy=="Fast-Trend Crossing"?ftcrossdw:stcrossdw))
crossexitshort = (closeshort =="Fast-Slow Crossing"?fscrossup:(closeshort=="Fast-Trend Crossing"?ftcrossup:stcrossup))


// Filters
rsifilter = usersi?(ta.rsi(close,14) > rsitrhs1 and ta.rsi(close,14) < rsitrhs2):true
volatilityfilter = useatr?(ta.atr(len_atr1) > ta.atr(len_atr2)):true
volumefilter = usevol?(volume > rvol*ta.sma(volume,len_vol)):true
totalfilter = volatilityfilter and volumefilter and rsifilter

//Filtered signals
golong  = crosslong  and islong  and (filterlong?totalfilter:true) 
goshort = crossshort and isshort and (filtershort?totalfilter:true)
endlong  = crossexitlong and (filterend?totalfilter:true)
endshort = crossexitshort and (filterend?totalfilter:true)

// Entry price and TP
startprice = ta.valuewhen(condition=golong or goshort, source=close, occurrence=0)
pm = golong?1:goshort?-1:1/math.sign(strategy.position_size)
takeprofit = startprice*(1+pm*tppercent*0.01)
// fixed stop loss
stoploss = startprice * (1-pm*slpercent*0.01)
// trailing stop loss
if istrailing and strategy.position_size>0
    stoploss := math.max(close*(1 - slpercent*0.01),stoploss[1])
else if istrailing and strategy.position_size<0
    stoploss := math.min(close*(1 + slpercent*0.01),stoploss[1])
    
if golong and islong
    strategy.entry("long",   strategy.long )
if goshort and isshort
    strategy.entry("short",  strategy.short)
if endlong
    strategy.close("long")
if endshort
    strategy.close("short")

// Exit via SL or TP
strategy.exit(id="sl/tp long", from_entry="long", stop=issl?stoploss:na, 
              limit=istp?takeprofit:na)
strategy.exit(id="sl/tp short",from_entry="short",stop=issl?stoploss:na, 
              limit=istp?takeprofit:na)



Thêm nữa