Algorithmische Handelsstrategie für Momentum-Breakout und Engulfing-Modell


Erstellungsdatum: 2024-01-30 17:20:59 zuletzt geändert: 2024-01-30 17:20:59
Kopie: 0 Klicks: 721
1
konzentrieren Sie sich auf
1617
Anhänger

Algorithmische Handelsstrategie für Momentum-Breakout und Engulfing-Modell

Überblick

Dieser Artikel beschreibt eine algorithmische Handelsstrategie, die Gewinnchancen identifiziert und Preise mit einer Kreuzung mit einem Moving Average als Einstiegssignale verwendet. Die Strategie kombiniert Preistechnik mit Trend-Tracking-Methoden, um Gewinne aus der Bilanzierung und Trendwende zu erzielen.

Grundsätze

Die Kernlogik der Strategie basiert auf der Kombination zweier unzusammenhängender Indikatoren:

  1. Schluckform: Ein Umkehrmodell zweier K-Linien, bei dem die Entität der zweiten K-Line die Entität der ersten K-Line vollständig verschlingt, um die Möglichkeit einer Umkehr zu erkennen.

  2. Preis-Kreuzung mit dem Moving Average: Ein Kaufsignal wird erzeugt, wenn der Preis von unterhalb des Moving Average einen Aufbruch des Cross Moving Average erzeugt; ein Verkaufsignal wird erzeugt, wenn der Preis von über dem Moving Average einen Aufbruch des Cross Moving Average erzeugt.

Die Zeit, zu der ein Umkippen möglich ist, kann durch die Vorstellung von Absorptionsformen beurteilt werden, die in Kombination mit dem Durchschnittspreis als Filtersignal zur Bestimmung des Umkippens verwendet werden, um die Gewinnwahrscheinlichkeit zu erhöhen.

Die Strategie beurteilt die Wahrscheinlichkeit von Verlagerungen und Umkehrungen, indem sie drei Formen des Eintritts verfolgt: Mehrkopf-Eintritt, Leerkopf-Eintritt und Schattenlos-Eintritt. In Kombination mit dem Filtern der Gold- und Dead-Fork-Signale des Preises und des Moving Averages wird schließlich die Richtung der Position festgelegt.

Vorteile

Der größte Vorteil dieser Strategie besteht darin, die Kombination von unabhängigen Indikatoren zu nutzen, um die Entscheidungswirksamkeit zu verbessern. Die Schluckform entscheidet über die Zeit und die Wahrscheinlichkeit eines Marktumkehrens, während der Kurs die Richtung und die Stärke des Umkehrens mit dem beweglichen Durchschnitt überprüft. Beide werden gegenseitig überprüft und können den Handelsverlust durch falsche Signale wirksam reduzieren.

Ein weiterer Vorteil ist die Flexibilität bei der Einstellung der Parameter. Der Benutzer kann selbst Parameter wie die Moving Average-Periode, die Stop-Loss-Marge einstellen, um die Strategie zu optimieren.

Die Gefahr

Trotz der Verwendung von mehreren Indikatoren zur Verbesserung der Entscheidungswirksamkeit besteht bei dieser Strategie ein gewisses Risiko für falsche Signale. Die Schluckform ist kein hundertprozentig zuverlässiges Umkehrsignal, und die Kreuzung des Preises mit dem Moving Average kann nicht wirksam sein.

Darüber hinaus wirkt die Strategie, wie die meisten Technik-Analyse-Strategien, schlechter auf Konfliktsituationen wie z. B. Preisschwankungen. Anhaltende Erschütterungen können einen Stop-Loss auslösen oder die Gewinnspanne verkürzen.

Um das Risiko zu kontrollieren, können die Moving Average-Parameter angepasst werden, um die Stop-Loss-Marge zu optimieren. Die Beteiligung an einer dynamischen Anpassungsstrategie kann auch in Verbindung mit anderen Indikatoren berücksichtigt werden, um Trends und Erschütterungen zu identifizieren.

Optimierungsrichtung

Diese Strategie kann optimiert werden durch folgende Aspekte:

  1. Es werden mehrere Arten von Moving Averages getestet, um die beste Kombination von Parametern zu finden, wie z. B. gewichtete Moving Averages, aufeinanderfolgende Glättungen von Moving Averages usw.

  2. Es ist wichtig, dass die Trendschätzungen erhöht werden, um nicht zu unsicherer Positionen zu kommen.

  3. Optimierung der Stop-Loss-Methode und Verbesserung der Stop-Loss-Effekte. Stop-Loss-Strategien wie Tracking-Stops, Chandelier Exit und andere können in Betracht gezogen werden.

  4. Erhöhung der Genauigkeit der Schluckerkennung durch die Einführung von maschinellen Lernmethoden zur Beurteilung der K-Linienform.

  5. Hinzugefügt wurde eine Funktion zur automatischen Optimierung von Parametern, um die Anpassung von Parametern zu ermöglichen.

Zusammenfassen

Diese Strategie nutzt die Form der Umkehrzeit, um die Umkehrrichtung mit der Kreuzung von Preisen und Moving Averages zu überprüfen. Die Verbesserung der Entscheidungswirksamkeit durch die Integration von Indikatoren ist eine technische Analyse-Strategie. Die Vorteile sind, dass die Indikatoren komplementär sind, die Parameter flexibel sind; Die Nachteile sind, dass es immer noch ein Risiko für falsche Signale gibt und die Schwingung schwach ist. Die Strategie kann durch die Optimierung der Moving Average-Parameter, die Stop-Loss-Methode und die Einbeziehung von Trendurteilen weiter verbessert werden.

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