La stratégie de couverture des risques de négociation en réseau est une stratégie de négociation quantitative basée sur le concept de négociation en réseau, combinée à l'idée de couverture des risques. La stratégie fixe plusieurs ordres d'achat et de vente dans une plage de prix prédéfinie pour tirer profit des fluctuations des prix.
Le principe de base de cette stratégie est la négociation sur la grille. Premièrement, en fonction des paramètres définis par l'utilisateur, les limites supérieures et inférieures de la grille et le nombre de lignes de grille sont déterminés. Ensuite, les ordres d'achat et de vente sont placés sur les lignes de grille: lorsque le prix touche une ligne de grille, si aucun ordre n'était sur cette ligne de grille auparavant, une position est ouverte; s'il y avait un ordre auparavant, la position est fermée. De cette façon, la stratégie peut continuellement ouvrir et fermer des positions dans les fluctuations de prix pour réaliser des profits.
En même temps, pour réduire les risques, la stratégie introduit un mécanisme dynamique d'ajustement des limites du réseau. Selon le choix de l'utilisateur, les limites supérieure et inférieure du réseau peuvent être ajustées automatiquement de deux manières: 1) en fonction des prix les plus élevés et les plus bas de la période récente, en tenant compte de l'écart défini par l'utilisateur; 2) en se basant sur la ligne moyenne mobile, en tenant compte de l'écart défini par l'utilisateur. En ajustant dynamiquement les limites du réseau, le réseau peut toujours être centré autour du prix actuel, réduisant ainsi le risque de rupture des prix à travers les limites du réseau.
En outre, lors de l'ouverture d'une position, la stratégie divise le total des fonds en N parties égales, et chaque fois qu'elle ouvre une position, elle utilise un montant égal de fonds, ce qui peut réduire le risque d'une seule transaction.
Une grande adaptabilité: en ajustant dynamiquement les limites du réseau, la stratégie peut s'adapter à différents environnements de marché.
Risque contrôlable: la stratégie utilise des montants égaux de fonds lors de l'ouverture de positions, de sorte que le risque d'une seule transaction est faible; en même temps, le mécanisme d'ajustement dynamique des limites du réseau peut réduire le risque de rupture des prix.
Fréquence de négociation élevée: comme la grille comporte généralement de nombreuses commandes, la fréquence de négociation est élevée, ce qui facilite le profit sur les marchés volatils.
Paramètres flexibles: les utilisateurs peuvent définir le nombre de grilles, les limites supérieures et inférieures, les paramètres d'ajustement dynamique, etc. en fonction de leurs préférences, s'adaptant ainsi à différents styles de négociation.
Faibles performances sur les marchés de tendance: si le prix continue à augmenter ou à baisser unilatéralement, en franchissant les limites du réseau, et que l'ajustement dynamique ne peut pas suivre la vitesse des changements de prix, la stratégie peut faire face à des risques plus importants.
Les frais de transaction: étant donné que la stratégie a une fréquence de négociation élevée, les frais de transaction peuvent avoir une certaine incidence sur les rendements.
Réglage incorrect des paramètres: si les paramètres sont réglés de manière incorrecte, par exemple trop de lignes de grille ou des réglages déraisonnables des limites de grille, cela peut entraîner une mauvaise performance de la stratégie.
Solutions: 1) Dans les marchés de tendance, envisager d'augmenter la plage d'ajustement des limites du réseau ou de la combiner avec des stratégies de tendance; 2) Choisir des bourses et des devises avec des frais de transaction inférieurs; 3) Avant l'opération réelle, les paramètres doivent être entièrement testés et optimisés.
Combiner avec d'autres stratégies: envisager de combiner les stratégies de négociation de réseau avec d'autres types de stratégies, telles que les stratégies de tendance, les stratégies de renversement moyen, etc., afin d'améliorer l'adaptabilité et la stabilité de la stratégie.
Améliorer le mécanisme d'ajustement dynamique: le mécanisme d'ajustement dynamique actuel de la stratégie est relativement simple et peut être optimisé davantage, par exemple en tenant compte de plus de facteurs (tels que le volume des transactions, la volatilité, etc.) et en adoptant des algorithmes plus avancés (tels que des algorithmes adaptatifs, des algorithmes d'apprentissage automatique, etc.).
Optimiser la gestion des fonds: Actuellement, la stratégie adopte une gestion équitable des fonds. Nous pouvons envisager d'introduire des méthodes de gestion des fonds plus avancées, telles que le critère Kelly, des méthodes d'optimisation, etc., pour améliorer encore l'efficacité de l'utilisation des fonds et les rendements.
Introduire le profit et le stop-loss: sur la base du trading en réseau, certaines logiques de profit et de stop-loss peuvent être introduites, telles que le déplacement du profit et du stop-loss, la volatilité, le profit et le stop-loss, etc., pour réduire davantage les risques de stratégie.
La stratégie de couverture des risques de trading en réseau est une stratégie de trading quantitative hautement automatisée, adaptable et contrôlable par le risque. Grâce au trading en réseau et à l'ajustement dynamique du réseau, la stratégie peut profiter dans diverses conditions de marché tout en contrôlant les risques. Cependant, la stratégie peut mal fonctionner sur les marchés de tendance et les frais de transaction peuvent avoir un impact sur les rendements. Par conséquent, une optimisation et une amélioration supplémentaires sont nécessaires dans les applications pratiques.
/*backtest start: 2024-03-19 00:00:00 end: 2024-03-23 00:00:00 period: 5m basePeriod: 1m 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)