Une stratégie de double équilibre


Date de création: 2023-11-17 16:56:24 Dernière modification: 2023-11-17 16:56:24
Copier: 1 Nombre de clics: 627
1
Suivre
1617
Abonnés

Une stratégie de double équilibre

Aperçu

La stratégie de réversion de la moyenne mobile double est une stratégie de réversion de courte durée typique. Elle utilise deux paramètres différents de la moyenne pour émettre des signaux de négociation et obtenir des bénéfices lorsque la tendance est inversée.

Principe de stratégie

La stratégie utilise deux courbes pour générer des signaux de négociation. La première courbe maopening est utilisée pour déterminer la direction de la tendance, la seconde courbe maclosing est utilisée pour émettre des signaux de négociation.

Lorsque le maopening augmente, il indique qu’il est actuellement dans la phase de hausse de la tendance; lorsque le maopening baisse, il indique qu’il est actuellement dans la phase de baisse de la tendance. Le maclosing est multiplié par un facteur supérieur à 1, ce qui le rend plus sensible et permet d’émettre un signal de reprise plus tôt.

Plus précisément, lorsque le maopening augmente et que le maclosing baisse, cela signifie un renversement de tendance, ce qui entraîne une ouverture à court terme de la stratégie; lorsque le maopening baisse et que le maclosing passe sur le maopening, cela signifie un renversement de tendance, ce qui entraîne une ouverture à long terme de la stratégie.

Les paramètres de la stratégie comprennent le type de ligne moyenne, la longueur, la source de données, etc. Les paramètres peuvent être ajustés pour obtenir de meilleurs résultats de négociation. En outre, la stratégie contient des options, telles que la méthode d’ouverture de position, la méthode d’arrêt, etc., qui peuvent être configurées en fonction des besoins.

Analyse des avantages

Les principaux avantages de la stratégie d’inversion de la double ligne sont les suivants:

  1. Les retraits sont petits et conviennent pour les transactions en ligne courte. Deux lignes moyennes rapides sont utilisées pour capturer rapidement le renversement de la tendance à court terme. Les retraits sont petits.

  2. La mise en œuvre est simple et facile à maîtriser. La formation d’une ligne homogène qui se croise est un signal de transaction, très simple et clair.

  3. Il est possible d’optimiser les paramètres en utilisant des paramètres et des coefficients à deux moyennes.

  4. La stratégie logique est simple et claire, la fréquence d’exécution est élevée, ce qui est très approprié pour la programmation de transactions automatisées.

  5. Risque contrôlable, avec un mécanisme de stop loss. Stop loss mobile ou numérique peut être configuré, les pertes individuelles peuvent être contrôlées.

Analyse des risques

Il y a aussi des risques liés à une stratégie de rétrogradation à double sens:

  1. Les croisements bi-équivalents sont en retard. La ligne équivalente elle-même est en retard sur le prix, et la tendance peut avoir été inversée pendant un certain temps au moment de la croisement.

  2. La tendance à l’inversion ne peut pas être maintenue et pourrait rapidement se retourner, entraînant un piège.

  3. Les retraits sont toujours possibles. Un arrêt rapide peut réduire les pertes individuelles, mais des retraits continus peuvent entraîner des retraits plus importants.

  4. Risque d’optimisation des données. Paramètres d’optimisation excessive, qui se sont bien comportés dans les données historiques, mais qui ont été moins efficaces sur le disque.

Les solutions pour faire face aux risques sont:

  1. Optimiser les paramètres pour trouver des réglages linéaires rapides.

  2. Évitez le confinement en combinant avec d’autres indicateurs, tels que les indicateurs de quantité, les indicateurs de volatilité, etc.

  3. Ajustez la position de stop pour réduire la probabilité de stop consécutif.

  4. Tests d’optimisation de paramètres en groupes multiples pour évaluer la robustesse des paramètres.

Direction d’optimisation

Les stratégies d’inversion de la double ligne uniforme peuvent être optimisées dans les domaines suivants:

  1. Testez différents types de médians pour trouver des médians plus sensibles à la réaction. Comme Kama, ZLEMA, etc.

  2. Optimiser les paramètres de la ligne moyenne pour trouver la meilleure combinaison de longueurs. Les lignes moyennes avec des périodes plus courtes sont généralement plus efficaces.

  3. Testez différentes sources de données, telles que les prix de clôture, les prix moyens et les prix typiques.

  4. Ajout d’un filtre de tendance pour éviter les signaux de retournement inappropriés.

  5. La confirmation est effectuée en combinaison avec d’autres indicateurs, tels que l’indicateur de quantité et de prix (MACD), l’indicateur OBV, etc.

  6. Des mécanismes de gestion des risques ont été ajoutés, tels que l’arrêt mobile, la perte maximale du compte, etc.

  7. Optimiser le portefeuille pour trouver le meilleur ratio de répartition des actifs.

  8. Ajout de tests de robustesse des paramètres pour évaluer le risque de sur-optimisation des paramètres.

Résumer

La stratégie de retour en arrière à deux lignes est une stratégie de courte ligne simple et pratique, adaptée à la capture de retournements à court terme du marché. La stratégie de retour en arrière est petite, facile à mettre en œuvre et convient parfaitement à la négociation en volume.

Code source de la stratégie
/*backtest
start: 2023-10-17 00:00:00
end: 2023-11-16 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy(title = "hamster-bot MRS 2", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 9, commission_value = 0.045, backtest_fill_limits_assumption = 1)
info_options = "Options"

on_close = input(false, title = "Entry on close", inline=info_options, group=info_options)
OFFS = input.int(0, minval = 0, maxval = 1, title = "| Offset View", inline=info_options, group=info_options)
trade_offset = input.int(0, minval = 0, maxval = 1, title = "Trade", inline=info_options, group=info_options)
use_kalman_filter = input.bool(false, title="Use Kalman filter", group=info_options)

//MA Opening
info_opening = "MA Opening"
maopeningtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_opening, group=info_opening)
maopeningsrc = input.source(ohlc4, title = "", inline=info_opening, group=info_opening)
maopeninglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_opening, group=info_opening)

//MA Closing
info_closing = "MA Closing"
maclosingtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_closing, group=info_closing)
maclosingsrc = input.source(ohlc4, title = "", inline=info_closing, group=info_closing)
maclosinglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_closing, group=info_closing)
maclosingmul = input.float(1, step = 0.005, title = "mul", inline=info_closing, group=info_closing)

long1on    = input(true, title = "", inline = "long1")
long1shift = input.float(0.96, step = 0.005, title = "Long", inline = "long1")
long1lot   = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "long1")
short1on    = input(true, title = "", inline = "short1")
short1shift = input.float(1.04, step = 0.005, title = "short", inline = "short1")
short1lot   = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "short1")
startTime = input(timestamp("01 Jan 2010 00:00 +0000"), "Start date", inline = "period")
finalTime = input(timestamp("31 Dec 2030 23:59 +0000"), "Final date", inline = "period")

HMA(_src, _length) =>  ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length)))
EHMA(_src, _length) =>  ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length)))
THMA(_src, _length) =>  ta.wma(ta.wma(_src,_length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length)
tema(sec, length)=>
    tema1= ta.ema(sec, length)
    tema2= ta.ema(tema1, length)
    tema3= ta.ema(tema2, length)
    tema_r = 3*tema1-3*tema2+tema3
donchian(len) => math.avg(ta.lowest(len), ta.highest(len))
ATR_func(_src, _len)=>
    atrLow = low - ta.atr(_len)
    trailAtrLow = atrLow
    trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1]
    supportHit = _src <= trailAtrLow
    trailAtrLow := supportHit ? atrLow : trailAtrLow
    trailAtrLow
f_dema(src, len)=>
    EMA1 = ta.ema(src, len)
    EMA2 = ta.ema(EMA1, len)
    DEMA = (2*EMA1)-EMA2
f_zlema(src, period) =>
    lag = math.round((period - 1) / 2)
    ema_data = src + (src - src[lag])
    zl= ta.ema(ema_data, period)
f_kalman_filter(src) =>
    float value1= na
    float value2 = na
    value1 := 0.2 * (src - src[1]) + 0.8 * nz(value1[1])
    value2 := 0.1 * (ta.tr) + 0.8 * nz(value2[1])
    lambda = math.abs(value1 / value2)
    alpha = (-math.pow(lambda, 2) + math.sqrt(math.pow(lambda, 4) + 16 * math.pow(lambda, 2)))/8
    value3 = float(na)
    value3 := alpha * src + (1 - alpha) * nz(value3[1])
//SWITCH
ma_func(modeSwitch, src, len, use_k_f=true) =>
      modeSwitch == "SMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.sma(src, len))  : ta.sma(src, len) :
      modeSwitch == "RMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.rma(src, len))  : ta.rma(src, len) :
      modeSwitch == "EMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.ema(src, len))  : ta.ema(src, len) :
      modeSwitch == "TEMA"  ? use_kalman_filter and use_k_f ? f_kalman_filter(tema(src, len))    : tema(src, len):
      modeSwitch == "DEMA"  ? use_kalman_filter and use_k_f ? f_kalman_filter(f_dema(src, len))  : f_dema(src, len):
      modeSwitch == "ZLEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_zlema(src, len)) : f_zlema(src, len):
      modeSwitch == "WMA"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.wma(src, len))  : ta.wma(src, len):
      modeSwitch == "VWMA"  ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.vwma(src, len)) : ta.vwma(src, len):
      modeSwitch == "Hma"   ? use_kalman_filter and use_k_f ? f_kalman_filter(HMA(src, len))     : HMA(src, len):
      modeSwitch == "Ehma"  ? use_kalman_filter and use_k_f ? f_kalman_filter(EHMA(src, len))    : EHMA(src, len):
      modeSwitch == "Thma"  ? use_kalman_filter and use_k_f ? f_kalman_filter(THMA(src, len/2))  : THMA(src, len/2):
      modeSwitch == "ATR"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ATR_func(src, len)): ATR_func(src, len) :
      modeSwitch == "L"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.lowest(len)): ta.lowest(len) :
      modeSwitch == "H"   ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.highest(len)): ta.highest(len) :
      modeSwitch == "DMA"   ? donchian(len) : na

//Var
sum = 0.0
maopening = 0.0
maclosing = 0.0
os = maopeningsrc
cs = maclosingsrc
pos = strategy.position_size
p = 0.0
p := pos == 0 ? (strategy.equity / 100) / close : p[1]
truetime = true
loss = 0.0
maxloss = 0.0
equity = 0.0

//MA Opening
maopening := ma_func(maopeningtyp, maopeningsrc, maopeninglen)

//MA Closing
maclosing := ma_func(maclosingtyp, maclosingsrc, maclosinglen) * maclosingmul

long1 = long1on == false ? 0 : long1shift == 0 ? 0 : long1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * long1shift
short1 = short1on == false ? 0 : short1shift == 0 ? 0 : short1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * short1shift
//Colors
maopeningcol = maopening == 0 ? na : color.blue
maclosingcol = maclosing == 0 ? na : color.fuchsia
long1col = long1 == 0 ? na : color.green
short1col = short1 == 0 ? na : color.red
//Lines
plot(maopening, offset = OFFS, color = maopeningcol)
plot(maclosing, offset = OFFS, color = maclosingcol)
long1line = long1 == 0 ? close : long1
short1line = short1 == 0 ? close : short1
plot(long1line, offset = OFFS, color = long1col)
plot(short1line, offset = OFFS, color = short1col)

//Lots
lotlong1 = p * long1lot
lotshort1 = p * short1lot

//Entry
if maopening > 0 and maclosing > 0 and truetime
    //Long
    sum := 0
    strategy.entry("L", strategy.long, lotlong1, limit = on_close ? na : long1, when = long1 > 0 and pos <= sum and (on_close ? close <= long1[trade_offset] : true))
    sum := lotlong1

    //Short
    sum := 0
    pos := -1 * pos
    strategy.entry("S", strategy.short, lotshort1, limit = on_close ? na : short1, when = short1 > 0 and pos <= sum and (on_close ? close >= short1[trade_offset] : true))
    sum := lotshort1

strategy.exit("Exit", na, limit = maclosing)
if time > finalTime
    strategy.close_all()