Dynamikverfolgung Adaptive statistische Arbitrage-Strategie

Schriftsteller:ChaoZhang, Datum: 2023-12-11 16:41:27
Tags:

img

Übersicht

Diese Strategie erstellt eine dynamische Volatilitätsumgebung auf der Grundlage der Nadaraya-Watson-Kernel-Regressionsmethode, um Handelssignale von niedrigem Kauf und hohem Verkauf zu generieren, indem die Crossover-Situationen zwischen Preis und Umschlagbändern verfolgt werden.

Strategie Logik

Der Kern der Strategie besteht darin, den dynamischen Umschlag des Preises zu berechnen. Zunächst konstruiert sie mit einem benutzerdefinierten Lookback-Fenster die Nadaraya-Watson-Kernel-Regressionskurven des Preises (nahe, hoch, niedrig), um eine glatte Preisschätzung zu erhalten. Dann berechnet sie den ATR basierend auf einer benutzerdefinierten ATR-Länge und bildet die oberen und unteren Umschlagbänder mit nahen und fernen Faktoren. Wenn der Preis von unten in den Umschlag bricht, wird ein Kaufsignal generiert. Wenn der Preis von oben aus dem Umschlag bricht, wird ein Verkaufssignal ausgelöst. Durch die Verfolgung der dynamischen Beziehung zwischen Preis und volatilitätsbezogenen statistischen Eigenschaften passt die Strategie ihre Handelsentscheidungen anpassungsfähig an.

Vorteile

  1. Basierend auf mathematischen Modellen mit kontrollierbaren Parametern, weniger Wahrscheinlichkeit einer Überanpassung.
  2. Anpassungsfähig an Marktveränderungen, indem dynamische Beziehungen zwischen Preis und Volatilität genutzt werden, um Handelschancen zu nutzen.
  3. Die Log-Skala funktioniert gut mit verschiedenen Zeitrahmen und Instrumenten mit unterschiedlichen Volatilitätsgrößen.
  4. Anpassbare Parameter zur Anpassung der Strategieempfindlichkeit.

Risiken

  1. Die theoretische Natur der mathematischen Modelle kann bei Live-Handel unterdurchschnittlich sein.
  2. Schlüsselparameter erfordern Fachwissen, falsche Einstellungen können die Rentabilität beeinträchtigen.
  3. Verzögerte Ausgabe kann dazu führen, dass einige Handelschancen verpasst werden.
  4. Anfällig für Whipsaws auf hochvolatilen Märkten.

Eine ordnungsgemäße Optimierung, ausreichende Backtests, das Verständnis der Schlüsselfaktoren und eine umsichtige Positionsgröße im Live-Handel könnten dazu beitragen, diese Risiken zu mindern.

Verbesserungsrichtlinien

  1. Optimieren Sie die Parameter weiter, um die beste Kombination zu finden.
  2. Anwendung von Methoden des maschinellen Lernens zur automatischen Auswahl optimaler Parameter.
  3. Fügen Sie Filter hinzu, um die Strategie in bestimmten Marktumgebungen zu aktivieren.
  4. Einbeziehung anderer Indikatoren, um irreführende Signale zu filtern.
  5. Versuchen Sie andere mathematische Modell-Algorithmen.

Schlussfolgerung

Die Strategie beinhaltet statistische Analyse und technische Indikatorenanalyse, um Handelssignale zu generieren, indem die Beziehung zwischen Preis und Volatilität dynamisch verfolgt wird. Die Parameter können basierend auf den Marktbedingungen und persönlichen Bedürfnissen angepasst werden. Insgesamt bedarf es trotz der soliden theoretischen Grundlage noch weiterer Überprüfung. Man sollte es vorsichtig behandeln und vorsichtig handeln.


/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// © Julien_Eche
//@version=5

strategy("Nadaraya-Watson Envelope Strategy", overlay=true, pyramiding=1, default_qty_type=strategy.percent_of_equity, default_qty_value=20)

// Helper Functions
getEnvelopeBounds(_atr, _nearFactor, _farFactor, _envelope) => 
    _upperFar = _envelope + _farFactor*_atr
    _upperNear = _envelope + _nearFactor*_atr
    _lowerNear = _envelope - _nearFactor*_atr
    _lowerFar = _envelope - _farFactor*_atr
    _upperAvg = (_upperFar + _upperNear) / 2
    _lowerAvg = (_lowerFar + _lowerNear) / 2 
    [_upperNear, _upperFar, _upperAvg, _lowerNear, _lowerFar, _lowerAvg]

customATR(length, _high, _low, _close) =>
    trueRange = na(_high[1])? math.log(_high)-math.log(_low) : math.max(math.max(math.log(_high) - math.log(_low), math.abs(math.log(_high) - math.log(_close[1]))), math.abs(math.log(_low) - math.log(_close[1])))
    ta.rma(trueRange, length)

customKernel(x, h, alpha, x_0) =>
    sumWeights = 0.0
    sumXWeights = 0.0
    for i = 0 to h
        weight = math.pow(1 + (math.pow((x_0 - i), 2) / (2 * alpha * h * h)), -alpha)
        sumWeights := sumWeights + weight
        sumXWeights := sumXWeights + weight * x[i]
    sumXWeights / sumWeights

// Custom Settings
customLookbackWindow = input.int(8, 'Lookback Window (Custom)', group='Custom Settings')
customRelativeWeighting = input.float(8., 'Relative Weighting (Custom)', step=0.25, group='Custom Settings')
customStartRegressionBar = input.int(25, "Start Regression at Bar (Custom)", group='Custom Settings')

// Envelope Calculations
customEnvelopeClose = math.exp(customKernel(math.log(close), customLookbackWindow, customRelativeWeighting, customStartRegressionBar))
customEnvelopeHigh = math.exp(customKernel(math.log(high), customLookbackWindow, customRelativeWeighting, customStartRegressionBar))
customEnvelopeLow = math.exp(customKernel(math.log(low), customLookbackWindow, customRelativeWeighting, customStartRegressionBar))
customEnvelope = customEnvelopeClose
customATRLength = input.int(60, 'ATR Length (Custom)', minval=1, group='Custom Settings')
customATR = customATR(customATRLength, customEnvelopeHigh, customEnvelopeLow, customEnvelopeClose)
customNearATRFactor = input.float(1.5, 'Near ATR Factor (Custom)', minval=0.5, step=0.25, group='Custom Settings')
customFarATRFactor = input.float(2.0, 'Far ATR Factor (Custom)', minval=1.0, step=0.25, group='Custom Settings')
[customUpperNear, customUpperFar, customUpperAvg, customLowerNear, customLowerFar, customLowerAvg] = getEnvelopeBounds(customATR, customNearATRFactor, customFarATRFactor, math.log(customEnvelopeClose))

// Colors
customUpperBoundaryColorFar = color.new(color.red, 60)
customUpperBoundaryColorNear = color.new(color.red, 80)
customBullishEstimatorColor = color.new(color.teal, 50)
customBearishEstimatorColor = color.new(color.red, 50)
customLowerBoundaryColorNear = color.new(color.teal, 80)
customLowerBoundaryColorFar = color.new(color.teal, 60)

// Plots
customUpperBoundaryFar = plot(math.exp(customUpperFar), color=customUpperBoundaryColorFar, title='Upper Boundary: Far (Custom)')
customUpperBoundaryAvg = plot(math.exp(customUpperAvg), color=customUpperBoundaryColorNear, title='Upper Boundary: Average (Custom)')
customUpperBoundaryNear = plot(math.exp(customUpperNear), color=customUpperBoundaryColorNear, title='Upper Boundary: Near (Custom)') 
customEstimationPlot = plot(customEnvelopeClose, color=customEnvelope > customEnvelope[1] ? customBullishEstimatorColor : customBearishEstimatorColor, linewidth=2, title='Custom Estimation')
customLowerBoundaryNear = plot(math.exp(customLowerNear), color=customLowerBoundaryColorNear, title='Lower Boundary: Near (Custom)')
customLowerBoundaryAvg = plot(math.exp(customLowerAvg), color=customLowerBoundaryColorNear, title='Lower Boundary: Average (Custom)') 
customLowerBoundaryFar = plot(math.exp(customLowerFar), color=customLowerBoundaryColorFar, title='Lower Boundary: Far (Custom)')

// Fills
fill(customUpperBoundaryFar, customUpperBoundaryAvg, color=customUpperBoundaryColorFar, title='Upper Boundary: Farmost Region (Custom)')
fill(customUpperBoundaryNear, customUpperBoundaryAvg, color=customUpperBoundaryColorNear, title='Upper Boundary: Nearmost Region (Custom)')
fill(customLowerBoundaryNear, customLowerBoundaryAvg, color=customLowerBoundaryColorNear, title='Lower Boundary: Nearmost Region (Custom)')
fill(customLowerBoundaryFar, customLowerBoundaryAvg, color=customLowerBoundaryColorFar, title='Lower Boundary: Farmost Region (Custom)')


longCondition = ta.crossover(close, customEnvelopeLow)
if (longCondition)
    strategy.entry("Buy", strategy.long)

exitLongCondition = ta.crossover(customEnvelopeHigh, close)
if (exitLongCondition)
    strategy.close("Buy")


Mehr