Introducción a las estrategias detalladas de negociación de alta frecuencia para las criptomonedas

El autor:El inventor de la cuantificación, Creado: 2023-03-19 19:56:11, Actualizado: 2023-09-18 19:55:58

img

Escribí un artículo en 2020 introduciendo estrategias de comercio de alta frecuencia (https://www.fmz.com/digest-topic/6228Aunque recibió cierta atención, no fue muy profunda. Han pasado dos años y medio desde entonces, y el mercado ha cambiado. Después de publicar ese artículo, mi estrategia de alta frecuencia fue capaz de obtener ganancias estables durante mucho tiempo, pero las ganancias disminuyeron gradualmente e incluso se detuvieron en un momento dado. En los últimos meses, he dedicado tiempo a reformarla, y todavía puede obtener algunas pequeñas ganancias.

Condiciones para la negociación de alta frecuencia

Cuentas de reembolsos de la Comisión

Si el volumen de negociación diario es de 100 millones de U, el reembolso es de 5,000 U. Por supuesto, la tarifa del tomador todavía depende de la tasa VIP, por lo que si la estrategia no necesita tomar órdenes, el nivel VIP tiene poco efecto en la estrategia de alta frecuencia. Diferentes niveles de reembolsos de comisión están disponibles en diferentes intercambios, lo que requiere un alto volumen de negociación. En los primeros días, todavía había ganancias que se podían obtener sin reembolsos, pero a medida que se intensificaba la competencia, los reembolsos representaban una mayor proporción de las ganancias y los operadores de alta frecuencia perseguían las tasas más altas.

Velocidad

El comercio de alta frecuencia se llama así debido a su velocidad rápida. Unirse a un servidor de colocación de un intercambio comercial y obtener la latencia más baja y la conexión más estable se ha convertido en una de las condiciones de competencia. El tiempo de procesamiento interno de la estrategia también debe ser lo más bajo posible.

Mercado adecuado

El comercio de alta frecuencia se considera la joya de la corona del comercio cuantitativo, y creo que muchos comerciantes algorítmicos lo han intentado, pero la mayoría de la gente debería haberlo dejado porque no podían ganar dinero y no podían encontrar una manera de mejorar. La razón principal es probablemente porque eligieron el mercado de comercio equivocado. En la etapa inicial de la estrategia, los mercados relativamente fáciles deben dirigirse al comercio para obtener ganancias y recibir retroalimentación para mejorar, lo que es propicio para el progreso de la estrategia. Si comienzas en el mercado más ferozmente competitivo y compites con muchos oponentes, perderás dinero sin importar lo duro que lo intentes, y te rendirás rápidamente. Recomiendo comenzar con pares de comercio de contratos perpetuos recién lanzados, donde hay menos competidores, especialmente aquellos con volúmenes comerciales relativamente grandes, lo que facilita hacer dinero. BTC y ETH tienen los volúmenes más altos y más activos, pero también son los más difíciles de sobrevivir en el potencial.

Enfrenta a la competencia de frente

El mercado para cualquier negociación está cambiando constantemente, y ninguna estrategia de negociación puede ser una solución de una sola vez. Esto es aún más obvio en el comercio de alta frecuencia, donde ingresar al mercado significa competir directamente con los operadores más inteligentes y diligentes. En un mercado de juego de suma cero, cuanto más gane, menos ganan los demás. Cuanto más tarde entre, más difícil se vuelve, y los que ya están en el mercado deben mejorar constantemente y podrían eliminarse en cualquier momento. Hace tres o cuatro años probablemente fue la mejor oportunidad, pero con la reciente disminución general de la actividad en el mercado de divisas digitales, se ha vuelto muy difícil para los principiantes comenzar a hacer comercio de alta frecuencia.

Principios del comercio de alta frecuencia

Existen varias estrategias de trading de alta frecuencia, como el arbitraje de alta frecuencia, que implica encontrar oportunidades de arbitraje a través de este u otros intercambios, aprovechando la oportunidad de comer órdenes antes que otros y obtener ganancias con ventaja de velocidad; el trading de tendencias de alta frecuencia, que implica beneficiarse de tendencias a corto plazo; y el marketing, que implica colocar órdenes en ambos lados de las operaciones de compra y venta, controlar bien las posiciones y obtener ganancias a través de descuentos de comisión.

Arquitectura estratégica

El siguiente código se basa en la arquitectura básica del contrato perpetuo de Binance y se suscribe principalmente a las operaciones de flujo de pedidos de profundidad del websocket e información de posición. Dado que los datos de mercado e información de la cuenta se suscriben por separado, se necesita leer (-1) continuamente para determinar si se ha obtenido la información más reciente. Aquí, EventLoop (1000) se utiliza para evitar bucles muertos directos y reducir la carga del sistema. EventLoop (1000) bloquea hasta que haya un wss o retorno de tareas concurrentes, con un tiempo de espera de 1000 ms.

var datastream = null
var tickerstream = null
var update_listenKey_time = 0

function ConncetWss(){
    if (Date.now() - update_listenKey_time < 50*60*1000) {
        return
    }
    if(datastream || tickerstream){
        datastream.close()
        tickerstream.close()
    }
    // need APIKEY
    let req = HttpQuery(Base+'/fapi/v1/listenKey', {method: 'POST',data: ''}, null, 'X-MBX-APIKEY:' + APIKEY) 
    let listenKey = JSON.parse(req).listenKey
    datastream = Dial("wss://fstream.binance.com/ws/" + listenKey + '|reconnect=true', 60)
    // Symbols is the pair of symbol
    let trade_symbols_string = Symbols.toLowerCase().split(',')
    let wss_url = "wss://fstream.binance.com/stream?streams="+trade_symbols_string.join(Quote.toLowerCase()+"@aggTrade/")+Quote.toLowerCase()+"@aggTrade/"+trade_symbols_string.join(Quote.toLowerCase()+"@depth20@100ms/")+Quote.toLowerCase()+"@depth20@100ms"
    tickerstream = Dial(wss_url+"|reconnect=true", 60)
    update_listenKey_time = Date.now()
}

function ReadWss(){
    let data = datastream.read(-1)
    let ticker = tickerstream.read(-1)
    while(data){
        data = JSON.parse(data)
        if (data.e == 'ACCOUNT_UPDATE') {
            updateWsPosition(data)
        }
        if (data.e == 'ORDER_TRADE_UPDATE'){
            updateWsOrder(data)
        }        
        data = datastream.read(-1)
    }
    while(ticker){
        ticker = JSON.parse(ticker).data
        if(ticker.e == 'aggTrade'){
            updateWsTrades(ticker)
        }
        if(ticker.e == 'depthUpdate'){
            updateWsDepth(ticker)
        }
        ticker = tickerstream.read(-1)
    }
    makerOrder()
}

function main() {
    while(true){
        ConncetWss()
        ReadWss()
        worker()
        updateStatus()
        EventLoop(1000)
    }
}

Indicadores de la estrategia

Como se mencionó anteriormente, mi estrategia de alta frecuencia requiere primero identificar tendencias antes de ejecutar operaciones de compra y venta. Juzgar las tendencias a corto plazo se basa principalmente en los datos de transacción, es decir, el aggTrade suscrito, que incluye la dirección, el precio, la cantidad y el tiempo de la transacción. Las operaciones de compra y venta se refieren principalmente a la profundidad y el volumen de transacción. Los siguientes son indicadores detallados que deben considerarse, la mayoría de los cuales se dividen en dos grupos para comprar y vender y se cuentan dinámicamente dentro de una cierta ventana de tiempo.

  • El volumen promedio de negociación por transacción, que es la colección de transacciones en la misma dirección, precio y órdenes diferentes dentro de 100 ms. Esto refleja el tamaño de las órdenes de compra y venta y tiene un alto peso. Si el volumen de negociación de las órdenes de compra es mayor que el de las órdenes de venta, se puede asumir que el mercado está dominado por compradores.
  • La frecuencia de orden o el intervalo de orden, también basado en datos de transacción, el volumen de transacción promedio anterior no tuvo en cuenta el concepto de tiempo y no es del todo preciso. Si una orden en una dirección tiene un pequeño volumen promedio de transacción pero una alta frecuencia, también contribuye a la fuerza de esa dirección.
  • El diferencial actual es generalmente un tick, y si el diferencial aumenta, a menudo indica que hay una tendencia. Los precios medios de compra y venta, que calculan el precio medio de las transacciones de compra y venta respectivamente y los comparan con el precio más reciente.

Estrategia lógica

Evaluar las tendencias a corto plazo

let bull =  last_sell_price > avg_sell_price && last_buy_price > avg_buy_price &&
            avg_buy_amount / avg_buy_time > avg_sell_amount / avg_sell_time;
let bear =  last_sell_price < avg_sell_price && last_buy_price < avg_buy_price && 
            avg_buy_amount / avg_buy_time < avg_sell_amount / avg_sell_time;

Si el último precio de compra es mayor que el precio de venta promedio y el último precio de oferta es mayor que el precio de oferta promedio y el valor de la orden de compra es mayor que el valor de la orden de venta en un intervalo fijo, se considera que se trata de un mercado alcista a corto plazo.

Posicionamiento de órdenes

function updatePrice(depth, bid_amount, ask_amount) {

    let buy_price = 0
    let sell_price = 0
    let acc_bid_amount = 0
    let acc_ask_amount = 0

    for (let i = 0; i < Math.min(depth.asks.length, depth.bids.length); i++) {
        acc_bid_amount += parseFloat(depth.bids[i][1])
        acc_ask_amount += parseFloat(depth.asks[i][1])
        if (acc_bid_amount > bid_amount  && buy_price == 0) {
            buy_price = parseFloat(depth.bids[i][0]) + tick_size
        }
        if (acc_ask_amount > ask_amount  && sell_price == 0) {
            sell_price = parseFloat(depth.asks[i][0]) - tick_size
        }
        if (buy_price > 0 && sell_price > 0) {
            break
        }
    }
    return [buy_price, sell_price]
}

Aquí, el viejo método de iteración de la profundidad a la cantidad requerida todavía se utiliza. Suponiendo que una orden de compra que puede ser ejecutada por 10 monedas en 1 segundo y sin considerar la situación de nuevas órdenes, el precio de venta se establece en la posición donde la orden de compra

El tamaño de la ventana de tiempo específica debe ser fijado por uno mismo.

Cantidad del pedido

let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time

La relación representa una proporción fija de la cantidad de la última orden de venta, representando la cantidad de la orden de compra como una proporción fija de la cantidad de la última orden de venta.

Condiciones de pedido

if(bull && (sell_price-buy_price) > N * avg_diff) {
    trade('buy', buy_price, buy_amount)
}else if(position.amount < 0){
    trade('buy', buy_price, -position.amount)
}
if(bear && (sell_price-buy_price) >  N * avg_diff) {
    trade('sell', sell_price, sell_amount)
}else if(position.amount > 0){
    trade('sell', sell_price, position.amount)
}

Entre ellos, el avg_diff es la diferencia promedio en el spread, y solo cuando la diferencia de compra y venta en la colocación de órdenes es mayor que un cierto múltiplo de este valor y el mercado es alcista, se colocará una orden de compra. Si se mantiene una posición corta, la posición también se cerrará para evitar mantener la posición durante mucho tiempo. Se pueden colocar órdenes solo para garantizar que se cumplan las órdenes, y se pueden usar ID de orden personalizadas para evitar esperar las devoluciones de órdenes.

Arquitectura simultánea

var tasks = []
var jobs = []

function worker(){
    let new_jobs = []
    for(let i=0; i<tasks.length; i++){
        let task = tasks[i]
        jobs.push(exchange.Go.apply(this, task.param))
    }
    _.each(jobs, function(t){
        let ret = t.wait(-1)
        if(ret === undefined){
            new_jobs.push(t)//未返回的任务下次继续等待
        }
    })
    jobs = new_jobs
    tasks = []
}

/*
tasks.push({'type':'order','param': ["IO", "api", "POST","/fapi/v1/order",
        "symbol="+symbol+Quote+"&side="+side+"&type=LIMIT&timeInForce=GTX&quantity="+
        amount+"&price="+price+"&newClientOrderId=" + UUID() +"&timestamp="+Date.now()]})
*/

Datos de seguimiento

  • Latencia: se ha enfatizado la importancia de la velocidad de las estrategias de negociación de alta frecuencia. La estrategia necesita monitorear y registrar varias latencias, como la colocación de órdenes, cancelación de órdenes, posiciones de retorno, profundidad, flujo de órdenes, ciclo general, etc. Cualquier latencia anormal debe investigarse rápidamente y se deben encontrar formas de acortar la latencia general de la estrategia.
  • La proporción de volumen: Las estadísticas muestran la proporción del volumen de operaciones respecto al volumen total de operaciones. Si la proporción es baja, todavía hay margen de mejora. En las horas pico, la proporción de la estrategia puede alcanzar el 10% o más del volumen total de operaciones.
  • Tasa de ganancia de cierre: Las estadísticas muestran la tasa de ganancia media de cierre, que es la referencia más importante para juzgar si la estrategia es efectiva.
  • Relación de descuentos: Las estadísticas muestran la proporción de descuentos en el total de ingresos, lo que refleja el grado en que la estrategia depende de los descuentos. Tasa de fracaso de la orden: las órdenes sólo se colocan y se cumplen, pero debido a los retrasos en la colocación de órdenes, pueden no ser cumplidas.
  • Ratio de ejecución de órdenes: La plataforma a menudo tiene requisitos para los ratios de ejecución de órdenes. Si es demasiado bajo, indica que la estrategia está cancelando órdenes con demasiada frecuencia y necesita ser resuelta. Distancia media de órdenes de compra y venta: estos datos reflejan la distancia entre la colocación de órdenes de la estrategia y la profundidad del mercado, y la mayoría de las órdenes todavía ocupan las posiciones de las órdenes de compra y venta.

Otros consejos

  • La estrategia de alta frecuencia en este artículo se limita a intercambios únicos, pares de divisas únicos y condiciones de mercado único, y tiene una aplicabilidad limitada. La mayoría de las monedas no pueden ser rentables, pero es imposible predecir qué monedas serán rentables en el futuro, por lo que se recomienda negociar múltiples o incluso todas las monedas para no perder oportunidades. Incluso bajo las restricciones de frecuencia del intercambio, un solo robot puede negociar múltiples pares de operaciones. Por supuesto, para la mejor velocidad, una subcuenta puede negociar un par de operaciones, un servidor corresponde a un robot, pero este enfoque tendrá costos mucho más altos.
  • Determinar el tamaño del pedido y las condiciones basadas en la rentabilidad. El comercio de múltiples monedas puede resultar en un costo demasiado alto de intentarlo, por lo que si el monitoreo muestra que no es rentable, reduzca la frecuencia de negociación y use el volumen mínimo de negociación hasta que la estrategia detecte dinámicamente una tasa de ganancia positiva y luego aumente gradualmente el volumen de negociación para mejorar la rentabilidad.
  • Obtener más información: Otra característica del comercio de alta frecuencia es que maneja más datos y utiliza más información. Todos los datos de mercado para un solo intercambio y par de divisas deben considerarse, y los datos perpetuos también pueden referirse a datos al contado o datos para el mismo par de divisas en otros intercambios o incluso otras monedas.

Relacionados

Más.