En la carga de los recursos... Cargando...

Explorar FMZ: estrategias de transacción y prácticas de protocolos de comunicación entre discos

El autor:Los inventores cuantifican - sueños pequeños, Creado: 2024-08-06 14:13:40, Actualizado: 2024-08-07 15:30:13

[TOC] ¿Qué quieres decir?

img

Con el rápido desarrollo de los mercados financieros y la popularidad de las transacciones cuantitativas, cada vez más comerciantes comienzan a confiar en estrategias automatizadas para operar. En este proceso, la comunicación y la coordinación entre las estrategias se vuelven especialmente importantes. FMZ (Quantitative Trading Platform) ayuda a los comerciantes a implementar la combinación sin fisuras de estrategias y el intercambio de datos en tiempo real mediante la prestación de protocolos de comunicación entre discos de estrategias comerciales eficientes.

En este artículo se profundizará en el protocolo de comunicación interdisciplinaria de estrategias de negociación en la plataforma FMZ, se presentarán sus conceptos de diseño, características funcionales y ventajas en la aplicación práctica. Se mostrará cómo utilizar este protocolo para lograr una comunicación estratégica eficiente y estable, mejorar la ejecución y rendimiento de las estrategias de negociación a través de un análisis de casos detallados.

Ya sea que usted sea un aficionado a la transacción cuantitativa de FMZ o un programador profesional experimentado, este artículo le proporcionará valiosas ideas y guías prácticas. Exploremos juntos las potentes funciones de FMZ y descubramos cómo lograr la colaboración sincronizada entre estrategias a través de protocolos de comunicación eficientes, mejorar la eficiencia de las transacciones y capturar las oportunidades del mercado.


El escenario de la demanda

    1. Negociación conjunta estratégica El escenario de la demanda: En un entorno de mercado complejo, una sola estrategia puede no ser capaz de responder a una variedad de situaciones y cambios en el mercado. Los operadores desean operar simultáneamente varias estrategias, como estrategias de seguimiento de tendencias, estrategias de retorno de valor medio y estrategias de alquiler, y permitir que se comunique en tiempo real entre estas estrategias para compartir información de mercado y señales de negociación, lo que mejora la eficiencia y estabilidad de la negociación en general.
    1. El interés de los mercados El escenario de la demanda: Los comerciantes desean operar con el interés de los mercados de negociación diferentes. Por ejemplo, aprovechar la diferencia entre el mercado de acciones A y el mercado de acciones de capital riesgo para obtener el interés. Cuando un mercado tiene un precio anormal, la estrategia necesita informar a los otros mercados de manera oportuna para realizar operaciones de compra y venta correspondientes para capturar las oportunidades de interés.
    1. Gestión de riesgos y cobertura El escenario de la demanda: Una estrategia se encarga de buscar y ejecutar operaciones de alto riesgo y alto rendimiento en el mercado, mientras que otra estrategia se centra en monitorear el riesgo general y ejecutar operaciones de cobertura. Para garantizar que no se sufran demasiadas pérdidas durante las operaciones de alto riesgo, ambas estrategias requieren comunicación y intercambio de datos en tiempo real para ajustar las posiciones y el riesgo de cobertura en el momento oportuno.
    1. Sistemas de negociación distribuidos El escenario de la demanda: Las grandes entidades desean operar sistemas de negociación distribuidos en varios servidores físicos para mejorar la tolerancia y el rendimiento de los sistemas de negociación. La estrategia en estos servidores requiere la sincronización y coordinación de operaciones de datos a través de protocolos de comunicación, lo que garantiza el funcionamiento estable y eficiente del sistema de negociación en general.
    1. Monitoreo y alerta de mercado El escenario de la demanda: Una estrategia se encarga de monitorear en tiempo real la dinámica del mercado, y cuando se producen cambios importantes en el mercado (como caídas o subidas repentinas de precios), la estrategia necesita informar rápidamente a otras estrategias para realizar acciones de respuesta correspondientes, como liquidar, cambiar o aumentar las posiciones, para reducir el riesgo o aprovechar las oportunidades comerciales.
    1. Gestión de estrategias de combinación El escenario de la demanda: Los operadores utilizan una combinación de estrategias para gestionar inversiones en diferentes categorías de activos, cada una de las cuales se centra en una categoría específica de activos (por ejemplo, acciones, bonos, futuros, etc.). Estas estrategias requieren comunicación y coordinación para optimizar y maximizar los beneficios de la inversión de la colección.

Estos escenarios de demanda muestran las múltiples posibilidades y ventajas de los protocolos de comunicación interdispositivos de la estrategia de negociación FMZ en aplicaciones prácticas. Con una comunicación interdispositiva estratégica efectiva, los operadores pueden responder mejor al complejo entorno del mercado, optimizar la estrategia de negociación, mejorar la eficiencia y los beneficios de las transacciones.


Protocolo de comunicación envuelto en FMZ y función Dial

Una vez entendidas las necesidades de comunicación entre los discos físicos, es necesario pensar en cómo lograrlas. No es nada más que el disco A desea interactuar con el disco B, aunque a primera vista las necesidades son simples. Sin embargo, hay varios detalles que requieren un conjunto de protocolos de comunicación para acordar, FMZ ya ha envasado varios protocolos de comunicación más populares.

Mqtt / nats / amqp / kafka

Arquitectura de las comunicaciones

La arquitectura de comunicación es:

  • El servidor es un agente. Se requiere un servidor con un protocolo de comunicación para retransmitir mensajes entre los suscriptores y los editores. Este servidor se puede implementar localmente (comunicación local entre discos) en el sistema donde se encuentra el anfitrión; también puede ser un servicio remoto (comunicación entre discos entre servidores).
  • Los clientes (suscriptores, editores) El programa de disco duro en FMZ puede entenderse como un cliente de un protocolo de comunicación, el disco duro puede ser un editor (pub) o un suscriptor (sub).

Función de marcado

Cuando se aplican estos protocolos en la plataforma FMZ, se pueden entender simplemente como mqtt / nats / amqp / kafka.Dial()En función, el usoDial()Las funciones realizan mensajes, suscripciones, etc. Estas mensajes se envían a través de los agentes del servidor del protocolo (repetidos) al disco físico del suscriptor, por lo que primero se debe ejecutar un servidor del protocolo. Para facilitar la demostración, en los siguientes ejemplos utilizamos una variedad de implementaciones de imágenes de servidor del protocolo.

La sección de la API donde se encuentra la función Dial:https://www.fmz.com/syntax-guide#fun_dial

Antes de implementar el espejo de Docker, recuerde que debe instalar el software de Docker.

img

A continuación, vamos a explorar y practicar las aplicaciones de protocolo de comunicación que FMZ apoya.


Práctica de protocolo de comunicación en disco real de la plataforma FMZ

Protocolo de mqtt

MQTT (Message Queuing Telemetry Transport) es un protocolo de mensajería ligero, especialmente para entornos de red de baja banda ancha, alta latencia o poco confiables. Fue propuesto por Andy Stanford-Clark y Arlen Nipper de IBM en 1999 y se convirtió en un estándar ISO (ISO/IEC PRF 20922) en el año 2000.

Principales características del protocolo MQTT: modelo de publicación / suscripción

  • Publicación: Los productores de noticias envían mensajes a los temas.
  • Suscripción: Los consumidores de mensajes se suscriben a los temas de interés para recibir mensajes publicados sobre ese tema.
  • Intermediario: MQTT utiliza un agente de mensajes (Broker) como intermediario para reenviar mensajes, asegurando la desvinculación entre los publicadores y los suscriptores.

Publicaciones y suscripciones

Debido a que implementamos servidores proxy de MQTT con software que soporta el protocolo MQTT (eclipse-mosquitto mirror), instalar el docker con anticipación es una opción.

Antes de ejecutar el comando de despliegue del espejo, necesitamos escribir un perfil de servidor proxy.mosquitto.conf

# 配置端口号及远程访问IP
listener 1883 0.0.0.0
# 设置匿名访问
allow_anonymous true

Luego ejecuta el comando de despliegue:

docker run --rm -p 1883:1883 -v ./mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto

La imagen del servidor proxy muestra lo siguiente cuando se pone en marcha:

1723012640: mosquitto version 2.0.18 starting
1723012640: Config loaded from /mosquitto/config/mosquitto.conf.
1723012640: Opening ipv4 listen socket on port 1883.
1723012640: mosquitto version 2.0.18 running

Entonces podemos probar la estrategia y ponerla en práctica.

var conn = null

function main() {
    LogReset(1)
    var robotId = _G()
    Log("当前实盘robotId:", robotId)

    conn = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
    if (!conn) {
        Log("通信失败!")
        return 
    }

    for (var i = 0; i < 10; i++) {
        // 写入
        var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()        
        conn.write(msg)
        Log("向testQueue写入消息:", msg)

        // 读取
        Log("read:", conn.read(1000), "#FF0000")

        Sleep(1000)
    }    
}

function onexit() {
    conn.close()
    Log("关闭conn")
}

El código estratégico utiliza principalmente la función Dial:

Dial("mqtt://127.0.0.1:1883?topic=test_topic")

La función Dial tiene el principio de la cadena de los parámetrosmqtt://Es el nombre del protocolo, seguido de la dirección de escucha, el puerto, el símbolo "¿?" y el nombre del tema de suscripción / publicación, donde el nombre del tema de prueba se llama:test_topic

Las estrategias anteriores para publicar, suscribir y ejecutar pruebas en un tema son las siguientes:

img

También se puede usar dos discos virtuales para suscribirse entre sí, publicar información temática, un ejemplo que usamos en el capítulo de prácticas del protocolo nats, que no se describe de esta manera en otros protocolos.


El acuerdo nats

El protocolo de NATS es un protocolo simple, de estilo de publicación/subscripción basado en texto. El cliente se conecta a gnatsd (servidor NATS) y se comunica con gnatsd, se comunica basado en el protocolo TCP/IP común y se define un conjunto de operaciones muy pequeño, que cambia de línea para indicar terminación. A diferencia de los sistemas de comunicación de mensajes tradicionales, que utilizan un formato de mensaje binario, el protocolo de NATS basado en texto permite una implementación muy simple para el cliente, que puede elegir fácilmente entre varios lenguajes de programación o lenguajes de script para implementar.

Cada acuerdo tiene sus propias características y se puede consultar documentación específica, información que no se describe aquí.

Para implementar el servidor de protocolos nats:

el nombre de los usuarios de Docker Run nombre nats rm -p 4222:4222 -p 8222:8222 nats http_port 8222 auth admin

Esta instrucción de docker descarga y ejecuta automáticamente el Nats Mirror, el puerto 4222 es el puerto al que el cliente quiere acceder.

Listening for client connections on 0.0.0.0:4222
Server is ready

El servidor nats mirror se pone en marcha y escucha el puerto 4222.

Comunicación entre dispositivos locales y estrategias de disco real

Necesitamos crear dos políticas (en realidad), por el momento llamamos a la política A y a la política B, que son básicamente el mismo código.

  • Estrategia A

    var connPub = null 
    var connSub = null
    
    function main() {
        var robotId = _G()
        Log("当前实盘robotId:", robotId)
    
        connPub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotA")
        if (!connPub) {
            Log("通信失败!")
            return 
        }
    
        connSub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotB")
        if (!connSub) {
            Log("通信失败!")
            return 
        }
    
        while (true) {
            connPub.write("robotA发布的消息,robotId: " + robotId + ", time:" + _D())
            var msgRead = connSub.read(10000)
            if (msgRead) {
                Log("msgRead:", msgRead)
            }
    
            LogStatus(_D())
            Sleep(10000)
        }
    }
    
    function onexit() {
        connPub.close()
        connSub.close()
    }
    
  • Estrategia B

    var connPub = null 
    var connSub = null
    
    function main() {
        var robotId = _G()
        Log("当前实盘robotId:", robotId)
    
        connPub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotB")
        if (!connPub) {
            Log("通信失败!")
            return 
        }
    
        connSub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotA")
        if (!connSub) {
            Log("通信失败!")
            return 
        }
    
        while (true) {
            connPub.write("robotB发布的消息,robotId: " + robotId + ", time:" + _D())
            var msgRead = connSub.read(10000)
            if (msgRead) {
                Log("msgRead:", msgRead)
            }
    
            LogStatus(_D())
            Sleep(10000)
        }
    }
    
    function onexit() {
        connPub.close()
        connSub.close()
    }
    

Las dos estrategias son básicamente las mismas, excepto que las publicaciones, suscripciones, temas de suscripción, temas de publicación y mensajes de publicación son diferentes.

Por ejemplo, la estrategia B:

  • 1, el usoDial()Función para crear objetos de servidor para conectar a un clienteconnPubEn el blog, el blogger de Twitter, que publicaba el mensaje sobre el tema:

    Var connPub = Marca el número127.0.0.1:4222?topic=pubRobotB”)

    La cadena de parámetros de la función Dial, que comienza connats://Esto significa que se utiliza el protocolo nats para la comunicación, y luegoadminEs un mensaje de verificación simple que se establece al implementar el espejo docker.auth admin, con el carácter "@" con el espacio de contenido posterior, y luego la dirección del servicio y el puerto127.0.0.1:4222En la página de Facebook de la red social, se puede leer el siguiente artículo:topic=pubRobotBTenga en cuenta el espacio entre el símbolo "¿y?" y la dirección anterior.

  • 2, usoDial()Función para crear objetos de servidor para conectar a un clienteconnSubEn la página web de Facebook de la empresa, se puede leer:

    Var connSub = Marca el número127.0.0.1:4222?topic=pubRobotA”)

    La diferencia estopic=pubRobotALa estrategia A es enviar mensajes a través de suscripción.pubRobotA

Para la creación y uso de objetos de suscripción, publicación y conexión en la política A, es lo mismo que lo descrito anteriormente.

  • La estrategia A está funcionando.

    img

  • La estrategia B está funcionando.

    img

Así se logra un simple ejemplo de aplicación del protocolo nats para la comunicación entre el disco A y el disco B.


Protocolo amqp

Cuadros de protocolos de amqp

En la comunicación sincronizada, el mensaje no llega inmediatamente al receptor, sino que se almacena en un recipiente, y cuando se cumplen ciertas condiciones, el mensaje es enviado por el recipiente al receptor, este recipiente es la cola de mensajes, y para lograr esta función se requiere que ambas partes y el recipiente y sus componentes cumplan con acuerdos y reglas uniformes.

Cada acuerdo tiene sus propias características y se puede consultar documentación específica, información que no se describe aquí.

Para implementar el servidor del protocolo amqp:

el nombre de host de mi conejo nombre de conejo -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=q -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3-management

Cuando se implementa el espejo de Docker, se descarga automáticamente la implementación y, una vez terminada, se muestra:

2024-08-06 09:02:46.248936+00:00 [info] <0.9.0> Time to start RabbitMQ: 15569 ms

Una vez que la imagen del servidor está bien implementada, escribe un ejemplo de prueba:

var conn = null

function main() {
    LogReset(1)
    var robotId = _G()
    Log("当前实盘robotId:", robotId)

    conn = Dial("amqp://q:admin@127.0.0.1:5672/?queue=robotA_Queue")
    if (!conn) {
        Log("通信失败!")
        return 
    }

    for (var i = 0; i < 10; i++) {
        // 读取
        Log("read:", conn.read(1000), "#FF0000")
        
        // 写入
        var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()        
        conn.write(msg)
        Log("向testQueue写入消息:", msg)

        Sleep(1000)
    }    
}

function onexit() {
    conn.close()
    Log("关闭conn")
}

Es importante tener en cuenta que una cola con el protocolo amqp tiene un mensaje que permanece en la cola después de su publicación, por ejemplo, una vez que ejecutamos el código de ejemplo anterior. Se escriben 10 mensajes a la cola.

img

Se puede ver que en la imagen, las dos mensajes de registro señalados por las flechas rojas no coinciden en el tiempo, ya que el rojo es el mensaje leído que se escribió en la cola cuando se ejecutó el código de la política por primera vez.

Se pueden realizar algunas necesidades basadas en esta característica, por ejemplo: después de reiniciar el disco real de la política, todavía se puede obtener datos de mercado registrados de la cola para operaciones como el cálculo de inicialización.


El acuerdo kafka

Apache Kafka es un almacenamiento de datos distribuido optimizado para extraer y procesar datos de flujo en tiempo real. Los datos de flujo se refieren a datos generados continuamente por miles de fuentes de datos, que generalmente pueden enviarse simultáneamente.

Kafka ofrece a sus usuarios tres funciones principales:

  • Publicación y suscripción de registros
  • Almacenar flujos de registros de manera eficiente en el orden en que se generan los registros
  • Procesamiento de flujo de registros en tiempo real

Kafka se utiliza principalmente para construir canales y aplicaciones de flujo de datos en tiempo real adaptados a los flujos de datos. Combina funciones de transmisión, almacenamiento y procesamiento de flujo para almacenar datos históricos y en tiempo real.

Publicaciones y suscripciones

Un ejemplo es el docker de Kafka:

docker run --rm --name kafka-server --hostname kafka-server -p 9092:9092 -p 9093:9093 \
        -e KAFKA_CFG_NODE_ID=0 \
        -e KAFKA_CFG_PROCESS_ROLES=controller,broker \
        -e KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 \
        -e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 \
        -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT \
        -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-server:9093 \
        -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER \
        bitnami/kafka:latest

La prueba de código de prueba:

var conn = null

function main() {
    LogReset(1)
    var robotId = _G()
    Log("当前实盘robotId:", robotId)

    conn = Dial("kafka://localhost:9092/test_topic")
    if (!conn) {
        Log("通信失败!")
        return 
    }

    for (var i = 0; i < 10; i++) {
        // 写入
        var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()        
        conn.write(msg)
        Log("向testQueue写入消息:", msg)

        // 读取
        Log("read:", conn.read(1000), "#FF0000")

        Sleep(1000)
    }    
}

function onexit() {
    conn.close()
    Log("关闭conn")
}

Veamos cómo publicar y suscribir mensajes con el protocolo kafka en la función Dial.

Dial("kafka://localhost:9092/test_topic")

Como con otros protocolos, comienza con el nombre del protocolo; luego sigue con la dirección de escucha:localhost:9092Luego, usa el símbolo "/" como un intervalo y escribe el tema de suscripción / publicación después, donde el tema de prueba se configura comotest_topic

Los resultados de las pruebas:

img


Más.