Momentum Breakout und Engulfing Pattern Algorithmische Handelsstrategie

Schriftsteller:ChaoZhang, Datum: 2024-01-30 17:20:59
Tags:

img

Übersicht

In diesem Artikel wird eine algorithmische Handelsstrategie vorgestellt, die durch Verschwemmungsmuster profitable Chancen identifiziert und Preiskreuzung mit gleitendem Durchschnitt als Einstiegssignale verwendet.

Grundsätze

Die Kernlogik dieser Strategie beruht auf der Konvergenz zweier unabhängiger Indikatoren:

  1. Ein Umkehrmuster mit zwei Kerzenstäben, bei dem der Körper der zweiten Kerze den Körper der ersten vollständig engulfs, verwendet, um Umkehrmöglichkeiten zu identifizieren.

  2. Preiskreuzung mit gleitendem Durchschnitt: Ein Kaufsignal wird erzeugt, wenn der Preis von unten über die gleitende Durchschnittslinie überschreitet; ein Verkaufssignal ist, wenn der Preis von oben unter die gleitende Durchschnittslinie überschreitet.

Durch die Beurteilung des Zeitpunkts einer möglichen Marktumkehr mit Abdeckungsmustern und die Verwendung von Preis-Crossover mit gleitendem Durchschnitt als Bestätigungssignale kann die Gewinnwahrscheinlichkeit verbessert werden.

Insbesondere verfolgt diese Strategie drei Arten von Verschwemmungsmustern - bullisch, bärisch und ohne Schattenschwemmung, um mögliche Konsolidierung und Umkehrungen zu bestimmen.

Vorteile

Der größte Vorteil dieser Strategie besteht darin, die Konvergenz unabhängiger Indikatoren zu nutzen, um die Entscheidungswirksamkeit zu verbessern. Engulfing-Muster beurteilen den Zeitpunkt und die Wahrscheinlichkeit einer Umkehr des Marktes; während der Preis-Crossover mit dem gleitenden Durchschnitt die Richtung und die Dynamik der Umkehr überprüft. Die beiden validieren sich gegenseitig und können die durch falsche Signale verursachten Handelsverluste effektiv reduzieren.

Ein weiterer Vorteil ist die Flexibilität der Parameter-Einstellungen. Benutzer können Parameter wie gleitende Durchschnittsperiode und Stop-Loss-Bereich festlegen, um die Strategie selbst zu optimieren.

Risiken

Obwohl die Verwendung mehrerer Indikatoren das Urteilsvermögen verbessert, besteht in dieser Strategie immer noch ein gewisses Risiko für falsche Signale. Engulfing-Muster sind nicht zu 100% zuverlässige Umkehrsignale, und bei einem Preis-Crossover mit dem gleitenden Durchschnitt gibt es auch Ausfallszenarien. All dies kann zu Verlusten durch vorzeitige Eröffnungspositionen führen.

Darüber hinaus ist es, wie die meisten technischen Analyse-Strategien, auch in widersprüchlichen Trendmärkten wie Ranging und Konsolidierung schlecht.

Um Risiken zu kontrollieren, können Parameter wie gleitender Durchschnittszeitraum und Stop-Loss-Bereich entsprechend angepasst werden.

Optimierungsrichtlinien

Für diese Strategie können folgende Bereiche optimiert werden:

  1. Testen Sie mehr gleitende Durchschnittsarten, um optimale Parametermengen zu finden, wie gewichteten gleitenden Durchschnitt, doppelt glätteten gleitenden Durchschnitt usw.

  2. Hinzufügen von Trendbeurteilungsindikatoren, um zu vermeiden, dass Positionen in seitlichen Märkten eröffnet werden.

  3. Optimieren Sie Stop-Loss-Methoden, um die Wirksamkeit zu verbessern.

  4. Erhöhen Sie die Methoden des maschinellen Lernens, um Kerzenmuster zu beurteilen und die Genauigkeit der Erkennung von Schluck zu verbessern.

  5. Hinzufügen von Optimierungsfunktionen für Anpassungsfunktionen.

Schlussfolgerung

Diese Strategie identifiziert Umkehrzeit mit Engulfing-Mustern und überprüft die Richtung, indem Preis-Crossover mit gleitendem Durchschnitt verwendet wird. Durch die Verbesserung der Entscheidungswirksamkeit durch Indikatorenkonvergenz ist es ein technischer Analyseansatz. Zu den Vorteilen gehören komplementäre Indikatoren und flexible Parameter. Zu den Nachteilen gehören Risiken von falschen Signalen und Schwäche in seitlichen Märkten. Möglichkeiten zur weiteren Verbesserung dieser Strategie gehören die Optimierung von gleitenden Durchschnittsparametern, Stop-Loss-Methoden, das Hinzufügen von Trendfilterindikatoren usw.


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


Mehr