RSI combiné à des bandes de Bollinger et à une stratégie quantitative de soutien/résistance dynamique

Auteur:ChaoZhang est là., Date: 24 janvier 2024
Les étiquettes:

img

Résumé

Cette stratégie utilise l'indicateur RSI pour juger des niveaux de surachat/survente sur le marché, combiné avec les bandes de Bollinger pour déterminer la plage de fluctuation des prix. En outre, un support/résistance dynamique est généré sur la base de prix élevés/faibles pour déclencher des ordres d'achat/vente uniquement lorsque le prix est proche des niveaux de support/résistance. Les utilisateurs peuvent définir une condition de filtre de tendance, telle qu'une moyenne mobile simple, pour s'assurer que la tendance des prix s'aligne sur les directions commerciales.

La logique de la stratégie

La stratégie est composée de 3 composantes clés RSI, Bollinger Bands et Dynamic S/R.

Le composant RSI évalue les niveaux de surachat/survente. Une baisse de RSI inférieure à 30 suggère une condition de survente et déclenche un signal d'achat. Une hausse supérieure à 70 suggère une condition de surachat et déclenche un signal de vente.

Les bandes de Bollinger sont des bandes supérieures/inférieures calculées à partir de la moyenne mobile des prix et de l'écart type, pour déterminer si le prix a franchi la plage de fluctuation normale.

La composante S/R utilise une méthode de calcul dynamique pour générer des niveaux clés de S/R basés sur des prix historiques élevés/faibles (ou des prix de clôture/ouverture) au cours de certaines périodes de rétrospective et des fourchettes en pourcentage, ainsi que des points d'inversion historiques des prix.

En résumé, cette stratégie n'engage des transactions d'achat/vente que lorsque l'indice RSI est suracheté/survendu, que le prix échappe aux bandes de Bollinger et que la proximité des niveaux dynamiques S/R est atteinte.

Les avantages

  1. L'indicateur RSI fondamental combiné à l'indicateur d'analyse technique Bollinger Bands. L'indicateur RSI évalue fondamentalement les niveaux de surachat/survente tandis que les Bollinger Bands déterminent les tendances techniques des prix.

  2. Le calcul dynamique des S/R est plus proche des S/R réels qui régissent le mouvement des prix.

  3. L'ajout d'un filtre de tendance améliore encore la précision du signal en filtrant le bruit lorsqu'il est combiné avec le RSI et les bandes de Bollinger.

Les risques

  1. Les paramètres RSI incorrects peuvent entraîner des erreurs de jugement. Une longueur de RSI trop courte augmente le bruit. Une configuration incorrecte du seuil de surachat/survente entraîne également des erreurs.

  2. Les paramètres incorrects des bandes de Bollinger tels que la longueur, le multiplicateur StdDev affectent la précision du jugement.

  3. Les utilisateurs doivent optimiser les paramètres S/R pour une plus grande pertinence pour le prix actuel.

  4. Cette stratégie a une logique relativement complexe avec de multiples indicateurs potentiellement causant des interférences. Les utilisateurs doivent tester des paramètres pour réduire les conflits.

Directions d'optimisation

  1. Testez et optimisez les paramètres de l'indice de volatilité, y compris la longueur, les seuils de surachat/de survente.

  2. Tester et optimiser les paramètres des bandes de Bollinger, y compris la longueur et le multiplicateur StdDev.

  3. Optimiser les paramètres S/R dynamiques pour aligner les niveaux S/R plus près du prix, par exemple en utilisant des périodes de rétrospective plus courtes ou moins de prix historiques élevés/faibles.

  4. Testez des indicateurs auxiliaires supplémentaires en combinaison avec le RSI, tels que KDJ, MACD, etc., pour améliorer la précision.

  5. Tester et optimiser les paramètres du filtre de tendance, en particulier la longueur du filtre, afin de prolonger la période d'attente et de réduire les ordres inversés inutiles.

Conclusion

Cette stratégie tire parti des forces de plusieurs indicateurs tels que le RSI, les bandes de Bollinger et le Dynamic S/R, avec une vérification croisée étendue pour une précision de signal robuste. L'ajout d'un filtre de tendance réduit encore le bruit.


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

//@version=5
strategy("RSI + BB + S/R Strategy with Trend Filter", shorttitle="RSI + BB + S/R + Trend Filter", overlay=true)

// RSI Settings
rsi_length = input.int(14, title="RSI Length")
overbought = input.int(70, title="Overbought Level")
oversold = input.int(30, title="Oversold Level")

// Bollinger Bands Settings
bb_length = input.int(20, title="BB Length")
bb_deviation = input.float(2.0, title="BB Deviation")

// Dynamic Support/Resistance Settings
pivot_period = input.int(10, title="Pivot Period")
pivot_source = input.string("High/Low", title="Pivot Source", options=["High/Low", "Close/Open"])
max_pivots = input.int(20, title="Maximum Number of Pivot", minval=5, maxval=100)
channel_width = input.int(10, title="Maximum Channel Width %", minval=1)
max_sr_levels = input.int(5, title="Maximum Number of S/R Levels", minval=1, maxval=10)
min_strength = input.int(2, title="Minimum Strength", minval=1, maxval=10)

// Trend Filter Settings
use_trend_filter = input.bool(false, title="Use Trend Filter")
trend_filter_length = input.int(50, title="Trend Filter Length")

// Calculate RSI and Bollinger Bands
rsi = ta.rsi(close, rsi_length)
basis = ta.sma(close, bb_length)
deviation = ta.stdev(close, bb_length)
upper_band = basis + bb_deviation * deviation
lower_band = basis - bb_deviation * deviation

// Plot Bollinger Bands on the chart
plot(upper_band, color=color.blue, title="Upper Bollinger Band")
plot(lower_band, color=color.red, title="Lower Bollinger Band")

// Dynamic Support/Resistance Calculation
float src1 = pivot_source == "High/Low" ? high : math.max(close, open)
float src2 = pivot_source == "High/Low" ? low : math.min(close, open)
float ph = ta.pivothigh(src1, pivot_period, pivot_period)
float pl = ta.pivotlow(src2, pivot_period, pivot_period)


// Calculate maximum S/R channel zone width
prdhighest = ta.highest(300)
prdlowest = ta.lowest(300)
cwidth = (prdhighest - prdlowest) * channel_width / 100

var pivotvals = array.new_float(0)

if ph or pl
    array.unshift(pivotvals, ph ? ph : pl)
    if array.size(pivotvals) > max_pivots
        array.pop(pivotvals)

get_sr_vals(ind) =>
    float lo = array.get(pivotvals, ind)
    float hi = lo
    int numpp = 0
    for y = 0 to array.size(pivotvals) - 1 by 1
        float cpp = array.get(pivotvals, y)
        float wdth = cpp <= lo ? hi - cpp : cpp - lo
        if wdth <= cwidth
            if cpp <= hi
                lo := math.min(lo, cpp)
            else
                hi := math.max(hi, cpp)
            numpp += 1
    [hi, lo, numpp]

var sr_up_level = array.new_float(0)
var sr_dn_level = array.new_float(0)
sr_strength = array.new_float(0)

find_loc(strength) =>
    ret = array.size(sr_strength)
    for i = ret > 0 ? array.size(sr_strength) - 1 : na to 0 by 1
        if strength <= array.get(sr_strength, i)
            break
        ret := i
    ret

check_sr(hi, lo, strength) =>
    ret = true
    for i = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
        if array.get(sr_up_level, i) >= lo and array.get(sr_up_level, i) <= hi or array.get(sr_dn_level, i) >= lo and array.get(sr_dn_level, i) <= hi
            if strength >= array.get(sr_strength, i)
                array.remove(sr_strength, i)
                array.remove(sr_up_level, i)
                array.remove(sr_dn_level, i)
            else
                ret := false
            break
    ret

if ph or pl
    array.clear(sr_up_level)
    array.clear(sr_dn_level)
    array.clear(sr_strength)
    for x = 0 to array.size(pivotvals) - 1 by 1
        [hi, lo, strength] = get_sr_vals(x)
        if check_sr(hi, lo, strength)
            loc = find_loc(strength)
            if loc < max_sr_levels and strength >= min_strength
                array.insert(sr_strength, loc, strength)
                array.insert(sr_up_level, loc, hi)
                array.insert(sr_dn_level, loc, lo)
                if array.size(sr_strength) > max_sr_levels
                    array.pop(sr_strength)
                    array.pop(sr_up_level)
                    array.pop(sr_dn_level)

// Calculate the Trend Filter
trend_filter = use_trend_filter ? ta.sma(close, trend_filter_length) : close

// Buy Condition (RSI + Proximity to Support + Trend Filter)
buy_condition = ta.crossover(rsi, oversold) and close <= ta.highest(high, max_sr_levels) and close >= ta.lowest(low, max_sr_levels) and (not use_trend_filter or close > trend_filter)

// Sell Condition (RSI + Proximity to Resistance + Trend Filter)
sell_condition = ta.crossunder(rsi, overbought) and close >= ta.lowest(low, max_sr_levels) and close <= ta.highest(high, max_sr_levels) and (not use_trend_filter or close < trend_filter)

// Strategy Orders
strategy.entry("Buy", strategy.long, when = buy_condition)
strategy.entry("Sell", strategy.short, when = sell_condition)

Plus de