
Se trata de una estrategia de comercio de cuadrícula dinámica de adaptación a múltiples espacios escrita en base a Pine Script. La idea central de la estrategia es calcular automáticamente el límite superior y inferior de una cuadrícula en función de los máximos y mínimos o promedios móviles simples de los precios más recientes, y luego dividir ese rango en varias líneas de la cuadrícula.
Calcular el límite superior y inferior de la grilla. Dependiendo de la elección del usuario, el límite superior y inferior se puede basar en los puntos más altos y más bajos de la línea N-K más reciente, y se puede configurar para ampliar o reducir el porcentaje; también se puede basar en el promedio móvil simple del precio de cierre de la línea N-K más reciente y configurar el porcentaje de desviación hacia arriba y hacia abajo.
Generar una matriz de líneas de la red. De acuerdo con el número de líneas de la red establecidas, dividir el rango de la red por un promedio y generar una matriz de líneas de la red correspondiente al precio.
Entrar/Aumentar la Posibilidad. Recorrer la línea de la rejilla de abajo hacia arriba. Si el precio de cierre actual es menor que el precio de una línea de la rejilla y esa línea de la rejilla no tiene una posición, se abre una opción en esa posición.
Salida/reducción de posiciones. Recorre la línea de la grilla de arriba a abajo. Si el precio de cierre actual es mayor que el precio de una línea de la grilla y la línea de la grilla inferior tiene una posición, aplana el polinomio de la línea de la grilla inferior. De esta manera, la reducción de posiciones continuará cuando el precio baje.
Ajuste dinámico. Si se selecciona la función de la red dinámica, cada línea K recomputará el límite superior e inferior de la red y la matriz de líneas de la red, lo que permite que la red se adapte continuamente a los cambios.
La estrategia de trading de la red puede adaptarse a situaciones de crisis y tendencias. En situaciones de crisis, la estrategia de la red puede mantener posiciones cerradas y ganar diferencias de precios. En situaciones de tendencia, la estrategia de la red puede mantener posiciones y obtener ganancias de tendencias debido a que la red sigue el movimiento de los precios.
El tamaño de cada posición abierta depende de la cantidad de cuadrados establecidos. La apertura de riesgo individual es pequeña y controlada. Al mismo tiempo, se cubre una cierta cantidad de pérdidas potenciales debido a que el precio se cerrará cuando toque la línea de la cuadrícula superior.
El nivel de automatización es alto. La estrategia es básicamente totalmente automática y no requiere intervención humana, y es adecuada para inversores que necesitan un rendimiento estable a largo plazo.
El usuario puede configurar el número de líneas de la cuadrícula de forma flexible, según las características del mercado, los parámetros de la cuadrícula dinámica, etc., para optimizar el rendimiento de la estrategia.
Riesgo de los cigüeñas negros. Si se encuentra con una caída extrema en el mercado, el precio se eleva directamente por debajo de la línea de la red más baja, la estrategia se llena de posición y se enfrenta a una gran retirada. Para reducir este riesgo, se puede establecer una condición de parada de pérdidas, una vez que las pérdidas alcancen la desvalorización, se cancela toda la posición.
La configuración de los parámetros de la cuadrícula es incorrecta. Si la cuadrícula es demasiado densa, la diferencia de precio de cada posición abierta será muy pequeña, y los honorarios pueden erosionar la mayor parte de los ingresos. Si la cuadrícula es demasiado ancha, la proporción de posiciones abiertas una vez es alta, y la brecha de riesgo es grande.
Riesgo de diferencia básica. La estrategia se basa en el precio actual para establecer las condiciones de apertura de la posición abierta. En mercados como los futuros, si el precio del contrato difiere mucho del precio de referencia, el precio de apertura de la posición abierta puede desviarse más de lo esperado.
Añadir filtro de tendencia. La estrategia de la cuadrícula no funciona bien en el caso de una tendencia unilateral. Se puede agregar un indicador de tendencia como filtro, como activar la cuadrícula solo cuando el ADX está por debajo de un determinado umbral, y cerrar la cuadrícula cuando la tendencia es evidente y solo tiene posiciones unilaterales.
Optimización de la señal. Se pueden superponer otras señales sobre la base de la red, como la red + la línea media, es decir, la red decide principalmente abrir posiciones abiertas, pero si el precio atraviesa una línea media, se abrirá la posición, de lo contrario no se abrirá.
Gestión de posiciones. La estrategia actual tiene posiciones fijas por parcela, que se pueden ajustar para reducir adecuadamente las posiciones por parcela cuando el precio está lejos del precio promedio del mercado, y aumentar las posiciones cuando están cerca del precio promedio del mercado, para mejorar la eficiencia en el uso de los fondos.
La densidad de la red se adapta a sí misma. Se ajusta la densidad de la red en función de la fluctuación dinámica de los precios, se puede aumentar adecuadamente el número de redes cuando la fluctuación es alta y se puede reducir el número de redes cuando la fluctuación es baja.
Esta estrategia es una estrategia de cuantificación de la línea media a largo plazo que se adapta a la red dinámica, puede abrir posiciones para obtener diferencias de precios en situaciones de agitación con frecuencia y también puede mantener una cierta dirección de apertura para obtener ganancias de tendencia en situaciones de tendencia. Es una estrategia de cuantificación de la línea media a largo plazo que tiene una gran capacidad de adaptación.
// 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)