[TOC] ¿Qué quieres decir?
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.
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.
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
La arquitectura de comunicación es:
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.
A continuación, vamos a explorar y practicar las aplicaciones de protocolo de comunicación que FMZ apoya.
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
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:
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 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.
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 clienteconnPub
En 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 luegoadmin
Es un mensaje de verificación simple que se establece al implementar el espejo docker.auth admin
, con el carácter "@127.0.0.1:4222
En la página de Facebook de la red social, se puede leer el siguiente artículo:topic=pubRobotB
Tenga 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 clienteconnSub
En 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=pubRobotA
La 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.
La estrategia B está funcionando.
Así se logra un simple ejemplo de aplicación del protocolo nats para la comunicación entre el disco A y el disco B.
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.
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.
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:
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.
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:9092
Luego, 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: