Стратегия перекрестного использования скользящей средней

Автор:Чао Чжан, Дата: 2023-10-27 16:19:00
Тэги:

img

Обзор

Стратегия пересечения скользящих средних - это стратегия импульса, которая использует сигналы пересечения двойных скользящих средних для определения направления тренда и генерации торговых сигналов.

Логика стратегии

Стратегия использует 3 скользящих средних:

  • EMA1: экспоненциальная скользящая средняя за более короткий период, действующая как быстрая линия
  • SMA1: Простая скользящая средняя длительного периода, действующая как медленная линия
  • SMA2: Простая скользящая средняя более длительного периода, определяющая направление тренда

Стратегия оценивает тенденцию на основе взаимосвязи между EMA1, SMA1 и SMA2:

  • Увеличительный тренд: EMA1 > SMA1 > SMA2
  • Низкий тренд: EMA1 < SMA1 < SMA2

Сигналы входа:

  • Длинный вход: когда быстрая линия пересекает медленную линию
  • Короткий вход: когда быстрая линия пересекается ниже медленной линии

Сигналы выхода:

  • Закрыть длинный: когда быстрая линия пересекает ниже медленной линии
  • Закрыть короткий: когда быстрая линия пересекает медленную линию

Стратегия предоставляет несколько конфигураций параметров с настраиваемыми скользящими средними для входа и выхода.

Анализ преимуществ

Преимущества этой стратегии:

  1. Захватывает импульс: обнаруживает изменения тренда, стратегию импульса
  2. Гибкая конфигурация: предоставляет несколько вариантов MA, гибкую настройку параметров
  3. Фильтрация тренда: использует длительный период MA для определения тренда, избегает контратендерных сделок
  4. Управление рисками: Конфигурируемые средства контроля стоп-лосса и контроля за получением прибыли

Анализ рисков

Риски этой стратегии:

  1. Продолжительное разрывание перед прорывом может вызвать множество ложных сигналов
  2. Чувствительный к параметрам MA: неправильная настройка периодов MA может привести к чрезмерной чувствительности или вялости.
  3. Отставание: естественное отставание скользящих средних, которое может привести к упущению лучшего времени вступления
  4. отсутствие фундаментальных показателей: чисто технические показатели, отсутствие учета фундаментальных показателей

Риск от задержки может быть смягчен путем настройки периодов MA; чувствительность параметров может быть решена путем оптимизации; риск отставания может быть уменьшен путем включения других ведущих индикаторов.

Руководство по оптимизации

Потенциальные оптимизации:

  1. Добавьте другие технические фильтры, такие как RSI, полосы Боллинджера для улучшения качества сигнала
  2. Оптимизировать периоды MA для поиска оптимальных параметров
  3. Включить модели машинного обучения для оценки тенденции и надежности сигнала
  4. Рассмотреть объем торговли, чтобы избежать ложных прорывов при условиях низкого объема
  5. Включить фундаментальные факторы, чтобы избежать торговли против экономических циклов

Заключение

Стратегия пересечения скользящей средней является прямой, оценивая тренд и сроки, пересекая быстрые и медленные МА. Ее преимущество заключается в захвате импульса с гибкой конфигурацией, но существуют риски, такие как винтовка и отставание. С оптимизациями, такими как дополнительные фильтры, она может стать очень практичной количественной торговой стратегией.


/*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)



Больше