Aktionszone ATR Umkehrfolge Quant Strategie

Schriftsteller:ChaoZhang, Datum: 23.11.2023
Tags:

img

Übersicht

Die Hauptidee dieser Strategie besteht darin, die Action Zone und den ATR-Indikator zu kombinieren, um bei einem goldenen Kreuz lang zu gehen und bei einem toten Kreuz kurz zu gehen. Es setzt auch Stop-Loss- und Take-Profit-Preise fest. Wenn ein Preisumkehrsignal auftritt, wird es umgekehrte Positionen öffnen, um eine umgekehrte Bestellfunktion zu erreichen.

Grundsätze

  1. Bei der Berechnung der Long- und Short-Signale wird die schnelle EMA über der langsamen EMA als bullisch, ansonsten aber als bearish bezeichnet.
  2. Wenn es keine Position gibt, geh lang auf goldenes Kreuz und kurz auf totes Kreuz.
  3. Wenn bereits eine Position vorhanden ist, schließt es, wenn ein Umkehrsignal auftritt, zuerst die aktuelle Position und öffnet dann eine neue Position in die entgegengesetzte Richtung.
  4. Der Stop-Loss-Preis wird anhand des ATR-Kanals angepasst, um ein geringes Stop-Loss-Risiko zu gewährleisten.
  5. Wenn der Preis in die überkaufte oder überverkaufte Zone eintritt, wird der Stop-Loss-Preis auf den höchsten oder niedrigsten Preis des letzten Balkens angepasst, um nicht gefangen zu werden.

Vorteile

  1. Die Kombination von Action Zone und ATR ermöglicht es, während der Trends Positionen entlang des Trends zu eröffnen und einen Stop-Loss zu setzen und rechtzeitig Gewinn zu erzielen.
  2. Durch die Implementierung der Reverse-Order-Funktionalität können bei Preisumkehrungen schnell Richtungen gewechselt werden, wodurch beiderseitige Preisschwankungen für höhere Renditen voll ausgenutzt werden.
  3. Der ATR-Stop-Loss-Mechanismus kann das Risiko eines einzigen Stop-Losss wirksam kontrollieren und insgesamt eine hohe Gewinnrate erzielen.
  4. Kombiniert mit Überkauf- und Überverkaufsschätzungen, um nicht von plötzlichen Ereignissen gefangen zu werden.

Risiken und Lösungen

  1. Umgekehrte Aufträge können zu einer übermäßigen Häufigkeit von Transaktionen in Bereichsgebundenen Märkten führen, was die Handelskosten und die Stop-Loss-Wahrscheinlichkeit erhöht.
    • Lösung: Erhöhung der Mindestaufbewahrungsdauer zur Verringerung von Rückschlägen in den bereichsgebundenen Märkten.
  2. Änderungen der ATR-Werte können dazu führen, dass der Stop-Loss-Bereich zu groß oder zu klein ist.
    • Lösung: Einstellen der Stoppverlustdistanz nach den Echtzeit-ATR-Werten.
  3. Eine unsachgemäße Einstellung der Parameter kann zu einer zu hohen Handelsfrequenz oder zu schlechten Signalleffekten führen.
    • Lösung: Entsprechende Parameterkombinationen für verschiedene Sorten wählen.

Optimierungsrichtlinien

  1. Optimieren Sie die Parameter-Einstellungen, um die beste Parameterkombination zu finden.
  2. Hinzufügen von Hilfstechnischen Indikatoren zum Filter zur Verbesserung der Signalqualität.
  3. Hinzufügen von Modulen für die Kapitalverwaltung zur Verknüpfung der Positionsgröße mit dem Gesamtvermögen des Kontos.
  4. Hinzufügen einer zeitrahmenübergreifenden Analyse zur Verbesserung der Strategieleistung mit mehr Informationen.

Zusammenfassung

Diese Strategie integriert die Vorteile von Action Zone und ATR-Indikatoren, um einen effizienten Zwei-Wege-Handel zu erzielen. Der Umkehr-Order-Mechanismus und der intelligente ATR-Stop-Loss können die Preisschwankungen voll ausnutzen. Die Optimierung der Parameter-Einstellungen und die Einbeziehung mehrerer Indikatoren können die Strategieleistung weiter verbessern. Diese Strategie eignet sich für den Hochfrequenz-Zwei-Wege-Handel und kann auch als Hilfsentscheidungswerkzeug dienen.


/*backtest
start: 2023-10-24 00:00:00
end: 2023-11-23 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © fenirlix

//@version=5
// Strategy parameter incl. position size, commission and initial capital
strategy("ACTIONZONE-ATR REVERSEORDER STRATEGY", "ACTIONZONEATR-REVERSEORDER", overlay=true
     )

// User Input Variable
fastMaInput     = input.int(12, "Fast MA Period", minval=2, step=1)
slowMaInput     = input.int(26, "Fast MA Period", minval=2, step=1)

atrLengthInput  = input.int(14, "ATR length", minval=2,step=1)
atrInnerMultInput = input.float(1, "atr inner multiplier", minval=0.1, step=0.1)
atrMidMultInput = input.float(2, "atr inner multiplier", minval=0.1, step=0.1) //***** MOST OF RISK MANAGEMENT LOGIC BASE ON THIS INPUT *****//
atrOuterMultInput = input.float(3, "atr inner multiplier", minval=0.1, step=0.1)

// Backtesting Date range
startYearInput      = input.int(2021, "Start Year", minval=1900, maxval=2100, step=1)
startMonthInput     = input.int(12, "Start Month", minval=1, maxval=12, step=1)
startDateInput      = input.int(1, "Start Day", minval=1, maxval=31, step=1)
setEndRangeInput    = input.bool(false, "Using Specific End Test Date") //Set specific End date or use present(end of candle) data
endYearInput        = input.int(2022, "End Year", minval=1900, maxval=2100, step=1)
endMonthInput       = input.int(1, "End Month", minval=1, maxval=12, step=1)
endDateInput        = input.int(31, "End Day", minval=1, maxval=31, step=1)

startDate = timestamp(syminfo.timezone, startYearInput, startMonthInput, startDateInput)
endDate = timestamp(syminfo.timezone, endYearInput, endMonthInput, endDateInput)
inDateRange = time >= startDate //Set backtest date range to present data
if setEndRangeInput
    inDateRange and time <= endDate //set backtest date range to specific date

// minimum position hold period (to get rid of false signal in sideway trend)
minHoldInput = input.int(8, 'Minimum position Hold Limit', minval=1, maxval=365, step=1) // Set Minimum Position Hold

var bool reverseToLong = false // Assign reverse order operator
var bool reverseToShort = false // Assign reverse order operator

// Indicator Declaration
fastEma = ta.ema(close, fastMaInput)
slowEma = ta.ema(close, slowMaInput)
atr = ta.atr(atrLengthInput)

// Declare trend of asset
isBullish = fastEma > slowEma
isBearish = fastEma <= slowEma

// Record position hold length, to limit minimum hold period(candle)
var int hold_length = 0
if strategy.opentrades > 0 or strategy.opentrades < 0
    hold_length := hold_length + 1
else
    hold_length := 0

// create permanent variable of stop price
var float longStopPrice = na
var float shortStopPrice = na
    
// Chart-Indicator COLOR declaration
REDBEAR     = color.new(color.red, 80)
GREENBULL   = color.new(color.green, 80)

greenLong = isBullish and close > fastEma
yellowLong = isBullish and close < fastEma
blueShort = isBearish and close > fastEma
redShort = isBearish and close < fastEma

// assign oversold, overbought condition(in this case, price over middle atr plus/minus fastEma)
overBand = high[1] > fastEma + (2*atr)
underBand = low[1] < fastEma - (2*atr)

// Strategy

// Main Entry Condition
goLong = isBullish and isBullish[1] == 0
goShort = isBearish and isBearish[1] == 0

inPosition = strategy.position_size != 0
minHoldPeriod = hold_length > minHoldInput ? true : false

// Entry Condition
if not inPosition and inDateRange and barstate.isconfirmed == true //compute after close of the bar to avoid repainting
    if goLong or reverseToLong // Long if longcondition or reverse order receive.
        strategy.entry('long', strategy.long)
        longStopPrice := fastEma - (atr * 2) // Set stop loss price
        reverseToLong := false // Reset reverse order status
    
    else if goShort or reverseToShort
        strategy.entry('short', strategy.short)
        shortStopPrice := fastEma + (atr * 2)
        reverseToShort := false
// Take profit and Set Higher Stop 
if inPosition and minHoldPeriod and barstate.isconfirmed == true // check if we're in position and pass minimum hold period, confirm no repainting
    if strategy.position_size > 0
        // if exit position by Sellcondition(which is the same as ShortCondition), Exit Long position and make Short order(by set reverse order to true)
        strategy.close('long', when=goShort, comment='exitLong(' + str.tostring(hold_length) + ')')
        reverseToShort := true
        if overBand //If overbought condition met, set Stop price to LAST LOW, and not reverse any position
            longStopPrice := low[1]
            reverseToShort := false
    else if strategy.position_size < 0
        strategy.close('short', when=goLong, comment='exitShort(' + str.tostring(hold_length) + ')')
        reverseToLong := true
        if underBand
            shortStopPrice := high[1]
            reverseToLong := false
// Stop Loss and Set calculate stop loss using Atr Channel
if inPosition 
    if strategy.position_size > 0
        if fastEma - (atr * atrMidMultInput) > longStopPrice // set long stop price to the higher of latest long stop price and ATR lower channel
            longStopPrice := fastEma - (atr * atrMidMultInput)
        strategy.exit('Long Stop atr ', 'long', stop=longStopPrice)
    else if strategy.position_size < 0
        if fastEma + (atr * atrMidMultInput) < shortStopPrice
            shortStopPrice := fastEma + (atr * atrMidMultInput)
        strategy.exit('Short Stop atr ', 'short', stop=shortStopPrice)

// Plotting
fastLine = plot(fastEma, title='fast ema line', linewidth=1, color=isBullish ? color.green : color.red)
slowLine = plot(slowEma, title='slow ema line', linewidth=2, color= isBullish? color.green : color.red)
atrUpperLine1 = plot(fastEma + (atr * atrInnerMultInput), title='ATR Upperline1', color=color.new(color.black,85))
atrLowerLine1 = plot(fastEma - (atr * atrInnerMultInput), title='ATR Lowerline1', color=color.new(color.black,85))
atrUpperLine2 = plot(fastEma + (atr * atrMidMultInput), title='ATR Upperline2', color=color.new(color.black,75))
atrLowerLine2 = plot(fastEma - (atr * atrMidMultInput), title='ATR Lowerline2', color=color.new(color.black,75))
atrUpperLine3 = plot(fastEma + (atr * atrOuterMultInput), title='ATR Upperline3', color=color.new(color.black,50))
atrLowerLine3 = plot(fastEma - (atr * atrOuterMultInput), title='ATR Lowerline3', color=color.new(color.black,50))

plot(longStopPrice, color=strategy.position_size > 0 ? color.red : na, linewidth=2)
plot(shortStopPrice, color=strategy.position_size < 0 ? color.red : na, linewidth=2)

//  Filling
fill(fastLine, slowLine, color=isBullish ? GREENBULL : REDBEAR)
fill(atrUpperLine3, atrLowerLine3, color=inPosition and (minHoldInput - hold_length > 0) ? color.new(color.blue,90): na)

barColor = switch
    greenLong => color.green
    yellowLong =>  color.yellow
    blueShort => color.blue
    redShort => color.red
    => color.black
barcolor(color=barColor)

// Fill background to distinguish inactive time(Zulu time)
nightTime = time(timeframe.period, "1500-0100") ? color.new(color.black, 95): na
bgcolor(nightTime)


Mehr