In diesem Artikel wird eine algorithmische Handelsstrategie vorgestellt, die durch Verschwemmungsmuster profitable Chancen identifiziert und Preiskreuzung mit gleitendem Durchschnitt als Einstiegssignale verwendet.
Die Kernlogik dieser Strategie beruht auf der Konvergenz zweier unabhängiger Indikatoren:
Ein Umkehrmuster mit zwei Kerzenstäben, bei dem der Körper der zweiten Kerze den Körper der ersten vollständig
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.
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.
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.
Für diese Strategie können folgende Bereiche optimiert werden:
Testen Sie mehr gleitende Durchschnittsarten, um optimale Parametermengen zu finden, wie gewichteten gleitenden Durchschnitt, doppelt glätteten gleitenden Durchschnitt usw.
Hinzufügen von Trendbeurteilungsindikatoren, um zu vermeiden, dass Positionen in seitlichen Märkten eröffnet werden.
Optimieren Sie Stop-Loss-Methoden, um die Wirksamkeit zu verbessern.
Erhöhen Sie die Methoden des maschinellen Lernens, um Kerzenmuster zu beurteilen und die Genauigkeit der Erkennung von Schluck zu verbessern.
Hinzufügen von Optimierungsfunktionen für Anpassungsfunktionen.
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)