Стратегия пересечения скользящих средних - это стратегия импульса, которая использует сигналы пересечения двойных скользящих средних для определения направления тренда и генерации торговых сигналов.
Стратегия использует 3 скользящих средних:
Стратегия оценивает тенденцию на основе взаимосвязи между EMA1, SMA1 и SMA2:
Сигналы входа:
Сигналы выхода:
Стратегия предоставляет несколько конфигураций параметров с настраиваемыми скользящими средними для входа и выхода.
Преимущества этой стратегии:
Риски этой стратегии:
Риск от задержки может быть смягчен путем настройки периодов MA; чувствительность параметров может быть решена путем оптимизации; риск отставания может быть уменьшен путем включения других ведущих индикаторов.
Потенциальные оптимизации:
Стратегия пересечения скользящей средней является прямой, оценивая тренд и сроки, пересекая быстрые и медленные МА. Ее преимущество заключается в захвате импульса с гибкой конфигурацией, но существуют риски, такие как винтовка и отставание. С оптимизациями, такими как дополнительные фильтры, она может стать очень практичной количественной торговой стратегией.
/*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)