Stratégie de trading de grille quantitative adaptative active


Date de création: 2024-02-02 18:08:22 Dernière modification: 2024-02-02 18:08:22
Copier: 0 Nombre de clics: 919
1
Suivre
1617
Abonnés

Stratégie de trading de grille quantitative adaptative active

Aperçu

Cette stratégie permet de réaliser des profits stables dans des conditions de volatilité en établissant une grille de transactions dynamiquement ajustée. La stratégie calcule automatiquement l’espacement de la grille et le prix de la limite supérieure et inférieure en fonction du nombre de grilles définies.

Principe de stratégie

  1. Calculer les limites de la grille et l’arrangement des prix des lignes de la grille en fonction des paramètres d’entrée.

  2. Lorsqu’un prix est inférieur à une ligne de grille et qu’il n’y a pas d’offre correspondante, un surcompte est créé au point de prix de cette ligne de grille; lorsqu’un prix est supérieur à la ligne de grille précédente (à l’exception de la première) et que la ligne de grille précédente contient une offre de détention correspondante, un surcompte correspondant à la ligne de grille précédente est effacé.

  3. Si le paramètre d’ajustement automatique de la grille est activé, le prix, l’espacement et l’arrangement de la grille sont recalculés périodiquement en fonction du nombre de lignes K les plus récentes.

Analyse des avantages

  1. L’objectif de rentabilité est atteint dans des conditions de volatilité. Dans des conditions de baisse, il est possible d’établir des positions de détention et de plafonnement en lots à différents points de prix, ce qui permet de réaliser une rentabilité globale.

  2. Il est possible de choisir d’ajuster manuellement ou automatiquement les paramètres de la grille. L’ajustement manuel nécessite une intervention humaine, mais est plus contrôlable. L’ajustement automatique réduit le travail opérationnel et permet à la stratégie de s’adapter aux changements de l’environnement du marché.

  3. En limitant le nombre maximal de grilles, le risque unilatéral est contrôlé. Le risque dans cette direction est contrôlé lorsque le prix franchit toutes les lignes de la grille.

  4. Il est possible de contrôler la marge de perte de chaque lot en ajustant l’espacement des grilles.

Analyse des risques

  1. Il existe un risque d’arbitrage dans des conditions de forte volatilité. Si le prix fluctue rapidement entre plusieurs grilles, il peut y avoir un risque d’arbitrage.

  2. Il est nécessaire d’établir un montant initial raisonnable. Si le montant initial est insuffisant, il est impossible de soutenir un nombre suffisant de lignes de grille.

  3. Un nombre de grilles trop élevé ou trop faible ne favorise pas les gains stratégiques. Un nombre de grilles trop faible ne permet pas d’exploiter pleinement les fluctuations.

  4. Il existe un risque de manipulation des paramètres de la grille d’ajustement automatique. Le calcul des paramètres de la grille dépend d’un certain nombre de lignes K et peut être affecté par des opérations à court terme.

Direction d’optimisation

  1. Augmentation de la logique d’arrêt des pertes. Par exemple, la mise en place d’un arrêt flottant ou d’un arrêt de suivi pour contrôler davantage le risque de pertes unilatérales.

  2. L’ajout d’algorithmes pour optimiser les paramètres de la grille. Les paramètres peuvent être testés à différents stades du marché, puis les modèles peuvent être formés à l’aide de méthodes d’apprentissage automatique pour optimiser automatiquement les paramètres.

  3. Combinez plus d’indicateurs pour juger de la situation. Les jugements tels que MACD, KD et autres sont actuellement en tendance haussière ou baissière pour ajuster le nombre de grilles ou les paramètres.

  4. Optimiser le contrôle des retraits. Par exemple, définir le taux de retrait maximal et fermer la stratégie lorsque le seuil est atteint, pour éviter que les pertes ne s’étendent davantage.

Résumer

Cette stratégie exploite pleinement les caractéristiques de la volatilité et vise à réaliser des bénéfices stables grâce à la négociation dynamique de la grille. La stratégie prend en compte à la fois la flexibilité des paramètres de configuration et réduit l’intensité du travail de l’opération.

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

//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds    = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool)                             // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc      = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"])     // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev      = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1)  // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound    = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float)                      // for manual grid bounds only. The upperbound price of your grid
i_lowerBound    = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float)                      // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty       = input(group="Grid Lines",  title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer)       // how many grid lines are in your grid

f_getGridBounds(_bs, _bl, _bd, _up) =>
    if _bs == "Hi & Low"
        _up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl)  * (1 - _bd)
    else
        avg = sma(close, _bl)
        _up ? avg * (1 + _bd) : avg * (1 - _bd)

f_buildGrid(_lb, _gw, _gq) =>
    gridArr = array.new_float(0)
    for i=0 to _gq-1
        array.push(gridArr, _lb+(_gw*i))
    gridArr

f_getNearGridLines(_gridArr, _price) =>
    arr = array.new_int(3)
    for i = 0 to array.size(_gridArr)-1
        if array.get(_gridArr, i) > _price
            array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
            array.set(arr, 1, i == 0 ? i : i-1)
            break
    arr

var upperBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound  // upperbound of our grid
var lowerBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth       = (upperBound - lowerBound)/(i_gridQty-1)                                                       // space between lines in our grid
var gridLineArr     = f_buildGrid(lowerBound, gridWidth, i_gridQty)                                                 // an array of prices that correspond to our grid lines
var orderArr        = array.new_bool(i_gridQty, false)                                                              // a boolean array that indicates if there is an open order corresponding to each grid line

var closeLineArr    = f_getNearGridLines(gridLineArr, close)                                                        // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
strategy.initial_capital = 50000
for i = 0 to (array.size(gridLineArr) - 1)
    if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
        buyId = i
        array.set(orderArr, buyId, true)
        strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
    if close > array.get(gridLineArr, i) and i != 0
        if array.get(orderArr, i-1)
            sellId = i-1
            array.set(orderArr, sellId, false)
            strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))

if i_autoBounds
    upperBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
    lowerBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
    gridWidth   := (upperBound - lowerBound)/(i_gridQty-1)
    gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)

closeLineArr    := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)