Stratégie d'arbitrage statistique adaptatif de suivi de l'élan

Auteur:ChaoZhang est là., Date: 2023-12-11 16:41:27 Je suis désolé
Les étiquettes:

img

Résumé

Cette stratégie construit une enveloppe de volatilité dynamique basée sur la méthode de régression du noyau de Nadaraya-Watson pour générer des signaux de trading d'achat bas et de vente élevé en suivant les situations de croisement entre les bandes de prix et d'enveloppe.

La logique de la stratégie

Le noyau de la stratégie est de calculer l'enveloppe dynamique du prix. Tout d'abord, en utilisant une fenêtre de rétroaction personnalisée, il construit les courbes de régression du noyau de Nadaraya-Watson du prix (clos, high, low) pour obtenir une estimation de prix lissée. Ensuite, il calcule l'ATR en fonction d'une longueur ATR personnalisée, et forme les bandes d'enveloppe supérieure et inférieure avec des facteurs proches et lointains. Lorsque le prix pénètre dans l'enveloppe depuis le bas, un signal d'achat est généré. Lorsque le prix sort de l'enveloppe depuis le haut, un signal de vente est déclenché. En suivant la relation dynamique entre le prix et les propriétés statistiques liées à la volatilité, la stratégie ajuste ses décisions de trading de manière adaptative.

Les avantages

  1. Basé sur des modèles mathématiques avec des paramètres contrôlables, moins de probabilité de surajustement.
  2. Adapté aux changements du marché en tirant parti de la relation dynamique entre prix et volatilité pour saisir les opportunités de négociation.
  3. L'échelle de log fonctionne bien avec différents délais et instruments avec des magnitudes de volatilité variables.
  4. Paramètres personnalisables pour ajuster la sensibilité de la stratégie.

Les risques

  1. La nature théorique des modèles mathématiques peut être sous-performante dans le commerce en direct.
  2. Les paramètres clés nécessitent de l'expertise, des réglages inappropriés peuvent nuire à la rentabilité.
  3. Le retard de la question peut entraîner la perte de certaines opportunités commerciales.
  4. Vulnérable aux fléchettes sur les marchés très volatils.

L'optimisation appropriée, un backtest suffisant, la compréhension des facteurs clés et une dimensionnement prudent des positions dans le commerce en direct pourraient contribuer à atténuer ces risques.

Directions d'amélioration

  1. Optimisez encore les paramètres pour trouver la meilleure combinaison.
  2. Appliquer des méthodes d'apprentissage automatique pour sélectionner automatiquement les paramètres optimaux.
  3. Ajoutez des filtres pour activer la stratégie dans certains environnements de marché.
  4. Incorporer d'autres indicateurs pour filtrer les signaux trompeurs.
  5. Essayez d'autres modèles mathématiques.

Conclusion

La stratégie intègre l'analyse statistique et l'analyse des indicateurs techniques pour générer des signaux de trading en suivant dynamiquement la relation entre le prix et la volatilité. Les paramètres peuvent être ajustés en fonction des conditions du marché et des besoins personnels.


/*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")


Plus de