Stratégie de négociation quantitative basée sur l'indicateur de super-tendance et le trading de courbe d'actions

Auteur:ChaoZhang est là., Date: 15 janvier 2024 à 11h41
Les étiquettes:

img

Résumé

L'idée de base de cette stratégie est de combiner l'indicateur Supertrend avec le trading de la courbe des actions. Lorsque l'indicateur Supertrend génère un signal d'achat ou de vente, nous n'exécutons pas directement le commerce. Au lieu de cela, nous vérifions si la courbe actuelle des actions est inférieure à sa moyenne mobile. Nous n'ouvrirons des positions que lorsque la courbe des actions est supérieure à la moyenne mobile. Lorsque la courbe des actions est inférieure à la moyenne mobile, nous suspendrons le trading pour la stratégie actuelle. Cela peut efficacement empêcher l'expansion des pertes.

La logique de la stratégie

Cette stratégie se compose essentiellement de deux parties:

  1. Indicateur de tendance supérieure
  2. Commerce de courbe de participation

La formule de calcul de l'indicateur Supertrend est:

Bande supérieure = Prix de source - Multiplicateur ATR * ATR Bande inférieure = prix de source + multiplicateur ATR * ATR

L'indicateur Supertrend utilise l'ATR pour définir les bandes supérieures et inférieures. Une rupture au-dessus de la bande supérieure représente un signal de vente, tandis qu'une rupture au-dessous de la bande inférieure représente un signal d'achat.

L'idée derrière le trading de la courbe d'actions est que nous prenons la moyenne mobile de la courbe d'actions de la stratégie. Lorsque la courbe d'actions tombe en dessous de sa moyenne mobile, nous faisons une pause dans le trading de la stratégie en cours et attendons que la courbe d'actions rebondisse au-dessus de la moyenne mobile avant de réactiver le trading.

Cette stratégie combine les deux techniques, de sorte qu'après que l'indicateur Supertrend ait généré un signal de trading, nous n'entrons pas directement dans les transactions. Au lieu de cela, nous vérifions si la courbe actuelle des actions est supérieure à sa moyenne mobile. Ce n'est que lorsque les deux conditions sont remplies que nous ouvrirons des positions. Cela peut effectivement atténuer les risques inhérents à l'indicateur Supertrend lui-même et prévenir des pertes excessives.

Les avantages

Les principaux avantages de cette stratégie sont les suivants:

  1. L'indicateur Supertrend lui-même ne peut pas réduire efficacement les pertes.

  2. Quand le trading devient défavorable, il fait une pause pour éviter des pertes excessives.

  3. Il peut gérer automatiquement les positions sans intervention manuelle. La négociation est interrompue automatiquement lorsque la courbe des actions tombe en dessous de la moyenne mobile et reprend lorsque la courbe des actions rebondit au-dessus.

Les risques

Cette stratégie comporte également certains risques:

  1. Des paramètres incorrects peuvent rendre inefficace la négociation de courbes d'actions. Des périodes de moyenne mobile appropriées doivent être sélectionnées.

  2. Il est possible qu'il n'ajuste pas rapidement ses positions lorsque la tendance du marché change, ce qui peut entraîner certaines pertes.

  3. Il peut manquer de bonnes opportunités commerciales en attendant que la courbe des actions rebondisse.

Les contre-mesures:

  1. Optimiser les paramètres et sélectionner la meilleure période de moyenne mobile.

  2. Incorporer d'autres indicateurs pour juger de la tendance et ajuster les positions en conséquence.

  3. Réduire la durée des opérations suspendues afin de réduire la probabilité de manquer des opportunités.

Directions d'optimisation

Nous pouvons optimiser la stratégie à partir des aspects suivants:

  1. Testez différentes combinaisons de paramètres pour trouver la période et le multiplicateur ATR optimaux.

  2. Essayez d'autres types de moyennes mobiles, comme moyenne mobile exponentielle, moyenne mobile Hull, etc.

  3. Ajouter d'autres indicateurs pour déterminer l'évolution du marché et ajuster les positions lorsque l'évolution change.

  4. Optimisez la période de moyenne mobile pour trouver le meilleur équilibre.

  5. Optimiser les conditions pour mettre en pause le trading, comme définir un seuil de stop loss avant la suspension.

Conclusion

Cette stratégie combine habilement l'indicateur Supertrend avec le trading de courbe d'actions, en tirant parti des forces des deux techniques. Les résultats des tests montrent que dans la plupart des cas, l'application du trading de courbe d'actions diminue réellement la rentabilité. En tant que telle, cette stratégie est plus adaptée aux traders défensifs. Avec l'optimisation des paramètres et de la logique, elle peut devenir une stratégie de trading quantitative très pratique.


/*backtest
start: 2023-01-14 00:00:00
end: 2024-01-14 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('Supertrend & Equity curve with EMA', overlay=false, format=format.price, precision=2, initial_capital=100000)

eqlen = input.int(25, "EQ EMA len", group = "New Equity Curve Settings")
shEQandMA = input.bool(true, "Show Original Equity Curve and MA")
shEQfilt = input.bool(true, "Show Filtered Equity Curve by MA")

Periods = input(title='ATR Period', defval=10, group = "SuperTrend Settings")
src = input(hl2, title='Source', group = "SuperTrend Settings")
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group = "SuperTrend Settings")
changeATR = input(title='Change ATR Calculation Method ?', defval=true, group = "SuperTrend Settings")

//SuperTrend Code
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend

// Strategy main code
buySignal = trend == 1 and trend[1] == -1
sellSignal = trend == -1 and trend[1] == 1
if buySignal
    strategy.entry('Long', strategy.long)
if sellSignal
    strategy.entry('Short', strategy.short)



//Equity Curve calcs
eq = strategy.netprofit
ch = ta.change(eq)
neq = ch != 0 ? eq : na
mova = ta.ema(neq,eqlen)

// New Equity Curve
var float neweq = 0
var int ttrades = 0
var int wintrades = 0
var int losetrades = 0

switch
    strategy.netprofit == strategy.netprofit[1]  => na
    strategy.netprofit < mova and strategy.netprofit[1] > mova  => neweq := neweq + ch
    strategy.netprofit < mova and strategy.netprofit[1] < mova => na
    strategy.netprofit > mova and strategy.netprofit[1] > mova => neweq := neweq + ch

newch = ta.change(neweq)
switch
    newch == 0 => na
    newch > 0 => 
        wintrades := wintrades +1
        ttrades := ttrades +1
    newch < 0 =>
        losetrades := losetrades +1
        ttrades := ttrades +1

//plot(eq, linewidth = 2)
//plot(mova, color=color.red)
//plot(neweq, color= color.green, linewidth = 3)


//Table 
var testTable = table.new(position = position.top_right, columns = 5, rows = 10, bgcolor = color.green, border_width = 1)
table.cell(table_id = testTable, column = 0, row = 0, text = "Strategy: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 1, row = 0, text = "Original: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 0, text = "Equity Curve EMA: ", bgcolor=color.white)     

table.cell(table_id = testTable, column = 0, row = 1, text = "Total Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 2, text = "Win Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 3, text = "Lose Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 4, text = "Win Rate: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 5, text = "Net Profit: ", bgcolor=color.white)     

//Equity Curve EMA stat
table.cell(table_id = testTable, column = 2, row = 1, text = str.tostring(ttrades), bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 2, text = str.tostring(wintrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 3, text = str.tostring(losetrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 4, text = str.tostring(math.round(100*wintrades/ttrades,2)), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 5, text = str.tostring(math.round(neweq)), bgcolor=color.white)

//Original Strategy stat
// table.cell(table_id = testTable, column = 1, row = 1, text = str.tostring(strategy.closedtrades), bgcolor=color.white)     
// table.cell(table_id = testTable, column = 1, row = 2, text = str.tostring(strategy.wintrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 3, text = str.tostring(strategy.losstrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 4, text = str.tostring(math.round(100*strategy.wintrades/strategy.closedtrades,2)), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 5, text = str.tostring(math.round(strategy.netprofit)), bgcolor=color.white)




//New Equity curve
var newcurve = array.new_float(0)
var int ida = 0
var bool printEQ = false
if newch !=0 
    array.push(newcurve, neweq)
if bar_index > last_bar_index - array.size(newcurve) - 1 - 20  and array.size(newcurve) > 20 
    printEQ := true
else
    printEQ := false

plot(printEQ and ida < strategy.closedtrades and shEQfilt ? array.get(newcurve, ida) : na, color=color.green, linewidth = 2)

if printEQ
    ida := ida + 1
if ida >= array.size(newcurve) and printEQ
    ida := array.size(newcurve) -1



//Original Equity curve
var newcurve2 = array.new_float(0)
var int ida2 = 0
var bool printEQ2 = false
if ch !=0 
    array.push(newcurve2, eq)
if bar_index > last_bar_index - array.size(newcurve2) - 1 - 20  and array.size(newcurve2) > 20 
    printEQ2 := true
else
    printEQ2 := false

plot(printEQ2 and ida2 < strategy.closedtrades and shEQandMA  ? array.get(newcurve2, ida2) : na, color=color.blue, linewidth = 2)

if printEQ2
    ida2 := ida2 + 1
if ida2 >= array.size(newcurve2) and printEQ2
    ida2 := array.size(newcurve2) -1



//Moving Average Array
var marray = array.new_float(0)
if ch
    array.push(marray, mova)

plot(printEQ2 and  array.size(marray) > 40 and shEQandMA ? array.get(marray, ida2-1) : na, color=color.red, linewidth = 1)

hline(0,"0 line", color=color.black, linestyle = hline.style_dotted)


if (last_bar_index-1) and array.size(newcurve2) > 20 and array.size(newcurve) > 20
    l = label.new(bar_index+2, array.get(newcurve2, array.size(newcurve2)-1), "Original Equity Curve", color=color.rgb(33, 149, 243, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(l[1])
    f = label.new(bar_index+2, array.get(newcurve, array.size(newcurve)-1), "Filtered Equity Curve", color=color.rgb(69, 238, 97, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(f[1])

Plus de