Chiến lược giao cắt xu hướng trung bình động


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

Chiến lược giao cắt xu hướng trung bình động

Tổng quan

Chiến lược chéo trung bình di chuyển là một chiến lược động lực sử dụng tín hiệu chéo của hai đường trung bình di chuyển để xác định hướng xu hướng, tạo ra tín hiệu mua và bán. Chiến lược này sử dụng hai đường trung bình di chuyển đơn giản và một đường trung bình di chuyển chỉ số, xác định khoảng trống dựa trên sự chéo của chúng, thuộc chiến lược giao dịch ngắn hạn trung bình.

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

Chiến lược này sử dụng 3 đường trung bình di chuyển:

  • EMA1: Một đường trung bình di chuyển chỉ số có chu kỳ ngắn hơn, đại diện cho đường nhanh
  • SMA1: Đường trung bình di chuyển đơn giản trên một chu kỳ dài hơn, đại diện cho đường chậm
  • SMA2: Một trung bình di chuyển đơn giản trên một chu kỳ dài hơn để đánh giá xu hướng

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

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

Tín hiệu nhập cảnh:

  • Nhiều đầu vào: Làm nhiều hơn khi đi qua đường dây chậm
  • Bước vào không đầu: Bước vào không đầu khi đi qua đường dây chậm

Tín hiệu thoát:

  • Nhiều người rút lui: Đường nhanh dưới đường chậm
  • Xuất thoát không đầu: Đường nhanh bằng đường chậm

Chiến lược này cung cấp nhiều cấu hình tham số, có thể lựa chọn các đường trung bình di chuyển khác nhau để đánh giá các bước vào và thoát ra.

Phân tích lợi thế

Chiến lược này có những ưu điểm sau:

  1. Capture Momentum: Chiến lược nắm bắt xu hướng thị trường
  2. flexible configuration: cung cấp nhiều lựa chọn moving average, có thể được cấu hình linh hoạt
  3. trend filtering: Sử dụng đường trung bình di chuyển dài hạn để đánh giá xu hướng, tránh giao dịch ngược
  4. quản lý rủi ro: có thể cấu hình dừng lỗ và chặn, kiểm soát rủi ro giao dịch đơn lẻ

Phân tích rủi ro

Chiến lược này cũng có những rủi ro sau:

  1. Whipsaws: Có thể xảy ra động đất liên tục trước khi phá vỡ dẫn đến nhiều vụ phá vỡ giả
  2. sensitive to MA parameters: Cài đặt tham số trung bình di chuyển không đúng cách có thể dẫn đến quá thường xuyên hoặc không đủ nhạy cảm
  3. lagging: Bản chất của đường trung bình di chuyển là chậm trễ, có thể bỏ lỡ thời điểm tốt nhất để phá vỡ
  4. No Fundamentals: Chỉ số kỹ thuật, không tính đến cơ bản

Đối với rủi ro whipsaws, có thể điều chỉnh chu kỳ trung bình di chuyển thích hợp; đối với rủi ro nhạy cảm tham số, có thể tối ưu hóa tham số; đối với rủi ro tụt hậu, có thể được tối ưu hóa kết hợp với các chỉ số tiên quyết khác.

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

Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:

  1. Thêm các bộ lọc cho các chỉ số kỹ thuật khác, chẳng hạn như RSI, Blink, để cải thiện chất lượng tín hiệu
  2. Tối ưu hóa các tham số chu kỳ trung bình di chuyển, tìm các tham số tối ưu
  3. Tham gia mô hình học máy để đánh giá xu hướng và độ tin cậy tín hiệu
  4. Kết hợp với khối lượng giao dịch, tránh phá vỡ giá giả trong trường hợp khối lượng thấp
  5. Kết hợp các yếu tố cơ bản để tránh giao dịch theo chu kỳ kinh tế

Tóm tắt

Chiến lược giao chéo đường trung bình di chuyển nói chung là đơn giản và trực tiếp, xác định hướng xu hướng và thời gian tham gia bằng cách giao chéo đường trung bình nhanh và chậm. Ưu điểm của chiến lược này là có thể nắm bắt được động lực, tham số cấu hình linh hoạt, nhưng cũng có một số rủi ro về whipsaw, rủi ro bị tụt hậu.

Mã nguồn chiến lược
/*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)