[TOC]
Dengan perkembangan pesat pasaran kewangan dan populariti dagangan kuantitatif, semakin ramai peniaga mula bergantung kepada strategi automatik untuk berdagang. Dalam proses ini, komunikasi dan penyelarasan antara strategi menjadi sangat penting. FMZ (Quantitative Trading Platform) membantu peniaga mencapai pairing lancar strategi dan perkongsian data masa nyata dengan menyediakan protokol komunikasi antara piringan strategi dagangan yang cekap.
Artikel ini akan mengkaji secara mendalam protokol komunikasi antara rakit sebenar strategi dagangan dalam platform FMZ, memperkenalkan konsep reka bentuk, ciri-ciri fungsi dan kelebihan dalam aplikasi sebenar. Kami akan menunjukkan melalui analisis kes terperinci bagaimana menggunakan protokol ini untuk mencapai komunikasi strategi yang cekap dan stabil, meningkatkan pelaksanaan dan prestasi pendapatan strategi dagangan.
Sama ada anda seorang peminat perdagangan kuantitatif FMZ yang baru atau seorang pengaturcara profesional yang berpengalaman, artikel ini akan memberikan anda wawasan yang berharga dan panduan operasi yang praktikal. Mari bersama-sama meneroka ciri-ciri FMZ yang kuat dan belajar bagaimana untuk mencapai kerjasama sinkronisasi antara strategi melalui protokol komunikasi yang cekap, meningkatkan kecekapan dagangan, dan menangkap peluang pasaran.
Skenario permintaan ini menunjukkan pelbagai kemungkinan dan kelebihan protokol komunikasi antara piringan dalam aplikasi sebenar. Dengan komunikasi antara piringan strategi yang berkesan, peniaga dapat menangani persekitaran pasaran yang kompleks, mengoptimumkan strategi dagangan, meningkatkan kecekapan dagangan dan keuntungan.
Setelah memahami keperluan komunikasi antara cakera sebenar, adalah untuk mempertimbangkan bagaimana untuk mencapai keperluan tersebut. Tidak ada yang lain daripada cakera sebenar A yang ingin berinteraksi dengan maklumat cakera sebenar B, walaupun keperluan itu kelihatan mudah. Tetapi terdapat pelbagai butiran yang memerlukan perjanjian untuk menggunakan satu set protokol komunikasi, FMZ telah membungkus beberapa protokol komunikasi yang lebih popular.
mqtt / nats / amqp / kafka
Struktur komunikasi ialah:
Apabila digunakan pada platform FMZ, protokol ini boleh difahami dengan mudah sebagai mqtt / nats / amqp / kafka.Dial()
Dalam fungsi, gunakanDial()
Fungsi melakukan penghantaran mesej, langganan, dan lain-lain. Mesej yang dihantar melalui ejen (relay) pihak berkhidmat protokol ke cakera keras pelanggan, jadi anda perlu mula menjalankan satu pihak berkhidmat protokol. Untuk kemudahan demonstrasi, dalam contoh berikut, kita menggunakan pelbagai penerapan cermin pihak berkhidmat protokol.
Bahagian dokumen API di mana fungsi dial berada:https://www.fmz.com/syntax-guide#fun_dial
Sebelum anda menggunakan Docker Mirror, pastikan anda memasang perisian Docker terlebih dahulu.
Mari kita bersama-sama meneroka dan mengamalkan aplikasi protokol komunikasi yang disokong oleh FMZ.
MQTT (Message Queuing Telemetry Transport) adalah protokol penghantaran mesej ringan, terutamanya untuk persekitaran rangkaian yang mempunyai bandwidth rendah, kelewatan tinggi, atau tidak boleh dipercayai. Ia dicadangkan oleh Andy Stanford-Clark dan Arlen Nipper dari IBM pada tahun 1999 dan kemudiannya menjadi piawaian ISO (ISO/IEC PRF 20922).
Ciri-ciri utama protokol MQTT: Model penerbitan / langganan
Oleh kerana kami menggunakan perisian yang menyokong protokol MQTT untuk melancarkan pelayan proxy MQTT (eclipse-mosquitto mirror), kami memasang docker terlebih dahulu dan tidak membincangkannya.
Sebelum menjalankan arahan untuk menggunakan cermin, kita perlu menulis profil pelayan ejen.mosquitto.conf
。
# 配置端口号及远程访问IP
listener 1883 0.0.0.0
# 设置匿名访问
allow_anonymous true
Kemudian, pelaksanaan perintah peluncuran:
docker run --rm -p 1883:1883 -v ./mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
Gambar pelayan proksi yang muncul selepas ia berjalan menunjukkan:
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
Kemudian kita boleh menguji strategi, dan berlatih.
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")
}
Dalam kod strategi, fungsi Dial digunakan terutamanya:
Dial("mqtt://127.0.0.1:1883?topic=test_topic")
Dial mempunyai parameter baris yang bermula denganmqtt://
Nama subjek adalah nama protokol, diikuti dengan alamat pemantauan, port, tanda "?" dan kemudian nama subjek langganan / penerbitan, di mana subjek ujian dipanggil:test_topic
。
Kaedah-kaedah di atas adalah sebagai berikut:
Anda juga boleh menggunakan dua rak maya untuk saling melanggan, menyiarkan maklumat topik, contoh seperti yang kita gunakan dalam seksyen amalan protokol nats, yang tidak lagi diceritakan dalam protokol lain.
Protokol NATS adalah protokol yang mudah, bergaya penerbitan / langganan berasaskan teks. Pelanggan disambungkan ke gnatsd (NATS server) dan berkomunikasi dengan gnatsd, komunikasi berdasarkan kata laluan TCP / IP biasa, dan menentukan set operasi yang sangat kecil, menukar baris menunjukkan pengakhiran. Berbeza dengan sistem komunikasi mesej tradisional, yang menggunakan format mesej binari, protokol NATS berasaskan teks digunakan, yang memudahkan pelaksanaan pelanggan, dengan mudah memilih pelbagai bahasa pengaturcaraan atau bahasa skrip untuk dilaksanakan.
Setiap perjanjian mempunyai ciri tersendiri, dan dokumen dan maklumat tertentu boleh dilihat, tetapi tidak diulas di sini.
Menghantar perkhidmatan protokol nats:
Docker run
name nats rm -p 4222:4222 -p 8222:8222 nats http_port 8222 auth admin
Perintah docker ini akan memuat turun dan menjalankan gambar nats secara automatik. Port 4222 adalah port yang akan diakses oleh pelanggan.
Listening for client connections on 0.0.0.0:4222
Server is ready
Nats Server Mirror mula beroperasi, memantau port 4222.
Kami perlu membuat dua dasar (disk sebenar) untuk sementara, namakan dasar A dan dasar B, kedua-dua dasar ini adalah kod yang sama; ditulis menggunakan bahasa Javascript yang paling mudah digunakan di FMZ.
Strategi 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()
}
Strategi 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()
}
Kedua-dua strategi ini pada dasarnya sama, tetapi mereka berbeza mengenai penyebaran, langganan, topik langganan, topik penyebaran, maklumat penyebaran.
Sebagai contoh, strategi B:
1, kegunaanDial()
Fungsi mencipta objek pelayan yang disambungkan ke pelangganconnPub
Di bawah ini adalah beberapa maklumat mengenai berita utama:
var connPub = Panggil127.0.0.1:4222?topic=pubRobotB”)
String parameter fungsi dial, bermula dengannats://
Ini menunjukkan bahawa komunikasi menggunakan protokol Nats, dan kemudianadmin
adalah mesej semak sederhana yang ditetapkan semasa anda menggunakan cermin dockerauth admin
, menggunakan karakter "@127.0.0.1:4222
Dan akhirnya, tema penerbitan / langganan:topic=pubRobotB
Perhatikan bahawa jarak antara alamat di atas dan alamat di bawah adalah dengan tanda "Y".
2, kegunaanDial()
Fungsi mencipta objek pelayan yang disambungkan ke pelangganconnSub
Di bawah ini adalah senarai berita yang boleh anda rujuk:
var connSub = Panggil127.0.0.1:4222?topic=pubRobotA”)
Perbezaan hanyatopic=pubRobotA
Ini adalah kerana anda memerlukan langganan untuk menghantar mesej.pubRobotA
。
Untuk membuat dan menggunakan objek sambungan langganan, penerbitan dalam Dasar A adalah sama seperti yang dijelaskan di atas.
Strategi A berjalan
Strategi B berjalan
Ini mewujudkan satu contoh penggunaan protokol nats yang mudah di mana cakera A dan cakera B saling melanggan, menghantar mesej dan berkomunikasi.
Dalam komunikasi tidak serentak, mesej tidak segera sampai kepada penerima, tetapi disimpan ke dalam sebuah bekas, apabila syarat tertentu dipenuhi, mesej akan dihantar oleh bekas kepada penerima, bekas ini adalah barisan mesej, dan untuk mencapai fungsi ini memerlukan kedua-dua pihak dan bekas dan komponen-komponennya mematuhi perjanjian dan peraturan yang seragam, AMQP adalah satu protokol seperti itu, mesej yang dihantar dan menerima kedua-dua pihak mematuhi protokol ini untuk mencapai komunikasi tidak serentak. Protokol ini menyetujui format dan cara kerja mesej.
Setiap perjanjian mempunyai ciri tersendiri, dan dokumen dan maklumat tertentu boleh dilihat, tetapi tidak diulas di sini.
Menghantar amqp protokol server:
docker run
rm hostname my-rabbit name rabbit -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=q -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3-management
Apabila anda menggunakan Docker Mirror, aplikasi akan dimuat turun secara automatik, dan apabila selesai, anda akan melihat:
2024-08-06 09:02:46.248936+00:00 [info] <0.9.0> Time to start RabbitMQ: 15569 ms
Apabila imej terminal telah digunakan dengan baik, anda boleh menulis contoh ujian:
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")
}
Perhatikan bahawa pada waktu yang sama, mesej yang dikeluarkan akan kekal dalam antrean, contohnya, kita akan menjalankan satu contoh kod di atas. Kami akan menulis 10 mesej ke antrean. Kemudian, ketika kita menjalankan kedua kali, kita akan membaca semula mesej yang pertama kali ditulis.
Anda dapat melihat dua mesej log yang diarahkan oleh anak panah merah dalam skrin, tetapi masa tidak sama, kerana warna merah adalah mesej yang dibaca dan ditulis pada waktu pertama kod dasar dijalankan.
Beberapa keperluan boleh dicapai berdasarkan ciri ini, contohnya: selepas disket dasar dihidupkan semula, data pasaran yang telah dicatatkan masih boleh diperoleh dari antrian untuk operasi seperti pengiraan inisialisasi.
Apache Kafka adalah penyimpanan data terdistribusi yang dioptimumkan untuk mengekstrak dan memproses data aliran secara real-time. Data aliran merujuk kepada data yang dihasilkan secara berterusan oleh ribuan sumber data, yang biasanya boleh dihantar secara serentak. Platform aliran memerlukan pemprosesan aliran data yang berterusan ini, yang diproses secara beransur-ansur.
Kafka menawarkan tiga fungsi utama kepada pengguna:
Kafka digunakan untuk membina saluran dan aplikasi aliran data masa nyata yang sesuai dengan aliran data. Ia menggabungkan fungsi penghantaran, penyimpanan dan proses aliran untuk menyimpan data sejarah dan masa nyata.
Gambar Docker yang digunakan oleh pro 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
Percubaan menggunakan kod ujian:
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")
}
Mari kita lihat bagaimana untuk menghantar dan melanggan mesej menggunakan protokol Kafka dalam fungsi Dial.
Dial("kafka://localhost:9092/test_topic")
Seperti beberapa protokol lain, bahagian pertama adalah nama protokol; kemudian ikuti alamat pengawasan:localhost:9092
Kemudian gunakan simbol "/" sebagai selang, kemudian tulis tema langganan / penerbitan, di mana tema ujian ditetapkan sebagaitest_topic
。
Hasil ujian: