Esta estrategia establece una red de negociación dinámica para lograr ganancias constantes en medio de mercados volátiles. Cálcula automáticamente el espaciamiento de la red y el límite superior / inferior basado en el número preestablecido de líneas de red. Cuando el precio atraviesa cada línea de red, se construirán posiciones largas / cortas en lotes. Se obtendrán ganancias cuando el precio vuelva a alcanzar las líneas de red originales. La estrategia admite el ajuste manual y automático de los parámetros de la red para adaptarse a las condiciones cambiantes del mercado.
Calcular los límites de la red y la matriz de precios de las líneas de red basándose en los parámetros de entrada.
Cuando el precio cae por debajo de una línea de cuadrícula sin órdenes correspondientes, las órdenes largas se colocarán al precio de la línea de cuadrícula.
Si el ajuste automático está habilitado, los límites superior/inferior de la red, el espaciamiento de la red y las matrices de la red se recalcularán periódicamente en función de los datos recientes de las velas.
Realizar ganancias constantes en medio de un mercado volátil. Las posiciones largas / cortas se construyen y cierran en lotes a diferentes niveles de precios para lograr un beneficio general.
Apoya el ajuste manual y automático de parámetros. El ajuste manual ofrece un mejor control pero requiere intervención. El ajuste automático reduce la carga de trabajo y se adapta a la dinámica cambiante del mercado.
Cuando el precio rompe todas las líneas de la red, los riesgos están contenidos.
Ajuste el espaciado de la cuadrícula para ajustar la ganancia/pérdida por operación.
El riesgo de quedar atrapado en un golpe de suerte, las frecuentes oscilaciones de precios dentro del rango de la red pueden conducir a pérdidas.
Se requiere un capital inicial adecuado, ya que una financiación insuficiente no puede apoyar suficientes líneas de red.
Los números de cuadrícula extremos perjudican las ganancias. Demasiadas cuadrículas no aprovechan al máximo la volatilidad, mientras que demasiadas cuadrículas conducen a ganancias mínimas por operación. Se necesitan pruebas extensas para determinar la configuración óptima.
El ajuste automático corre el riesgo de manipulación de los precios y se basa en los candeleros recientes que pueden verse afectados por operaciones de precios a corto plazo.
Introduzca una lógica de stop loss como la de stop loss de seguimiento para restringir aún más el riesgo a la baja por dirección.
Optimizar los parámetros de la red a través del aprendizaje automático. Probar diferentes parámetros en condiciones de mercado y entrenar modelos de ML para obtener parámetros óptimos y adaptables.
Incorporar indicadores técnicos adicionales. Evaluar la fuerza de la tendencia actual con indicadores como MACD y RSI para guiar la cantidad de la red y el ajuste de parámetros.
Mejorar el control del riesgo estableciendo el porcentaje máximo de extracción permitido.
Esta estrategia utiliza plenamente las características de los mercados volátiles y logra ganancias constantes a través de un marco de negociación de red dinámica que ofrece flexibilidad de parámetros y facilidad de operación.
/*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)