Stratégie de trading quantitatif oscillant K-line


Date de création: 2023-09-26 20:05:55 Dernière modification: 2023-09-26 20:05:55
Copier: 0 Nombre de clics: 724
1
Suivre
1617
Abonnés

Aperçu

La stratégie est une stratégie dynamique basée sur des indicateurs, utilisant des indicateurs d’oscillateurs tels que le RSI, le Stoch et le MACD pour construire des signaux de négociation stratégiques. L’idée principale de la stratégie est d’utiliser l’indicateur pour identifier la direction de la tendance lorsque les prix sont en état de choc et d’entrer en fonction du signal de l’indicateur.

Principe de stratégie

La stratégie commence par appeler la fonction f_getOscilatorValues pour obtenir les valeurs des différents indicateurs d’oscillation, y compris le RSI, le Stoch, le MACD, etc. Ensuite, la fonction f_getSupertrend pour calculer les valeurs de l’indicateur de tendance décalée est utilisée pour suivre les arrêts.

Après avoir calculé l’indicateur, la stratégie appelle la fonction f_getBuySellStops, qui calcule l’arrêt d’entrée et l’arrêt d’arrêt en fonction de la valeur de l’indicateur. Plus précisément, elle calcule l’indicateur ATR et prend l’arrêt d’entrée par ATR multiplié par un coefficient d’arrêt.

La stratégie détermine ensuite l’orientation physique de la ligne K. Si la ligne K est en hausse, elle est dessinée en vert et si la ligne K est en baisse, elle est dessinée en rouge. Après avoir dessiné la ligne K et l’indicateur, la stratégie détermine si la condition d’entrée est remplie.

Après l’entrée, le stop-loss est suivi, le stop-loss est suivi en haut ou en bas du rail, selon ce qui est le plus proche. Lorsque le stop-loss est déclenché, le marché est libéré.

Analyse des forces stratégiques

Cette stratégie présente les avantages suivants:

  1. L’utilisation d’indicateurs d’oscillation pour identifier la direction de la tendance permet de saisir en temps opportun les occasions de revirement de courte ligne du marché.

  2. La stratégie de suspension des pertes en retard peut limiter les pertes individuelles avant que les pertes ne s’élargissent.

  3. La taille de la position peut être ajustée de manière dynamique en fonction de l’arrêt de perte et de l’arrêt de position calculés par l’ATR.

  4. Le filtrage est effectué en combinaison avec une moyenne de haute périodicité, afin d’éviter le bourrage.

  5. La stratégie de blocage partiel permet de maintenir les bénéfices et de bloquer une partie des bénéfices.

  6. La stratégie est simple, claire, facile à comprendre et adaptée aux débutants en trading quantitatif.

Analyse stratégique des risques

Cette stratégie comporte aussi des risques:

  1. Les indicateurs oscillators présentent des problèmes de retard, ce qui peut entraîner un retard dans le signal d’entrée et un retard dans le signal de sortie. Les paramètres de l’indicateur peuvent être optimisés en ajustant les paramètres de l’indicateur ou en ajoutant un indicateur de suivi de tendance.

  2. Le point de stop est proche et peut être atteint par un stop-break. Il est possible d’alléger la portée de stop-loss de manière appropriée ou d’utiliser des stratégies de stop-loss dynamiques telles que le stop Chandelier.

  3. Après un arrêt partiel, la position restante peut être clôturée. Vous pouvez réduire le pourcentage d’arrêt partiel pour laisser de la place.

  4. Risque de ressemblance des données de retracement. Les données doivent être vérifiées plusieurs fois dans différents marchés pour éviter les surcorrélations.

  5. Les moyennes à hautes périodes peuvent également être inefficaces en tant que conditions de filtrage. Des méthodes telles que la classification des tendances devraient être utilisées pour aider à déterminer le mouvement des grandes périodes.

Orientation de l’optimisation de la stratégie

Cette stratégie peut être optimisée dans les domaines suivants:

  1. Tester des combinaisons de paramètres de différents oscillators, en choisissant une combinaison qui fournit un signal de meilleure qualité, comme l’indicateur Sttoch pour les lignes K rapides.

  2. Essayez de modifier une partie de l’arrêt en arrêt mobile, en réglant la position de l’arrêt en fonction de l’ATR ou de la moyenne mobile

  3. L’ajout d’un algorithme d’apprentissage automatique pour la détection des tendances à grande périodicité remplace le filtrage linéaire à haute périodicité et améliore la précision de la détection.

  4. L’augmentation de l’indicateur de quantité d’énergie peut être utilisée comme condition de filtrage d’entrée pour éviter des échanges inversés inutiles.

  5. L’intégration et l’optimisation des poids des indicateurs permettent de sélectionner la combinaison d’indicateurs la plus appropriée pour la variété actuelle.

  6. Ajout d’un module de contrôle de vent par apprentissage automatique, optimisation dynamique des positions de stop loss, stop stop, position, etc.

  7. Ajouter des signaux de négociation en arbitrage triangulaire ou en arbitrage à terme pour profiter de la différence de prix entre les options futures et les options en espèces.

Résumer

Cette stratégie est une stratégie idéale pour les débutants en trading quantitatif, elle est claire et basée sur l’analyse des indicateurs et le contrôle des risques. Cependant, l’optimisation des paramètres et l’évitement des risques sur le terrain sont nécessaires pour obtenir des rendements stables.

Code source de la stratégie
/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)

showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier  = input(4)
targetMultiplier  = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)

useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true

f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
    oOpen = rsi(open, length)
    oClose = rsi(close, length)
    oHigh = rsi(high, length)
    oLow = rsi(low, length)
    if(oscilatorType == "tsi")
        oOpen := tsi(open, shortlength, longlength)
        oClose := tsi(close, shortlength, longlength)
        oHigh := tsi(high, shortlength, longlength)
        oLow := tsi(low, shortlength, longlength)
    if(oscilatorType == "stoch")
        oOpen := stoch(open, longlength, shortlength, length)
        oClose := stoch(close, longlength, shortlength, length)
        oHigh := stoch(high, longlength, shortlength, length)
        oLow := stoch(low, longlength, shortlength, length)
    if(oscilatorType == "cci")
        oOpen := cci(open, length)
        oClose := cci(close, length)
        oHigh := cci(high, length)
        oLow := cci(low, length)
    if(oscilatorType == "cog")
        oOpen := cog(open, length)
        oClose := cog(close, length)
        oHigh := cog(high, length)
        oLow := cog(low, length)
    if(oscilatorType == "cmo")
        oOpen := cmo(open, length)
        oClose := cmo(close, length)
        oHigh := cmo(high, length)
        oLow := cmo(low, length)
    if(oscilatorType == "mfi")
        oOpen := mfi(open, length)
        oClose := mfi(close, length)
        oHigh := mfi(high, length)
        oLow := mfi(low, length)
    if(oscilatorType == "macd")
        [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
        [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
        [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
        [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
        oOpen := macdLineOpen
        oClose := macdLineClose
        oHigh := macdLineHigh
        oLow := macdLineLow
    [oOpen, oClose, oHigh, oLow]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
    atr = averagetruerange * stopMultiplier

    longStop = oClose - atr
    longStopPrev = nz(longStop[1], longStop)
    longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
    
    shortStop = oClose + atr
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
    
    dir = 1
    dir := nz(dir[1], dir)
    dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
    
    trailingStop = dir == 1? longStop : shortStop
    
    [dir, trailingStop]


f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
    barState = 0
    source = oClose
    
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)

    buyStop = source - atr * stopMultiplier
    sellStop = source + atr * stopMultiplier
    buyStopDerived = buyStop
    sellStopDerived = sellStop
    highTarget = considerWicks ? oHigh : source
    lowTarget = considerWicks ? oLow : source
    
    highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
    lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
    
    barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
    
    buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
    sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
    buyStop := source - atr * buyMultiplier
    sellStop := source + atr * sellMultiplier
    buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
    sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
    
    buyStopDerived := buyStop
    sellStopDerived := sellStop
    
    buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
    sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived

    [buyStopDerived, sellStopDerived, barState]


f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
    
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
    derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
    HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
    HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
    CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
    pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
    pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
    pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
    pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
    [pivothi, pivotlo]
    
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)

candleColor = colorByPreviousClose ?
                 (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : 
                 (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)

[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)

trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived

plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)

[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)

buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)

// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)