Двойная скользящая средняя кроссоверная алгоритмическая стратегия торговли

Автор:Чао Чжан, Дата: 2023-10-30 15:27:34
Тэги:

img

Обзор

Эта стратегия в основном использует принцип пересечения скользящей средней, в сочетании с сигналами обратного движения индикатора RSI и пользовательским алгоритмом пересечения двойной скользящей средней для реализации трендовой торговли. Стратегия отслеживает две скользящие средние различных периодов, с более быстрым MA отслеживающим краткосрочные тенденции и более медленным MA отслеживающим долгосрочные тенденции. Когда более быстрый MA пересекает более медленный MA вверх, это сигнализирует о восходящем тренде и шансе на покупку. Когда более быстрый MA пересекает ниже более медленного MA, это сигнализирует о конце краткосрочного тренда и о возможности закрыть позиции.

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

  1. Вычислить две группы скользящих средних VWAP с различными параметрами, представляющими долгосрочные и краткосрочные тенденции соответственно.

    • Медленный Тенкансен и Киюнсен рассчитывают долгосрочную тенденцию
    • Fast Tenkansen и Kijunsen рассчитывают краткосрочный тренд
  2. Примите средние значения Тенкансена и Киюнсена как медленные и быстрые средние значения.

  3. Вычислить полосы Боллинджера для выявления консолидаций и вырывов.

    • Средняя линия - это среднее значение быстрого и медленного МА
    • Верхние и нижние полосы используются для обнаружения прорывов
  4. Расчет TSV для определения объемной энергии

    • TSV больше 0 указывает на рост объема
    • TSV выше EMA указывает на укрепление импульса
  5. Расчет РСИ для выявления условий перекупа и перепродажи

    • RSI ниже 30 - это зона перепродажи для покупки
    • RSI выше 70 - это перекупленная зона для продажи
  6. Условия въезда:

    • Быстрый MA пересекает медленный MA
    • Закрытые перекрестки над верхней полосой Боллинджера
    • TSV больше 0 и EMA
    • RSI ниже 30
  7. Условия выхода:

    • Быстрый MA пересекает медленный MA
    • RSI более 70

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

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

  2. RSI избегает покупки перекупленных и продажи перепроданных зон

  3. TSV обеспечивает достаточный объем, поддерживающий тенденцию

  4. Болинджерские полосы определяют ключевые точки прорыва

  5. Комбинация индикаторов помогает отфильтровать ложные прорывы

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

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

  2. Параметры RSI нуждаются в оптимизации, в противном случае могут пропустить точки покупки/продажи

  3. ТСВ также очень чувствителен к параметрам, требует тщательного тестирования.

  4. Разрыв BB верхней полосы может быть ложным прорыв, нуждается в проверке

  5. Трудно оптимизировать многие показатели, риски перенастройки

  6. Недостаточные данные поезда/испытания могут привести к установке кривой

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

  1. Проверьте больше периодов для поиска лучших комбинаций параметров

  2. Попробуйте другие индикаторы, такие как MACD, KD заменить или комбинировать с RSI

  3. Использовать анализ ходьбы вперед для оптимизации параметров

  4. Добавление стоп-лосса для контроля потери от одной сделки

  5. Рассмотрим модели машинного обучения для прогнозирования сигналов

  6. Настройка параметров для разных рынков, не перегружайте набор параметров

Заключение

Эта стратегия фиксирует долгосрочные и краткосрочные тренды с использованием двойных скользящих средних и фильтрует сигналы с помощью RSI, TSV, полос Боллинджера и многого другого. Преимущество заключается в торговле в соответствии с долгосрочным восходящим импульсом. Но она также несет в себе риски ложного сигнала, требующие дальнейшей настройки параметров и остановки потерь для снижения рисков. В целом, сочетание следующего тренда и среднего реверсии дает хорошие результаты в долгосрочных восходящих тенденциях, но параметры нуждаются в корректировке для разных рынков.


/*backtest
start: 2022-10-23 00:00:00
end: 2023-10-29 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// @version=4

// Credits

// "Vwap with period" code which used in this strategy to calculate the leadLine was written by "neolao" active on https://tr.tradingview.com/u/neolao/
// "TSV" code which used in this strategy was written by "liw0" active on https://www.tradingview.com/u/liw0. The code is corrected by "vitelot" December 2018.
// "Vidya" code which used in this strategy was written by "everget" active on https://tr.tradingview.com/u/everget/

strategy("HYE Combo Market [Strategy] (Vwap Mean Reversion + Trend Hunter)", overlay = true, initial_capital = 1000, default_qty_value = 100, default_qty_type = strategy.percent_of_equity, commission_value = 0.025)
  
//Strategy inputs

source = input(title = "Source", defval = close, group = "Mean Reversion Strategy Inputs")
smallcumulativePeriod = input(title = "Small VWAP", defval = 8, group = "Mean Reversion Strategy Inputs")
bigcumulativePeriod = input(title = "Big VWAP", defval = 10, group = "Mean Reversion Strategy Inputs")
meancumulativePeriod = input(title = "Mean VWAP", defval = 50, group = "Mean Reversion Strategy Inputs")
percentBelowToBuy = input(title = "Percent below to buy %", defval = 2, group = "Mean Reversion Strategy Inputs")
rsiPeriod = input(title = "Rsi Period", defval = 2, group = "Mean Reversion Strategy Inputs")
rsiEmaPeriod = input(title = "Rsi Ema Period", defval = 5, group = "Mean Reversion Strategy Inputs") 
rsiLevelforBuy = input(title = "Maximum Rsi Level for Buy", defval = 30, group = "Mean Reversion Strategy Inputs")
slowtenkansenPeriod = input(9, minval=1, title="Slow Tenkan Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
slowkijunsenPeriod = input(13, minval=1, title="Slow Kijun Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
fasttenkansenPeriod = input(3, minval=1, title="Fast Tenkan Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
fastkijunsenPeriod = input(7, minval=1, title="Fast Kijun Sen VWAP Line Length", group = "Trend Hunter Strategy Inputs")
BBlength = input(20, minval=1, title= "Bollinger Band Length", group = "Trend Hunter Strategy Inputs")
BBmult = input(2.0, minval=0.001, maxval=50, title="Bollinger Band StdDev", group = "Trend Hunter Strategy Inputs")
tsvlength  = input(20, minval=1, title="TSV Length", group = "Trend Hunter Strategy Inputs")
tsvemaperiod = input(7, minval=1, title="TSV Ema Length", group = "Trend Hunter Strategy Inputs")
length = input(title="Vidya Length", type=input.integer, defval=20, group = "Trend Hunter Strategy Inputs") 
src = input(title="Vidya Source", type=input.source, defval= hl2 , group = "Trend Hunter Strategy Inputs")

// Vidya Calculation 

getCMO(src, length) =>
    mom = change(src)
    upSum = sum(max(mom, 0), length)
    downSum = sum(-min(mom, 0), length)
    out = (upSum - downSum) / (upSum + downSum)
    out

cmo = abs(getCMO(src, length))

alpha = 2 / (length + 1)

vidya = 0.0
vidya := src * alpha * cmo + nz(vidya[1]) * (1 - alpha * cmo)

// Make input options that configure backtest date range 

startDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31, group = "Strategy Date Range")
startMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12, group = "Strategy Date Range")
startYear = input(title="Start Year", type=input.integer,
     defval=2000, minval=1800, maxval=2100, group = "Strategy Date Range")

endDate = input(title="End Date", type=input.integer, 
     defval=31, minval=1, maxval=31, group = "Strategy Date Range")
endMonth = input(title="End Month", type=input.integer,
     defval=12, minval=1, maxval=12, group = "Strategy Date Range") 
endYear = input(title="End Year", type=input.integer,
     defval=2021, minval=1800, maxval=2100, group = "Strategy Date Range")
     
inDateRange = true
// Mean Reversion Strategy Calculation 

typicalPriceS = (high + low + close) / 3
typicalPriceVolumeS = typicalPriceS * volume
cumulativeTypicalPriceVolumeS = sum(typicalPriceVolumeS, smallcumulativePeriod)
cumulativeVolumeS = sum(volume, smallcumulativePeriod)
smallvwapValue = cumulativeTypicalPriceVolumeS / cumulativeVolumeS

typicalPriceB = (high + low + close) / 3
typicalPriceVolumeB = typicalPriceB * volume
cumulativeTypicalPriceVolumeB = sum(typicalPriceVolumeB, bigcumulativePeriod)
cumulativeVolumeB = sum(volume, bigcumulativePeriod)
bigvwapValue = cumulativeTypicalPriceVolumeB / cumulativeVolumeB 

typicalPriceM = (high + low + close) / 3
typicalPriceVolumeM = typicalPriceM * volume
cumulativeTypicalPriceVolumeM = sum(typicalPriceVolumeM, meancumulativePeriod)
cumulativeVolumeM = sum(volume, meancumulativePeriod)
meanvwapValue = cumulativeTypicalPriceVolumeM / cumulativeVolumeM

rsiValue = rsi(source, rsiPeriod)
rsiEMA   = ema(rsiValue, rsiEmaPeriod)
buyMA = ((100 - percentBelowToBuy) / 100) * bigvwapValue[0]

inTrade = strategy.position_size > 0
notInTrade = strategy.position_size <= 0

if(crossunder(smallvwapValue, buyMA) and rsiEMA < rsiLevelforBuy and close < meanvwapValue and inDateRange and notInTrade)
    strategy.entry("BUY-M", strategy.long)

if(close > meanvwapValue or not inDateRange)
    strategy.close("BUY-M")
    
// Trend Hunter Strategy Calculation

// Slow Tenkan Sen Calculation

typicalPriceTS = (high + low + close) / 3
typicalPriceVolumeTS = typicalPriceTS * volume
cumulativeTypicalPriceVolumeTS = sum(typicalPriceVolumeTS, slowtenkansenPeriod)
cumulativeVolumeTS = sum(volume, slowtenkansenPeriod)
slowtenkansenvwapValue = cumulativeTypicalPriceVolumeTS / cumulativeVolumeTS

// Slow Kijun Sen Calculation

typicalPriceKS = (high + low + close) / 3
typicalPriceVolumeKS = typicalPriceKS * volume
cumulativeTypicalPriceVolumeKS = sum(typicalPriceVolumeKS, slowkijunsenPeriod)
cumulativeVolumeKS = sum(volume, slowkijunsenPeriod)
slowkijunsenvwapValue = cumulativeTypicalPriceVolumeKS / cumulativeVolumeKS

// Fast Tenkan Sen Calculation

typicalPriceTF = (high + low + close) / 3
typicalPriceVolumeTF = typicalPriceTF * volume
cumulativeTypicalPriceVolumeTF = sum(typicalPriceVolumeTF, fasttenkansenPeriod)
cumulativeVolumeTF = sum(volume, fasttenkansenPeriod)
fasttenkansenvwapValue = cumulativeTypicalPriceVolumeTF / cumulativeVolumeTF

// Fast Kijun Sen Calculation

typicalPriceKF = (high + low + close) / 3
typicalPriceVolumeKF = typicalPriceKS * volume
cumulativeTypicalPriceVolumeKF = sum(typicalPriceVolumeKF, fastkijunsenPeriod)
cumulativeVolumeKF = sum(volume, fastkijunsenPeriod)
fastkijunsenvwapValue = cumulativeTypicalPriceVolumeKF / cumulativeVolumeKF

// Slow LeadLine Calculation
 
lowesttenkansen_s = lowest(slowtenkansenvwapValue, slowtenkansenPeriod)
highesttenkansen_s = highest(slowtenkansenvwapValue, slowtenkansenPeriod)

lowestkijunsen_s = lowest(slowkijunsenvwapValue, slowkijunsenPeriod)
highestkijunsen_s = highest(slowkijunsenvwapValue, slowkijunsenPeriod)

slowtenkansen = avg(lowesttenkansen_s, highesttenkansen_s)
slowkijunsen = avg(lowestkijunsen_s, highestkijunsen_s)
slowleadLine = avg(slowtenkansen, slowkijunsen)

// Fast LeadLine Calculation 
 
lowesttenkansen_f = lowest(fasttenkansenvwapValue, fasttenkansenPeriod)
highesttenkansen_f = highest(fasttenkansenvwapValue, fasttenkansenPeriod)

lowestkijunsen_f = lowest(fastkijunsenvwapValue, fastkijunsenPeriod)
highestkijunsen_f = highest(fastkijunsenvwapValue, fastkijunsenPeriod) 

fasttenkansen = avg(lowesttenkansen_f, highesttenkansen_f)
fastkijunsen = avg(lowestkijunsen_f, highestkijunsen_f)
fastleadLine = avg(fasttenkansen, fastkijunsen)

// BBleadLine Calculation
 
BBleadLine = avg(fastleadLine, slowleadLine)

// Bollinger Band Calculation
 
basis = sma(BBleadLine, BBlength)
dev = BBmult * stdev(BBleadLine, BBlength)
upper = basis + dev  
lower = basis - dev 

// TSV Calculation

tsv = sum(close>close[1]?volume*(close-close[1]):close<close[1]?volume*(close-close[1]):0,tsvlength)
tsvema = ema(tsv, tsvemaperiod)

// Rules for Entry & Exit  

if(fastleadLine > fastleadLine[1] and slowleadLine > slowleadLine[1] and tsv > 0 and tsv > tsvema and close > upper and close > vidya and inDateRange and notInTrade)
    strategy.entry("BUY-T", strategy.long)
 
if((fastleadLine < fastleadLine[1] and slowleadLine < slowleadLine[1]) or not inDateRange)
    strategy.close("BUY-T")

// Plots 

plot(meanvwapValue, title="MEAN VWAP", linewidth=2, color=color.yellow)

//plot(vidya, title="VIDYA", linewidth=2, color=color.green)

//colorsettingS = input(title="Solid Color Slow Leadline", defval=false, type=input.bool)
//plot(slowleadLine, title = "Slow LeadLine", color = colorsettingS ? color.aqua : slowleadLine > slowleadLine[1] ? color.green : color.red, linewidth=3)

//colorsettingF = input(title="Solid Color Fast Leadline", defval=false, type=input.bool)
//plot(fastleadLine, title = "Fast LeadLine", color = colorsettingF ? color.orange : fastleadLine > fastleadLine[1] ? color.green : color.red, linewidth=3)

//p1 = plot(upper, "Upper BB", color=#2962FF)
//p2 = plot(lower, "Lower BB", color=#2962FF)
//fill(p1, p2, title = "Background", color=color.blue)

//plot(smallvwapValue, color=#13C425, linewidth=2)
//plot(bigvwapValue, color=#CA1435, linewidth=2)


Больше