Алгоритмическая торговая стратегия модели прорыва и поглощения импульса


Дата создания: 2024-01-30 17:20:59 Последнее изменение: 2024-01-30 17:20:59
Копировать: 0 Количество просмотров: 721
1
Подписаться
1617
Подписчики

Алгоритмическая торговая стратегия модели прорыва и поглощения импульса

Обзор

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

Принципы

Основная логика этой стратегии основана на сочетании двух не связанных показателей:

  1. Поглощающая форма: обращение двух K-линий, где объект второй K-линии полностью поглощает объект первой K-линии, используется для выявления возможности обращения.

  2. Пересечение цены с подвижным средним: при появлении пересечения цены с подвижным средним вверх, создается сигнал покупки; при появлении пересечения цены с подвижным средним вверх, создается сигнал продажи.

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

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

Преимущества

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

Еще одним преимуществом является гибкость параметров. Пользователь может самостоятельно настроить такие параметры, как цикл скользящей средней, стоп-лосс, оптимизировать стратегию.

Риск

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

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

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

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

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

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

  2. Добавление трендовых показателей, чтобы избежать рискованных позиций. Например, ADX, Bollinger Bands и т.д.

  3. Оптимизация методов остановки, повышение эффективности остановки. Можно рассмотреть стратегию остановки, такую как отслеживание остановки, выход Чанделиера.

  4. Добавление методов машинного обучения для определения формы K-линий, повышение точности распознавания проглощений.

  5. Добавлена функция автоматической оптимизации параметров для самостоятельной адаптации параметров.

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

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

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

//@version=4
//@author=Daveatt

StrategyName = "BEST Engulfing + MA"
ShortStrategyName = "BEST Engulfing + MA"

strategy(title=StrategyName, shorttitle=ShortStrategyName, overlay=true)

includeEngulfing = true

includeMA = true
source_ma = input(title="Source Price vs MA", type=input.source, defval=close)
typeofMA = input(title="Type of MA", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "KMA", "TMA", "HullMA", "DEMA", "TEMA"])
length_ma = input(32, title = "MA Length", type=input.integer)

// ---------- Candle components and states
GreenCandle = close > open
RedCandle = close < open
NoBody = close==open
Body = abs(close-open)


// bullish conditions
isBullishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
isBullishEngulfing2 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) <= min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]

// bearish conditions
isBearishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]
isBearishEngulfing2 = max(close[1],open[1]) >= max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]

// consolidation of conditions
isBullishEngulfing = isBullishEngulfing1 or isBullishEngulfing2
isBearishEngulfing = isBearishEngulfing1 or isBearishEngulfing2

//isBullishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
//isBearishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]

Engulf_curr = 0 - barssince(isBearishEngulfing) + barssince(isBullishEngulfing)
Engulf_Buy = Engulf_curr < 0 ? 1 : 0
Engulf_Sell = Engulf_curr > 0 ? 1 : 0


// Price vs MM


smma(src, len) =>
    smma = 0.0
    smma := na(smma[1]) ? sma(src, len) : (smma[1] * (len - 1) + src) / len
    smma

ma(smoothing, src, length) => 
    if smoothing == "RMA"
        rma(src, length)
    else
        if smoothing == "SMA"
            sma(src, length)
        else 
            if smoothing == "EMA"
                ema(src, length)
            else 
                if smoothing == "WMA"
                    wma(src, length)
				else
					if smoothing == "VWMA"
						vwma(src, length)
					else
						if smoothing == "SMMA"
						    smma(src, length)
						else
							if smoothing == "HullMA"
								wma(2 * wma(src, length / 2) - wma(src, length), round(sqrt(length)))
							else
								if smoothing == "LSMA"
									src
								else
								    if smoothing == "KMA"
								        xPrice = src
                                        xvnoise = abs(xPrice - xPrice[1])
                                        nfastend = 0.666
                                        nslowend = 0.0645
                                        nsignal = abs(xPrice - xPrice[length])
                                        nnoise = sum(xvnoise, length)
                                        nefratio = iff(nnoise != 0, nsignal / nnoise, 0)
                                        nsmooth = pow(nefratio * (nfastend - nslowend) + nslowend, 2) 
                                        nAMA = 0.0
                                        nAMA := nz(nAMA[1]) + nsmooth * (xPrice - nz(nAMA[1]))
                                        nAMA
								    else
								        if smoothing == "TMA"
									        sma(sma(close, length), length)
						                else
							                if smoothing == "DEMA"
							                    2 * src - ema(src, length)
							                else
							                    if smoothing == "TEMA"
							                        3 * (src - ema(src, length)) + ema(ema(src, length), length) 
							                    else
		    							            src
		    							                

MA = ma(typeofMA, source_ma, length_ma)

plot(MA, color=#006400FF, title="MA breakout", linewidth=3)

macrossover  = crossover (source_ma, MA)
macrossunder = crossunder(source_ma, MA)

since_ma_buy = barssince(macrossover)
since_ma_sell = barssince(macrossunder)
macross_curr = 0 - since_ma_sell + since_ma_buy
bullish_MA_cond = macross_curr < 0 ?  1 : 0
bearish_MA_cond = macross_curr > 0 ? 1  : 0

posUp = (Engulf_Buy ? 1 : 0) + (bullish_MA_cond ? 1 : 0) 
posDn = (Engulf_Sell ? 1 : 0) + (bearish_MA_cond ? 1 : 0) 

conditionUP = posUp == 2 and posUp[1] < 2
conditionDN = posDn == 2 and posDn[1] < 2


sinceUP = barssince(conditionUP)
sinceDN = barssince(conditionDN)

// primary-first signal of the trend
nUP = crossunder(sinceUP,sinceDN)
nDN = crossover(sinceUP,sinceDN)


// and the following secondary signals

// save of the primary signal
sinceNUP = barssince(nUP)
sinceNDN = barssince(nDN)

buy_trend   = sinceNDN > sinceNUP
sell_trend  = sinceNDN < sinceNUP

// engulfing by
barcolor(nUP ? color.orange : na, title="Bullish condition")
barcolor(nDN ? color.yellow : na, title="Bearish condition")

isLong  = nUP
isShort = nDN

long_entry_price    = valuewhen(nUP, close, 0)
short_entry_price   = valuewhen(nDN, close, 0)

longClose   = close[1] < MA
shortClose  = close[1] > MA

///////////////////////////////////////////////
//* Backtesting Period Selector | Component *//
///////////////////////////////////////////////


StartYear = input(2017, "Backtest Start Year",minval=1980)
StartMonth = input(1, "Backtest Start Month",minval=1,maxval=12)
StartDay = input(1, "Backtest Start Day",minval=1,maxval=31)
testPeriodStart = timestamp(StartYear,StartMonth,StartDay,0,0)

StopYear = input(2020, "Backtest Stop Year",minval=1980)
StopMonth = input(12, "Backtest Stop Month",minval=1,maxval=12)
StopDay = input(31, "Backtest Stop Day",minval=1,maxval=31)
testPeriodStop = timestamp(StopYear,StopMonth,StopDay,0,0)

testPeriod() => true


//////////////////////////
//* Profit Component *//
//////////////////////////

input_tp_pips = input(600, "Backtest Profit Goal (in USD)",minval=0)
input_sl_pips = input(300, "Backtest STOP Goal (in USD)",minval=0)


tp = buy_trend? long_entry_price + input_tp_pips : short_entry_price - input_tp_pips
sl = buy_trend? long_entry_price - input_sl_pips : short_entry_price + input_sl_pips


long_TP_exit  = buy_trend and high >= tp
short_TP_exit = sell_trend and low <= tp

plot(tp, title="TP", style=plot.style_circles, linewidth=3, color=color.blue)
plot(sl, title="SL", style=plot.style_circles, linewidth=3, color=color.red)

if testPeriod()
    strategy.entry("Long", 1, when=isLong)
    strategy.close("Long", when=longClose )
    strategy.exit("XL","Long", limit=tp,  when=buy_trend, stop=sl)


if testPeriod()
    strategy.entry("Short", 0,  when=isShort)
    strategy.close("Short", when=shortClose )
    strategy.exit("XS","Short", when=sell_trend, limit=tp, stop=sl)