Estrategia de negociación de criptomonedas adaptativa basada en el arbitraje

El autor:¿ Qué pasa?, Fecha: 2024-01-19 14:17:50
Las etiquetas:

img

Resumen general

Esta es una estrategia de negociación de criptomonedas adaptativa basada en la metodología de negociación de la red para el arbitraje. Puede ajustar automáticamente el rango de precios del comercio de la red en función de las fluctuaciones del mercado y realizar operaciones de arbitraje eficientes dentro de ese rango de precios.

Principio de la estrategia

La idea central de esta estrategia es la siguiente:

  1. Calcular dinámicamente un rango de precios de la red de negociación basado en los precios históricos altos y bajos.

  2. Establecer N líneas de red a intervalos iguales dentro de este rango de precios.

  3. Cuando el precio se rompe a través de cada línea de la cuadrícula, abrir posiciones largas o cortas con una cantidad fija.

  4. Arbitraje entre líneas de red adyacentes y posiciones cerradas para obtener ganancias.

  5. Cuando el precio vuelva a entrar en el rango de la red, continúe abriendo posiciones al costo marginal de las líneas de la red.

  6. Repetir este ciclo para las operaciones de arbitraje de alta frecuencia dentro del rango de precios de la red.

Específicamente, la estrategia calcula primero los límites superior e inferior de la red en tiempo real de acuerdo con los parámetros de ventana de vista configurada (i_boundLookback) y el rango de volatilidad (i_boundDev).

Luego N líneas de red (i_gridQty) se dividen uniformemente entre los límites superior e inferior. Los precios de estas líneas de red se almacenan en la matriz gridLineArr.

Cuando el precio rompe una línea de cuadrícula, se utiliza una cantidad fija (capital estratégico dividido por el número de cuadrículas) para abrir posiciones largas o cortas.

Cuando el precio vuelve a romper la línea adyacente de la cuadrícula, puede combinarse con órdenes anteriores para arbitraje y cierre de posiciones para obtener ganancias.

Repetir este ciclo para el arbitraje de alta frecuencia dentro del rango de fluctuación de precios.

Análisis de ventajas

En comparación con las estrategias tradicionales de red, la mayor ventaja de esta estrategia es que el rango de red se ajusta automáticamente para adaptarse a las fluctuaciones del mercado, con las siguientes características:

  1. Totalmente automatizado, sin necesidad de intervención manual.

  2. Capaz de capturar las tendencias de precios y el comercio en la dirección de la tendencia.

  3. Riesgos controlables, evitando los riesgos de persecución unilateral.

  4. Alta frecuencia de operaciones y margen de ganancia.

  5. Fácil de entender, configuración simple.

  6. Alta utilización del capital, no fácilmente atrapado.

  7. Reflejar los cambios del mercado en tiempo real, adecuado para el comercio algorítmico.

Análisis de riesgos

Aunque la estrategia tiene muchas ventajas, también existen algunos riesgos, principalmente concentrados en:

  1. Posibilidad de mayores pérdidas en fluctuaciones extremas de precios.

  2. Requiere un período de retención adecuado y un par de operaciones para obtener beneficios.

  3. La escala de capital debe coincidir con el rango de volatilidad.

  4. Puede requerir un seguimiento y una optimización frecuentes de los parámetros.

Las contramedidas incluyen:

  1. Aumentar la distancia entre las redes para ampliar el alcance de la red.

  2. Elige pares comerciales más estables.

  3. Ajustar la escala de capital para garantizar la liquidez suficiente.

  4. Establecer mecanismos automáticos de vigilancia y alerta.

Direcciones de optimización

La estrategia se puede optimizar en los siguientes aspectos:

  1. Red dinámica: ajusta automáticamente los parámetros de la red en función de la volatilidad.

  2. Mecanismo de detención de pérdidas: establecer ubicaciones razonables de stop loss para limitar los riesgos extremos.

  3. Cuadrícula compuesta: combinar cuadrículas utilizando diferentes parámetros para diferentes períodos para maximizar el uso del tiempo.

  4. Aprendizaje automático: usar redes neuronales para optimizar automáticamente parámetros en lugar de reglas.

  5. Arbitraje entre mercados: arbitraje entre bolsas o pares de divisas.

Resumen de las actividades

En resumen, esta es una estrategia de negociación de criptomonedas adaptativa muy práctica para el arbitraje. En comparación con las estrategias de red tradicionales, su mayor característica es el ajuste automático del rango de la red en función de los cambios del mercado, lo que permite a los operadores configurar su propio rango de negociación. La lógica de la estrategia es clara y fácil de entender y configurar, adecuada para inversores individuales con alguna base y también como plantilla para algoritmos de negociación. Con el ajuste adecuado de parámetros, se puede lograr una eficiencia de utilización de capital muy alta.


/*backtest
start: 2024-01-11 00:00:00
end: 2024-01-18 00:00:00
period: 1m
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.