Quantitative Handelsstrategie mit drei gleitenden Durchschnitten und dem William-Indikator


Erstellungsdatum: 2023-09-28 10:58:16 zuletzt geändert: 2023-09-28 10:58:16
Kopie: 1 Klicks: 833
1
konzentrieren Sie sich auf
1617
Anhänger

Überblick

Die Strategie verwendet die Kombination von drei flachen Moving Averages, einem relativ starken Index (RSI) und dem Williams-Index, um die Trendrichtung des Aktienpreises zu identifizieren und bei einer Trendwende eine Eintrittsgelegenheit zu suchen. Wenn die drei schnellen und langsamen Moving Averages nach oben (nieder) ausgerichtet sind und der RSI über (unter) 50 liegt und ein Williams-Index-Signal nach unten (auf) auftritt, wird ein Plus (ohne) gemacht. Der Stop-Loss-Punkt wird als ein bestimmter Prozentsatz des Eintrittspreises festgelegt, der Stop-Loss-Punkt wird als ein bestimmter Prozentsatz der Eintrittspreise in eine günstige Richtung gesetzt.

Strategieprinzip

Die Strategie nutzt gleitende Moving Averages aus drei verschiedenen Perioden, darunter die Schnelllinie, die Mittellinie und die langsame Linie. Wenn die Schnelllinie die Mittellinie überschreitet, ist der Kurs in eine steigende Tendenz eingetreten. Wenn die Schnelllinie die Mittellinie unterbricht, ist der Kurs in eine absteigende Tendenz eingetreten.

Die Strategie sieht vor, dass die Aktienkurse nach dem Aufwärtstrend die folgenden fünf Bedingungen erfüllen:

  1. Die Kurz-, Mittel- und Langstrecke sind nach oben.
  2. Der RSI ist höher als 50.
  3. Die William-Index-Form zeigt sich nach unten.
  4. Die Aktienpreise sind schrumpf;
  5. Derzeit keine Positionen.

Nach dem Eintritt in einen fallenden Kurs wartet die Strategie, bis die folgenden fünf Bedingungen erfüllt sind, um eine Short-Position zu eröffnen:

  1. Die Kurz-, Mittel- und Langstrecken sind nach unten gerichtet.
  2. RSI unter 50;
  3. Der William-Index zeigt sich nach oben.
  4. Die Aktienpreise sind nach unten gerückt.
  5. Derzeit keine Positionen.

Nach einer Überschneidung setzt die Strategie Stop-Loss- und Stop-Stop-Punkte ein, um das Risiko zu kontrollieren. Konkret ist der Stop-Loss-Punkt ein bestimmter Prozentsatz des Eintrittspreises, der Stop-Stop-Punkt der Preis, der sich nach einem bestimmten Prozentsatz des Eintrittspreises in eine günstige Richtung bewegt.

Strategische Vorteile

  1. In Kombination mit mehreren Indikatoren, die die Eintrittsbestätigung ermöglichen, können falsche Durchbrüche wirksam vermieden werden. Die drei Gleichlinien bestimmen die Trendrichtung, der William-Indikator fängt die Umkehrsignale auf und der RSI filtert die Erschütterungen, um die Genauigkeit der Eintrittsbestätigung zu verbessern.

  2. Die Einrichtung von Stop-Loss-Punkten ermöglicht eine gute Kontrolle des Risiko-Gewinn-Verhältnisses pro Einheit, um zu gewährleisten, dass ein profitabler Handel größer ist als ein verlustbehafteter Handel.

  3. Die Strategie ist klar und verständlich, die Parameter sind vernünftig eingestellt und sind für Händler auf allen Ebenen geeignet.

Strategisches Risiko

  1. In einem wackligen Moment kann der Indikator ein falsches Signal abgeben, was zu unnötigen Eintritten führt. Die Parameter des RSI können durch Optimierung des RSI gefiltert werden, um einen Teil des wackligen Zustands zu filtern.

  2. Bei der Überschneidung von Schnelllinien kann es zu False-Breaks kommen, die in Kombination mit anderen Kennzahlen verwendet werden sollten. Es kann in Erwägung gezogen werden, die Überschneidung zu berücksichtigen.

  3. Ein Stop-Loss, der zu nahe am Einstiegspreis liegt, kann zum Stoppen des Ausstiegs führen, und die Einstellung des Stopp-Losses muss an die richtige Position angepasst werden.

  4. Wenn der Stopppunkt zu weit entfernt von dem Einstiegspreis ist, kann es sein, dass der Ausstieg nicht verhindert wird, und der Stopppunkt muss an die richtige Stelle angepasst werden.

Richtung der Strategieoptimierung

  1. Die Parameterkombinationen für verschiedene Perioden können getestet werden, um die Parameter für die Dreilinie und den RSI zu optimieren.

  2. Andere Kennzahlen, wie der Umsatzindex, können hinzugefügt werden, um zu beurteilen, ob der Umsatz vor dem Durchbruch hervorragend ist.

  3. Die Parameter-Einstellungen für diese Strategie können je nach Sorte getestet werden.

  4. Die Gewinn- und Verlustkurve kann anhand der Rückmessungen erstellt und die Einstellungen für die Stop-Loss-Stopp-Parameter getestet werden.

  5. Vor der Einführung können Sie simulierte Transaktionen ausprobieren und die Parameter optimieren.

Zusammenfassen

Die Strategie als Ganzes ist logisch klar, mit einer Kombination von Indikatoren für die Ein- und Ausstieg, kann die Risiken effektiv zu kontrollieren. Die Strategie Parameter Optimierung Raum ist noch groß, durch die Prüfung der verschiedenen Parameter-Einstellungen, die Strategie kann ein stabilen Gewinn quantitative Trading-Strategie.

Strategiequellcode
/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//This script is a combination of 3 smoothed moving averages, and RSI. When moving averages are aligned upward (downward) and RSI is above (below) 50 and a down (up) William fractal appears, it enters long (short) position. Exiting from long and short entries are defined by StopLoss and TargetProfit.

//@version=5

strategy(title="3SmmaCrossUp + Fractal + RSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, currency=currency.USD, commission_type=strategy.commission.percent, commission_value=0.03)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// inputs

// Global
src = input(close, title="Source")
stopLoss = input.float(defval = 0.1, title = "Stop Loss %", minval = 0, maxval=100, step = 0.1)
targetProfit = input.float(defval = 0.4, title = "Target Profit %", minval = 0, maxval=100, step = 0.1)

// Smooth Moving Average
fastSmmaLen = input.int(21, minval=1, title="Fast Length", group = "Smooth Moving Average")
midSmmaLen = input.int(50, minval=1, title="Mid Length",group = "Smooth Moving Average")
slowSmmaLen = input.int(200, minval=1, title="Slow Length",group = "Smooth Moving Average")

// RSI
rsiLen = input.int(defval=14, title="length", minval=1, maxval=1000, step=1, group="RSI")

// Fractals
n = input.int(title="Periods", defval=2, minval=2, group = "Fractals")

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// initialization

var waitingFirstTradeInUpwardTrend = false
var waitingFirstTradeInDownwardTrend = false

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// functions

smma(ma, src, len) => 
    smma = 0.0
    smma := na(smma[1]) ? ma : (smma[1] * (len - 1) + src) / len
    smma
    
fractals(n, highs, lows) =>
    // UpFractal
    bool upflagDownFrontier = true
    bool upflagUpFrontier0 = true
    bool upflagUpFrontier1 = true
    bool upflagUpFrontier2 = true
    bool upflagUpFrontier3 = true
    bool upflagUpFrontier4 = true
    for i = 1 to n
        upflagDownFrontier := upflagDownFrontier and (highs[n-i] < highs[n])
        upflagUpFrontier0 := upflagUpFrontier0 and (highs[n+i] < highs[n])
        upflagUpFrontier1 := upflagUpFrontier1 and (highs[n+1] <= highs[n] and highs[n+i + 1] < highs[n])
        upflagUpFrontier2 := upflagUpFrontier2 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+i + 2] < highs[n])
        upflagUpFrontier3 := upflagUpFrontier3 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+i + 3] < highs[n])
        upflagUpFrontier4 := upflagUpFrontier4 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+4] <= highs[n] and highs[n+i + 4] < highs[n])
    flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
    
    upFractal = (upflagDownFrontier and flagUpFrontier)
    
    // downFractal
    bool downflagDownFrontier = true
    bool downflagUpFrontier0 = true
    bool downflagUpFrontier1 = true
    bool downflagUpFrontier2 = true
    bool downflagUpFrontier3 = true
    bool downflagUpFrontier4 = true
    
    for i = 1 to n
        downflagDownFrontier := downflagDownFrontier and (lows[n-i] > lows[n])
        downflagUpFrontier0 := downflagUpFrontier0 and (lows[n+i] > lows[n])
        downflagUpFrontier1 := downflagUpFrontier1 and (lows[n+1] >= lows[n] and lows[n+i + 1] > lows[n])
        downflagUpFrontier2 := downflagUpFrontier2 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+i + 2] > lows[n])
        downflagUpFrontier3 := downflagUpFrontier3 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+i + 3] > lows[n])
        downflagUpFrontier4 := downflagUpFrontier4 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+4] >= lows[n] and lows[n+i + 4] > lows[n])
    flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
    
    downFractal = (downflagDownFrontier and flagDownFrontier)
    [upFractal, downFractal]

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// calcs

[upFractal, downFractal] = fractals(n, high, low)


rsiIsHigh = ta.rsi(src, rsiLen) >= 50 


slowMa = ta.sma(src, slowSmmaLen)
midMa = ta.sma(src, midSmmaLen)
fastMa = ta.sma(src, fastSmmaLen)

slowSmma = smma(slowMa ,src, slowSmmaLen)
midSmma = smma(midMa, src, midSmmaLen)
fastSmma = smma(fastMa, src, fastSmmaLen)

isFastSmmaUpward = ta.rising(fastSmma, 1)
isMidSmmaUpward = ta.rising(midSmma, 1)
isSlowSmmaUpward = ta.rising(slowSmma, 1)

isFastSmmaDownward = ta.falling(fastSmma, 1)
isMidSmmaDownward = ta.falling(midSmma, 1)
isSlowSmmaDownward = ta.falling(slowSmma, 1)

slowMovingAveragesAreUpward = isMidSmmaUpward and isSlowSmmaUpward
slowMovingAveragesAreDownward = isMidSmmaDownward and isSlowSmmaDownward

justEnteredUpwardTrend = ta.crossover(fastSmma, midSmma) ? true : false
justEnteredDownwardTrend = ta.crossunder(fastSmma, midSmma) ? true : false

waitingFirstTradeInUpwardTrend := justEnteredUpwardTrend == true ? true : (isFastSmmaDownward or isMidSmmaDownward or isSlowSmmaDownward ? false : waitingFirstTradeInUpwardTrend)
waitingFirstTradeInDownwardTrend := justEnteredDownwardTrend == true ? true : (isFastSmmaUpward or isMidSmmaUpward or isSlowSmmaUpward ? false : waitingFirstTradeInDownwardTrend)

priceCrossedOverSlowMa = ta.crossover(close, slowSmma)
priceCrossedUnderSlowMa = ta.crossunder(close, slowSmma)

enterLongCondition = barstate.isconfirmed and low > fastSmma and rsiIsHigh and (downFractal or priceCrossedOverSlowMa) and waitingFirstTradeInUpwardTrend and strategy.position_size == 0

enterShortCondition = barstate.isconfirmed and high < fastSmma and (not rsiIsHigh) and (upFractal or priceCrossedUnderSlowMa) and waitingFirstTradeInDownwardTrend and strategy.position_size == 0

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// strategy

if(enterLongCondition)
    strategy.entry(id="L", direction=strategy.long)
    waitingFirstTradeInUpwardTrend := false

if(enterShortCondition)
    strategy.entry(id="S", direction=strategy.short)
    waitingFirstTradeInDownwardTrend := false
    
if(strategy.position_size > 0)
    strategy.exit(id="EL", stop=strategy.position_avg_price * (1 - stopLoss/100), limit=strategy.position_avg_price * (1+targetProfit/100)) 
if(strategy.position_size < 0)
    strategy.exit(id="ES", stop=strategy.position_avg_price * (1 + stopLoss/100), limit=strategy.position_avg_price * (1-targetProfit/100)) 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// plots

plot(series = slowSmma, title="Slow SMMA", linewidth=3)
plot(series = midSmma, title="Mid SMMA", linewidth=2)
plot(series = fastSmma, title="Fast SMMA", linewidth=1)
plotchar(series=rsiIsHigh, title='rsiIsHigh', char='')
plotchar(series=justEnteredUpwardTrend, title='justEnteredUpwardTrend', char='')
plotchar(series=justEnteredDownwardTrend, title='justEnteredDownwardTrend', char='')
plotchar(series=waitingFirstTradeInUpwardTrend, title='waitingFirstTradeInUpwardTrend', char='')
plotchar(series=waitingFirstTradeInDownwardTrend, title='waitingFirstTradeInDownwardTrend', char='')
plotchar(series=enterLongCondition, title='enterLongCondition' , char='')
plotchar(series=enterShortCondition, title='enterShortCondition' , char='')
plotshape(series=upFractal, title='upFractal', style=shape.triangleup, location=location.abovebar, color=#009688, size = size.tiny)
plotshape(series=downFractal, title='downFractal', style=shape.triangledown, location=location.belowbar, color=color.red, size = size.tiny)