Dynamischer gleitender Durchschnittswert

Schriftsteller:ChaoZhang, Datum: 2023-11-13 10:27:54
Tags:

img

Übersicht

Die Schlüsselidee dieser Strategie besteht darin, mehrere gleitende Durchschnitte basierend auf dem Ratio OCHL Averager-Indikator verschiedener Zeitrahmen zu erstellen und Handelssignale basierend auf dem Crossover zu generieren.

Strategie Logik

Die Strategie verwendet zwei Ratio OCHL Averager-Indikatoren mit unterschiedlichen Zeitrahmen als schnelle und langsame Linien.

b = abs(close-open)/(high - low)
c = min(max(b, 0), 1)  
Ratio OCHL Averager = c*close + (1-c)*previous Ratio OCHL Averager

Hier stellt b die Intraday-Preisbewegung dar und c ist die normalisierte b. Der Ratio OCHL Averager enthält die offenen, schließenden, hohen und niedrigen Preise, um den gleitenden Durchschnitt zu erstellen.

Die Strategie setzt einen kürzeren Zeitraum für die schnelle Linie und einen längeren Zeitraum für die langsame Linie. Ein Kaufsignal wird erzeugt, wenn die schnelle Linie über die langsame Linie überschreitet, und ein Verkaufssignal, wenn die schnelle Linie unterhalb überschreitet.

Vorteile

  1. Der Ratio OCHL Averager glättet die Preisdaten aus und filtert Marktlärm aus, wodurch das Handelssignal zuverlässiger wird.

  2. Die Kombination von zwei gleitenden Durchschnitten mit verschiedenen Zeitrahmen kann den Beginn eines neuen Trends besser erkennen.

  3. Die Zeiten der schnellen und der langsamen Linie können an unterschiedliche Marktbedingungen angepasst werden.

  4. Die Strategie ist einfach und intuitiv, leicht zu verstehen und umzusetzen.

  5. Stop-Loss und Take-Profit können flexibel festgelegt werden, um Risiken zu kontrollieren.

Risiken

  1. Bei der Überschreitung des gleitenden Durchschnitts können übermäßige falsche Signale erzeugt werden. Für die Filtration können andere technische Indikatoren erforderlich sein.

  2. Die Zeiträume der schnellen und der langsamen Linie sollten vernünftig gewählt werden, da dies sonst Auswirkungen auf die Strategieergebnisse haben kann.

  3. Es handelt sich dabei um eine Trendstrategie, die nicht für einen Bereichsmarkt geeignet ist.

  4. Der Stop-Loss- und der Take-Profit-Ausgleich sollte angemessen angepasst werden, um Verluste zu reduzieren und das Gewinnniveau zu optimieren.

Optimierungsrichtlinien

  1. Es sollte in Betracht gezogen werden, Impulsindikatoren wie MACD, KDJ zur Signalfiltration und Qualitätsverbesserung zu kombinieren.

  2. Versuche verschiedene Kombinationen von schnellen und langsamen Linienperioden, um die optimalen Parameter zu finden.

  3. Optimieren Sie den Stop-Loss und nehmen Sie Profit basierend auf Backtest-Ergebnissen.

  4. Es sollte in Betracht gezogen werden, die Parameter unter bestimmten Marktbedingungen dynamisch anzupassen, z. B. den Zeitraum in einem Bereichsmarkt zu verlängern.

Schlussfolgerung

Die Strategie hat eine klare Logik der Verwendung von schnellen und langsamen gleitenden Durchschnitts-Crossover, um die Trendrichtung zu bestimmen. Es ist eine dynamische Trendstrategie, die für den mittelfristigen Handel geeignet ist. Es gibt noch viel Raum für Optimierungen durch Parameter-Tuning, Signalfiltration usw. Insgesamt ist es eine flexible und praktische Trendhandelsstrategie.


/*backtest
start: 2023-11-05 00:00:00
end: 2023-11-12 00:00:00
period: 3m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="[XC] Adaptive Strategy V3 - Ratio OCHL Averager no repaint",shorttitle="R_OHCL", overlay=true, currency=currency.EUR,initial_capital=10000,
     default_qty_value=100, default_qty_type=strategy.percent_of_equity , calc_on_every_tick=false, calc_on_order_fills=true)


//                  ╔═ SETTINGS                  ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

strategy_1     = input ( defval=true   , type=input.bool    , title="STRATEGY 1? —>"      )
Recursive      = input(false)
RES201         = "Min",RES202= "D",RES203 = "W",RES204 = "M"

//++ Resolution 1 ++
inp_resolution1 = input(600, minval=1, title="Resolution Line 1")
restype1        = input ( defval="Min"  , type=input.string , title= "Resolution Line 1" , options=[ "Min","D","W","M"])
multiplier1     = restype1 == "Min" ? "" : restype1 == "D" ? "D" : restype1 == "W" ? "W" : "M"
resolution1     = tostring(inp_resolution1)+ multiplier1

//++ Resolution 2 ++
inp_resolution2 = input(1440, minval=1, title="Resolution Line 2")
restype2        = input ( defval="Min"  , type=input.string , title= "Resolution Line 2" , options=["Min","D","W","M"])
multiplier2     = restype2 == "Min" ? "" : restype2 == "D" ? "D" : restype2 == "W" ? "W" : "M"
resolution2     = tostring(inp_resolution2)+ multiplier2

StopLoss        = input(defval = 500 , title = "Stop Loss", minval = 0)
TakeProfit      = input(defval = 2500 , title = "Take Profit", minval = 0)
// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit   = TakeProfit  >= 1 ? TakeProfit  : na
useStopLoss     = StopLoss    >= 1 ? StopLoss    : na


//                  ╔═ BACKTEST RANGE            ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░
line_breakBTR  = input ( defval = true   , type=input.bool   , title="BACKTEST RANGE —"      ) 
FromYear       = input ( defval = 2019, title = "From Year", minval = 2017)
FromMonth      = input ( defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay        = input ( defval = 2, title = "From Day", minval = 1, maxval = 31)
//FromHour     = input ( defval = 1, title = "From Hour", minval = 1, maxval = 24)
ToYear         = input ( defval = 9999, title = "To Year", minval = 2017)
//ToHour       = input ( defval = 0, title = "From Hour", minval = 0, maxval = 24)
ToMonth        = input ( defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay          = input ( defval = 1, title = "To Day", minval = 1, maxval = 31)

// === FUNCTION EXAMPLE ===
start     = timestamp(syminfo.timezone, FromYear, FromMonth, FromDay, 0, 00)  // backtest start window
finish    = timestamp(syminfo.timezone, ToYear  , ToMonth  , ToDay  , 0, 59)  // backtest finish window
window()  => time >= start and time <= finish ? true : false // create function "within window of time"

//                  ╔═ INDICATOR                 ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

// "Ratio OCHL Averager" -> alexgrover / tradingview.com/script/RGAtOI6h-Ratio-OCHL-Averager-An-Alternative-to-VWAP/

rochla( res,Recursive)=>
    //Recursive = false
    H =  security(syminfo.tickerid,res,high[1],gaps = barmerge.gaps_off,  lookahead = barmerge.lookahead_on)
    L =  security(syminfo.tickerid,res,low[1] ,gaps = barmerge.gaps_off,  lookahead = barmerge.lookahead_on)
    d = 0.
    //----
    a = Recursive ? nz(d[1],open) : open
    b = abs(close-a)/(H - L)
    c = b > 1 ? 1 : b
    d := c*close+(1-c)*nz(d[1],close)



strat1_line1=rochla(resolution1,Recursive)
strat1_line2=rochla(resolution2,Recursive)

plot(strat1_line1, title="Ratio OCHL Averager 1", color=#DAA520,linewidth=2,transp=0)
plot(strat1_line2, title="Ratio OCHL Averager 2", color=#B22222,linewidth=2,transp=0)



//                  ╔═ STRATEGY 1                ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░

trading_strat1_line1 = strategy_1 == 1    ? strat1_line1   : na
trading_strat1_line2 = strategy_1 == 1    ? strat1_line2   : na

longCross  = crossunder (trading_strat1_line2, trading_strat1_line1) ? true : false
shortCross = crossover  (trading_strat1_line2, trading_strat1_line1) ? true : false

plot( longCross  ? trading_strat1_line1 : na , title = "Long"  , color=color.aqua, style=plot.style_circles, linewidth=5, offset= 0)
plot( shortCross ? trading_strat1_line2 : na , title = "Short" , color=color.red , style=plot.style_circles, linewidth=5, offset= 0)



//                  ╔═ Backtest 1                ╗
//░░░░░░░░░░░░░░░░░ ╚════════════════════════════╝ ░░░░░░░░░░░░░░░░░░░░░░░░


strategy.exit("close",loss = useStopLoss, profit = useTakeProfit)

if longCross  and window() and strategy_1 == 1 
    strategy.entry("Go Long", strategy.long)
if shortCross and window() and strategy_1 == 1 
    strategy.entry("Go Short", strategy.short)

//end

Mehr