Комбинированная стратегия на основе количественных осцилляторных индикаторов


Дата создания: 2024-02-27 16:46:42 Последнее изменение: 2024-02-27 16:46:42
Копировать: 3 Количество просмотров: 653
1
Подписаться
1617
Подписчики

Комбинированная стратегия на основе количественных осцилляторных индикаторов

Обзор

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

Стратегический принцип

Эта стратегия рассчитана на основе четырех ключевых показателей.

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

В частности, четыре условия для входа в стратегию: симметричная линия сигналов и циклическая линия сигналов проходят одновременно вверх; первоначальная линия пробивает циклическую линию вверх; первоначальная линия выше восходящей линии мгновенной тенденции; коэффициент соотношения степени Спилмана положительный.

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

Условия “делай пустое” аналогичны условиям “делай многое”, только можно изменить условия суждения.

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

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

В частности, грамотный шокирующий индикатор определяет направление и силу тенденции, циклический индикатор определяет циклические поворотные точки, мгновенная трендовая линия определяет краткосрочную тенденцию, соответствующий коэффициент уровня Спирмана определяет относительности цены. Сочетание этих четырех может дать полную оценку характеристикам рынка в отношении тенденции, цикла, динамики и цены, что дает высоконадёжный торговый сигнал.

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

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

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

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

Направление оптимизации

Эта стратегия может быть оптимизирована в следующих аспектах:

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

  2. Добавление фильтров. Присоединение к MACD, Бринбанду и другим показателям для многослойной фильтрации, что еще больше уменьшает ложные сигналы.

  3. В сочетании с большим количеством временных циклов. В настоящее время существует только один набор параметров, но можно вводить больше параметров, используя методы проверки с использованием нескольких временных осей, чтобы повысить стабильность.

  4. Динамическая корректировка параметров. Добавлен модуль оптимизации параметров, который динамически корректирует параметры показателя в зависимости от различных рыночных условий, чтобы сделать стратегию более адаптивной.

  5. Арбитраж в нескольких сортах. Применение стратегии для различных сортов, чтобы найти возможности для арбитража, чтобы еще больше контролировать риск.

Подвести итог

Эта стратегия использует хитрое сочетание четырех основных показателей Энлеса, чтобы создать всестороннюю торговую стратегию для определения тенденций, циклов, динамики и количественной цены. Ее способность отфильтровывать шум отлична и может производить высококачественные сигналы. Однако отсутствие фильтрации стоп-лостов и вспомогательных показателей делает ее определенным риском.

Исходный код стратегии
/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © simwai

//@version=5
strategy('Ehlers Elegant Oscillator + Ehlers Decycler + Ehlers Instantaneous + Ehlers Spearman Rank', 'Ehlers Combo', overlay=true, margin_long=100, margin_short=100)

// -- Inputs --
inp = input(title='Source', defval=close)
res = input.timeframe(title='Resolution', defval='')
bar = input(title='Allow Bar Color Change?', defval=true)
src = inp
length = input.int(title='Length', defval=20, minval=2, maxval=300)
rmsLength = input.int(title='Rms Length', defval=50, minval=2)
decyclerLength = length

// -- Calculation --
// Ehlers Elegant Oscillator
a1 = math.exp(-1.414 * math.pi / length)
b1 = 2 * a1 * math.cos(1.414 * math.pi / length)
c2 = b1
c3 = -a1 * a1
c1 = 1 - c2 - c3

deriv = src - nz(src[2])
rms = math.avg(math.pow(deriv, 2), rmsLength)
rms := rms != 0 ? math.sqrt(rms) : 0
nDeriv = rms != 0 ? deriv / rms : 0
iFish = nDeriv != 0 ? (math.exp(2 * nDeriv) - 1) / (math.exp(2 * nDeriv) + 1) : 0

ss = 0.0
ss := bar_index < 3 ? 0 : (c1 * ((iFish + nz(iFish[1])) / 2)) + (c2 * nz(ss[1])) + (c3 * nz(ss[2]))
ssSig = ta.wma(ss, length)

slo = ss - ssSig
sig = slo > 0 ? slo > nz(slo[1]) ? 2 : 1 : slo < 0 ? slo < nz(slo[1]) ? -2 : -1 : 0
eoColor = sig > 1 ? color.green : sig > 0 ? color.lime : sig < -1 ? color.maroon : sig < 0 ? color.red : color.black

hline(0)
plot(ssSig, title='EO', color=eoColor, linewidth=2)

// Ehlers Decycler
pi = 2 * math.asin(1)
twoPiPrd = 2 * pi / decyclerLength
alpha = (math.cos(twoPiPrd) + math.sin(twoPiPrd) - 1) / math.cos(twoPiPrd)

dec = 0.0
dec := ((alpha / 2) * (src + nz(src[1]))) + ((1 - alpha) * nz(dec[1]))

decyclerSig = src > dec ? 1 : src < dec ? -1 : 0
decColor = decyclerSig > 0 ? color.green : decyclerSig < 0 ? color.red : color.black
plot(dec, title='Decycler', color=decColor, linewidth=2)

// Ehlers Instantaneous Trendline
getItrend(src, alpha) =>
    Price = src
    Smooth = 0.0
    ITrend = 0.0
    Trigger = 0.0
    
    ITrend := (alpha - alpha * alpha / 4) * Price + .5 * alpha * alpha  * Price[1] - (alpha - .75 * alpha * alpha) * Price[2] + 2 * (1 - alpha) * nz(ITrend[1]) - (1 - alpha) * (1 - alpha) * nz(ITrend[2])
    if(bar_index < 7)
        ITrend := (Price + 2 * Price[1] + Price[2]) / 4
    Trigger := 2 * ITrend - ITrend[2]
    [ITrend, Trigger]

itrendAlpha = 2 / (length + 1) / 2
[iT, Tr] = getItrend(src, itrendAlpha)

iTColor = Tr > iT ? color.aqua : color.maroon
plot(iT, 'Instantaneous Trend', iTColor, 2)

// Ehlers Spearman Rank
priceArray = array.new_float(300, 0.0)
rank = array.new_float(300, 0.0)
for i = 1 to length
    array.set(priceArray, i, nz(src[i - 1]))
    array.set(rank, i, i)

for i = 1 to length
    count = length + 1 - i
    for j = 1 to length - count
        if array.get(priceArray, j + 1) < array.get(priceArray, j)
            tempPrice = array.get(priceArray, j)
            tempRank = array.get(rank, j)
            array.set(priceArray, j, array.get(priceArray, j + 1))
            array.set(rank, j, array.get(rank, j + 1))
            array.set(priceArray, j + 1, tempPrice)
            array.set(rank, j + 1, tempRank)
         
sum = 0.0   
for i = 1 to length
    sum := sum + math.pow(i - array.get(rank, i), 2)
signal = 2 * (0.5 - (1 - ((6 * sum) / (length * (math.pow(length, 2) - 1)))))
spearmanSlo = signal - nz(signal[1])
spearmanSig = spearmanSlo > 0 or signal > 0 ? spearmanSlo > nz(spearmanSlo[1]) ? 2 : 1 : spearmanSlo < 0 or signal < 0 ? spearmanSlo < nz(spearmanSlo[1]) ? -2 : -1 : 0

// -- Signals --
bool enterLong = ta.crossover(sig, 0) and ta.crossover(decyclerSig, 0) and ta.crossover(src, dec) and (src > iT) and iT[1] < iT and spearmanSig > 0
bool enterShort = ta.crossunder(sig, 0) and ta.crossunder(decyclerSig, 0) and ta.crossunder(src, dec) and (src < iT) and iT[1] > iT and spearmanSig < 0
bool exitLong = ta.crossunder(src[100], iT) 
bool exitShort = ta.crossover(src[100], iT)

barcolor(bar and strategy.position_size > 0 ? color.green : bar and strategy.position_size < 0 ? color.red : color.gray)

// -- Long Exits --
strategy.close('long', when=exitLong and strategy.position_size > 0, comment='EXIT_LONG')

// -- Short Exits --
strategy.close('short', when=exitShort and strategy.position_size < 0, comment='EXIT_SHORT')

bool isStrategyEntryEnabled = true
// -- Long Entries --
if (isStrategyEntryEnabled)
    strategy.entry('long', strategy.long, when=enterLong, comment='ENTER_LONG')
else
    strategy.order('long', strategy.long, when=enterLong, comment='ENTER_LONG')

// -- Short Entries --
if (isStrategyEntryEnabled)
    strategy.entry('short', strategy.short, when=enterShort, comment='ENTER_SHORT')
else
    strategy.order('short', strategy.short, when=enterShort, comment='ENTER_SHORT')