Estrategia de negociación de redes inteligentes adaptativas

El autor:¿ Qué pasa?, Fecha: 2024-01-16 14:51:48
Las etiquetas:

img

Resumen general

Esta estrategia es una estrategia de negociación de red inteligente adaptativa basada en la plataforma TradingView, escrita en Pine Script v4.

Estrategia lógica

Características clave

  1. Pirámide y gestión del dinero:

    • Permite hasta 14 adiciones en la misma dirección (piramidación),
    • Utiliza una estrategia basada en el efectivo para gestionar el tamaño de las posiciones,
    • El capital inicial se fija en 100 USD a efectos de simulación,
    • Se cobra una pequeña comisión del 0,1% por cada operación.
  2. Límites de la red:

    • Los usuarios pueden optar por utilizar límites calculados automáticamente o establecer manualmente los límites superior e inferior de la red,
    • Los límites automáticos pueden derivarse de los recientes altos y bajos del precio o de un promedio móvil simple (SMA),
    • Los usuarios pueden definir el período de retroceso para el cálculo de los límites y ajustar la desviación para ampliar o reducir los límites.
  3. Líneas de la red:

    • La estrategia permite un número personalizable de líneas de red dentro de los límites, con un rango recomendado entre 3 y 15,
    • Las líneas de la cuadrícula están uniformemente espaciadas entre los límites superior e inferior.

Estrategia lógica

  • Entrada:

    • El guión coloca órdenes de compra cuando el precio cae por debajo de una línea de red y no hay ninguna orden existente asociada a esa línea de red.
    • Cada cantidad de orden de compra se calcula sobre la base del capital inicial dividido por el número de líneas de red, ajustado al precio actual.
  • Salida:

    • Las órdenes de venta se activan cuando el precio se eleva por encima de una línea de cuadrícula, siempre que exista una orden abierta correspondiente a la siguiente línea inferior de la cuadrícula.
  • Cuadrícula adaptativa:

    • Si se establece en límites automáticos, la red se adapta a las condiciones cambiantes del mercado recalculando los límites superior e inferior y ajustando la red en consecuencia.

Análisis de ventajas

La estrategia integra la naturaleza sistemática y la ejecución eficiente de la negociación en red. Permitir la pirámide y el uso de la gestión del dinero puede controlar los riesgos de manera efectiva. La red de adaptación automática se adapta a diferentes condiciones del mercado. Los parámetros ajustables se adaptan a diferentes estilos de negociación.

Análisis de riesgos

Una ruptura de precios más allá de los límites de la red puede causar pérdidas graves. Los parámetros deben ajustarse adecuadamente o combinarse con un stop loss para controlar los riesgos. Además, el comercio excesivo aumenta los costos de transacción.

Direcciones de optimización

Considere combinarlo con un filtro de tendencia u optimizar los parámetros de la red.

Conclusión

Esta estrategia genera sistemáticamente entradas y salidas mientras gestiona posiciones. A través de la puesta a punto de parámetros se adapta a diferentes preferencias. Combina la naturaleza basada en reglas de la negociación de la red con la flexibilidad de la negociación de tendencias, facilitando la complejidad de la operación mientras se conserva la robustez.


/*backtest
start: 2024-01-08 00:00:00
end: 2024-01-15 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)

Más.