Esta es una estrategia de negociación de cuadrícula dinámica adaptativa larga y corta basada en Pine Script. La idea central de esta estrategia es calcular automáticamente los límites superiores e inferiores de una cuadrícula en función de los máximos y mínimos de precios recientes o un promedio móvil simple, y luego dividir este rango uniformemente en múltiples líneas de cuadrícula. Cuando el precio alcanza una cierta línea de cuadrícula, abrirá una posición larga o cerrará una posición en ese nivel. De esta manera, la estrategia puede abrir y cerrar continuamente posiciones en un mercado de rango para capturar el margen de precios. Al mismo tiempo, ajustando dinámicamente los límites de la cuadrícula, también puede adaptarse a diferentes tendencias del mercado.
Calcular los límites de la cuadrícula: basados en la elección del usuario, los límites se pueden calcular a partir de los puntos más altos y más bajos de las velas N recientes, con la opción de ampliar o reducir el rango en un porcentaje; o pueden basarse en el promedio móvil simple de los precios de cierre de las velas N recientes, con la opción de establecer las proporciones de desviación ascendente y descendente.
Generar una matriz de líneas de red. De acuerdo con el número establecido de líneas de red, divide el rango de red de manera uniforme para generar una matriz de precios de líneas de red.
Si el precio de cierre actual es menor que un precio de línea de red y no hay una posición en esa línea de red, abra una posición larga en ese nivel. De esta manera, cuando el precio alcance líneas de red más altas, continuará agregando posiciones.
Posición de salida/reducción. Cruce las líneas de la cuadrícula de arriba a abajo. Si el precio de cierre actual es mayor que un precio de la línea de la cuadrícula y hay una posición en la línea de la cuadrícula debajo, cierre la posición larga en la línea de la cuadrícula inferior. De esta manera, cuando el precio vuelva a caer, continuará reduciendo las posiciones.
Ajuste dinámico: si se selecciona la función de red dinámica, los límites superior e inferior de la red y la matriz de líneas de red se recalcularán en cada vela, de modo que la red pueda adaptarse constantemente a medida que el mercado cambia.
La estrategia de negociación de la red puede adaptarse tanto a los mercados de rango como a los de tendencia. En un mercado de rango, la estrategia de la red puede abrir y cerrar continuamente posiciones para obtener el diferencial de precios; en un mercado de tendencia, debido a que la red sigue el movimiento de los precios, también puede mantener una cierta posición para obtener ganancias de tendencia.
El tamaño de la posición de cada apertura está determinado por el número establecido de redes, por lo que la exposición al riesgo individual es pequeña y controlable.
Esta estrategia puede ejecutarse básicamente de forma totalmente automática sin intervención manual, lo que es adecuado para los inversores que necesitan rendimientos constantes a largo plazo.
Parámetros flexibles: los usuarios pueden configurar de forma flexible el número de líneas de red, los parámetros de red dinámica, etc. de acuerdo con las características del mercado para optimizar el rendimiento de la estrategia.
En caso de un colapso extremo del mercado, si el precio cae directamente por debajo de la línea más baja de la cuadrícula, la estrategia estará en posiciones completas y enfrentará un descenso mayor.
Si la densidad de la red es demasiado alta, la propagación de cada apertura y cierre será muy pequeña, y los costos de transacción pueden erosionar la mayoría de las ganancias. Si la anchura de la red es demasiado grande, la relación de apertura única es alta y la exposición al riesgo es grande. Las características del activo subyacente deben evaluarse cuidadosamente para seleccionar los parámetros de la red apropiados.
El riesgo de base. Esta estrategia establece las condiciones de apertura y cierre basadas en el precio actual. En mercados como los futuros, si el precio del contrato difiere mucho del precio subyacente, los precios reales de apertura y cierre pueden desviarse significativamente de las expectativas.
Añadir filtro de tendencia. Las estrategias de cuadrícula no funcionan bien en mercados de tendencia unilaterales. Los indicadores de tendencia se pueden agregar como filtro, como activar la cuadrícula solo cuando el ADX está por debajo de un umbral, y cerrar la cuadrícula cuando la tendencia es obvia, solo manteniendo posiciones unilaterales.
Optimización de la señal. Otras señales pueden superponerse sobre la base de la cuadrícula, como la cuadrícula + promedio móvil, es decir, la apertura y el cierre están determinados principalmente por la cuadrícula, pero solo se abren posiciones cuando el precio cruza un cierto promedio móvil, de lo contrario no se abren posiciones. Esto puede reducir el costo de la apertura y el cierre frecuentes.
Actualmente, la posición de cada red en la estrategia está fija. Se puede establecer para reducir adecuadamente la posición de cada red cuando el precio está lejos del precio promedio del mercado y aumentar la posición cuando está cerca del precio promedio del mercado para mejorar la eficiencia de la utilización del capital.
Densidad de red adaptativa. Ajusta dinámicamente la densidad de la red de acuerdo con la volatilidad de los precios. Cuando la volatilidad es alta, el número de redes puede aumentarse apropiadamente; cuando la volatilidad es baja, el número de redes puede reducirse. Esto puede optimizar el ancho de la red y mejorar la utilización del capital.
A través de las redes dinámicas adaptativas, esta estrategia puede abrir y cerrar posiciones con frecuencia para obtener diferencias de precios en los mercados de rango, y también puede mantener un cierto grado de dirección de exposición en los mercados de tendencia para obtener ganancias de tendencia. Es una estrategia cuantitativa a medio y largo plazo con una fuerte adaptabilidad. Al establecer razonablemente la red que activa la lógica y la gestión de posiciones, se pueden lograr retornos constantes. Sin embargo, es necesario prestar atención a los riesgos de condiciones extremas de mercado y brechas de precios, lo que requiere establecer condiciones de stop-loss apropiadas para controlar. Además, hay más espacio para la optimización en la configuración de parámetros y la gestión de riesgos. La robustez y rentabilidad de la estrategia se pueden mejorar mediante la introducción de filtrado de tendencias, superposición de señales, gestión de posición, densidad de red adaptativa y otros medios. En resumen, basada en la lógica básica de las redes, esta estrategia incorpora un mecanismo adaptativo, que puede proporcionar nuevas ideas y referencias cuantitativas a mediano y largo
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © jcloyd //@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)