[TOC]
Dengan pesatnya perkembangan pasar keuangan dan popularitas perdagangan kuantitatif, semakin banyak trader yang mulai mengandalkan strategi otomatis untuk trading. Dalam proses ini, komunikasi dan koordinasi antara strategi sangat penting.
Artikel ini akan mengeksplorasi protokol komunikasi perdagangan langsung strategi perdagangan di platform FMZ, memperkenalkan konsep desain, fitur fungsional dan keuntungannya dalam aplikasi praktis. Melalui analisis kasus yang rinci, kami akan menunjukkan cara menggunakan protokol ini untuk mencapai komunikasi strategi yang efisien dan stabil dan meningkatkan pelaksanaan dan kinerja keuntungan strategi perdagangan.
Apakah Anda seorang penggemar perdagangan kuantitatif yang baru memulai dengan FMZ atau seorang programmer profesional yang berpengalaman, artikel ini akan memberi Anda wawasan berharga dan panduan operasi praktis. Mari kita jelajahi fungsi kuat platform FMZ dan belajar bagaimana mencapai kolaborasi antara strategi melalui protokol komunikasi yang efisien, meningkatkan efisiensi perdagangan, dan menangkap peluang pasar.
Skenario permintaan ini menunjukkan berbagai kemungkinan dan keuntungan dari protokol komunikasi perdagangan langsung strategi perdagangan FMZ dalam aplikasi praktis. Melalui komunikasi antar strategi yang efektif, pedagang dapat lebih baik mengatasi lingkungan pasar yang kompleks, mengoptimalkan strategi perdagangan, dan meningkatkan efisiensi perdagangan dan keuntungan.
Setelah memahami persyaratan komunikasi antara perdagangan langsung, kita perlu mempertimbangkan bagaimana menerapkan persyaratan ini. Ini tidak lebih dari perdagangan langsung A berharap untuk bertukar informasi dengan perdagangan langsung B. Meskipun persyaratan tampaknya sederhana, ada berbagai detail yang perlu disepakati pada menggunakan seperangkat protokol komunikasi. FMZ telah merangkum beberapa protokol komunikasi populer.
mqtt / nats / amqp / kafka
Arsitektur komunikasi adalah:
Ketika menerapkan protokol-protokol ini pada platform FMZ, mudah dipahami bahwa mqtt / nats / amqp / kafkaprotokol terintegrasi ke dalamDial()
fungsi, danDial()
fungsi ini digunakan untuk mempublikasikan dan berlangganan pesan. Pesan yang dipublikasikan ini diproksi (dikirim kembali) ke perdagangan langsung yang terdaftar melalui server protokol, sehingga server protokol harus dijalankan terlebih dahulu. demi demonstrasi, kita menggunakan berbagai penyebaran gambar server protokol dalam contoh berikut.
Fungsi dial di bagian dokumentasi API:https://www.fmz.com/syntax-guide#fun_dial
Sebelum menyebarkan gambar docker, ingat untuk menginstal perangkat lunak docker terlebih dahulu.
Selanjutnya, mari kita mengeksplorasi dan berlatih aplikasi protokol komunikasi yang didukung oleh FMZ.
MQTT (Message Queuing Telemetry Transport) adalah protokol transmisi pesan ringan yang sangat cocok untuk lingkungan jaringan dengan bandwidth rendah, latensi tinggi atau tidak dapat diandalkan.
Fitur utama dari protokol MQTT: publish/subscribe mode
Karena kami menggunakan gambar docker (gambar gergaji gergaji) dari perangkat lunak yang mendukung protokol MQTT untuk menyebarkan server proxy MQTT, kami telah menginstal docker sebelumnya dan tidak akan membahas detailnya nanti.
Sebelum menjalankan perintah untuk menyebarkan gambar, kita perlu menulis file konfigurasi server proxymosquitto.conf
.
# Configure port number and remote access IP
listener 1883 0.0.0.0
# Setting up anonymous access
allow_anonymous true
Kemudian eksekusi perintah deployment:
docker run --rm -p 1883:1883 -v ./mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
Setelah gambar server proxy berjalan, berikut ditampilkan:
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 bisa menguji strategi untuk menerapkannya.
var conn = null
function main() {
LogReset(1)
var robotId = _G()
Log("Current live trading robotId:", robotId)
conn = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
if (!conn) {
Log("Communication failure!")
return
}
for (var i = 0; i < 10; i++) {
// Write
var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()
conn.write(msg)
Log("Write a message to testQueue:", msg)
// Read
Log("read:", conn.read(1000), "#FF0000")
Sleep(1000)
}
}
function onexit() {
conn.close()
Log("close conn")
}
Penggunaan utama fungsi Dial dalam kode strategi adalah:
Dial("mqtt://127.0.0.1:1883?topic=test_topic")
Parameter string dari fungsi Dial dimulai denganmqtt://
, yang merupakan nama protokol, diikuti oleh alamat mendengarkan dan port. simbol test_topic
.
Strategi di atas menerbitkan dan berlangganan topik pada saat yang sama.
Kami juga dapat menggunakan dua perdagangan langsung untuk berlangganan satu sama lain dan mempublikasikan informasi topik. Kami menggunakan contoh seperti itu di bagian praktek protokol nats, dan tidak akan mengulangi metode ini dalam protokol lain.
Protokol NATS adalah protokol publish/subscribe gaya berbasis teks yang sederhana. Klien terhubung ke gnatsd (server NATS) dan berkomunikasi dengan gnatsd. Komunikasi didasarkan pada soket TCP/IP biasa dan mendefinisikan satu set operasi yang sangat kecil. Newline menunjukkan terminasi. Tidak seperti sistem komunikasi pesan tradisional yang menggunakan format pesan biner, protokol NATS berbasis teks membuat implementasi klien sangat sederhana dan dapat dengan mudah diimplementasikan dalam berbagai bahasa pemrograman atau bahasa skrip.
Setiap protokol memiliki karakteristiknya sendiri. Anda dapat merujuk pada dokumen dan materi khusus, yang tidak akan diuraikan di sini.
Mengerahkan server protokol NATS:
Docker run
name nats rm -p 4222:4222 -p 8222:8222 nats http_port 8222 auth admin
Perintah docker ini akan secara otomatis mengunduh dan menjalankan gambar nats, dan port 4222 adalah port yang perlu diakses klien. Setelah gambar digunakan, monitor http juga akan dibuka di port 8222.
Listening for client connections on 0.0.0.0:4222
Server is ready
Gambar server Nats mulai berjalan, mendengarkan di port 4222.
Kita perlu membuat dua strategi (live trading), mari kita sebut mereka Strategi A dan Strategi B. Kode dari kedua strategi ini pada dasarnya sama.
var connPub = null
var connSub = null
function main() {
var robotId = _G()
Log("Current live trading robotId:", robotId)
connPub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotA")
if (!connPub) {
Log("Communication failure!")
return
}
connSub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotB")
if (!connSub) {
Log("Communication failure!")
return
}
while (true) {
connPub.write("Message posted by 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()
}
var connPub = null
var connSub = null
function main() {
var robotId = _G()
Log("Current live trading robotId:", robotId)
connPub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotB")
if (!connPub) {
Log("Communication failure!")
return
}
connSub = Dial("nats://admin@127.0.0.1:4222?topic=pubRobotA")
if (!connSub) {
Log("Communication failure!")
return
}
while (true) {
connPub.write("Message posted by 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 strategi ini hampir sama, kecuali bahwa mereka mempublikasikan dan berlangganan satu sama lain, dan topik yang berlangganan, topik yang diterbitkan, dan informasi yang diterbitkan berbeda.
Ambil Strategi B sebagai contoh:
Dial()
fungsi untuk membuat objek server koneksi klienconnPub
untuk penerbitan pesan topik:Var connPub = Digit127.0.0.1:4222?topic=pubRobotB”)
Senar parameter dari fungsi Dial dimulai dengannats://
menunjukkan bahwa protokol NATS digunakan untuk komunikasi.admin
adalah informasi verifikasi sederhanaauth admin
karakter 127.0.0.1:4222
Akhirnya, ada topik publish/subscribe:topic=pubRobotB
Perhatikan bahwa simbol
Dial()
fungsi untuk membuat objek server koneksi klienconnSub
untuk langganan pesan topik:var connSub = Digit127.0.0.1:4222?topic=pubRobotA”)
Satu-satunya perbedaan adalahtopic=pubRobotA
, karena kita perlu berlangganan topikpubRobotA
di mana strategi A mengirim informasi.
Penciptaan dan penggunaan objek koneksi langganan dan penerbitan dalam strategi A adalah sama dengan yang dijelaskan di atas.
Dengan cara ini, contoh sederhana dari aplikasi protokol NATS diimplementasikan di mana live trading A dan live trading B berlangganan dan mempublikasikan pesan untuk berkomunikasi satu sama lain.
Dalam komunikasi asinkron, pesan tidak akan segera mencapai penerima, tetapi akan disimpan di sebuah kontainer. Ketika kondisi tertentu terpenuhi, pesan akan dikirim ke penerima oleh kontainer. Kontainer ini adalah antrian pesan. Untuk menyelesaikan fungsi ini, kedua pihak dan kontainer dan komponen-komponennya harus mematuhi perjanjian dan aturan yang seragam. AMQP adalah protokol seperti itu. Baik pengirim dan penerima pesan dapat menerapkan komunikasi asinkron dengan mematuhi protokol ini. Protokol ini menetapkan format dan metode kerja pesan.
Setiap protokol memiliki karakteristiknya sendiri. Anda dapat merujuk pada dokumen dan materi khusus, yang tidak akan diuraikan di sini.
Mengerahkan server protokol amqp:
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
Ketika menyebarkan gambar docker, akan mengunduh dan menyebarkan secara otomatis, dan ketika selesai akan menampilkan:
2024-08-06 09:02:46.248936+00:00 [info] <0.9.0> Time to start RabbitMQ: 15569 ms
Setelah gambar server digunakan, tulis contoh uji:
var conn = null
function main() {
LogReset(1)
var robotId = _G()
Log("Current live trading robotId:", robotId)
conn = Dial("amqp://q:admin@127.0.0.1:5672/?queue=robotA_Queue")
if (!conn) {
Log("Communication failure!")
return
}
for (var i = 0; i < 10; i++) {
// Read
Log("read:", conn.read(1000), "#FF0000")
// Write
var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()
conn.write(msg)
Log("Write a message to testQueue:", msg)
Sleep(1000)
}
}
function onexit() {
conn.close()
Log("close conn")
}
Ketika menggunakan antrian protokol AMQP, harap perhatikan bahwa pesan yang diterbitkan akan tetap ada di antrian. Misalnya, jika kita menjalankan kode contoh di atas, 10 pesan akan ditulis ke antrian. Kemudian ketika kita menjalankannya untuk kedua kalinya, kita dapat menemukan bahwa pesan tertulis pertama akan dibaca lagi saat dibaca. Seperti yang ditunjukkan dalam gambar:
Kita dapat melihat bahwa dua pesan log yang ditunjuk oleh panah merah dalam tangkapan layar memiliki waktu yang tidak konsisten. alasannya adalah bahwa pesan merah adalah yang dibaca dan ditulis ke antrian ketika kode strategi pertama kali dijalankan.
Berdasarkan fitur ini, beberapa persyaratan dapat dipenuhi. misalnya, setelah strategi dimulai kembali, data pasar yang tercatat masih dapat diperoleh dari antrian untuk perhitungan inisialisasi dan operasi lainnya.
Apache Kafka adalah penyimpanan data terdistribusi yang dioptimalkan untuk mengonsumsi dan memproses data streaming secara real time. Data streaming adalah data yang terus-menerus dihasilkan oleh ribuan sumber data, sering mengirim catatan data secara bersamaan.
Kafka menyediakan tiga fungsi utama bagi penggunanya:
Kafka terutama digunakan untuk membangun pipa data streaming real-time dan aplikasi yang beradaptasi dengan aliran data.
Mengerahkan gambar docker dari proxy 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
Uji menggunakan kode uji:
var conn = null
function main() {
LogReset(1)
var robotId = _G()
Log("Current live trading robotId:", robotId)
conn = Dial("kafka://localhost:9092/test_topic")
if (!conn) {
Log("Communication failure!")
return
}
for (var i = 0; i < 10; i++) {
// Write
var msg = "i: " + i + ", testQueue, robotA, robotId: " + robotId + ", time:" + _D()
conn.write(msg)
Log("Write a message to testQueue:", msg)
// Read
Log("read:", conn.read(1000), "#FF0000")
Sleep(1000)
}
}
function onexit() {
conn.close()
Log("close conn")
}
Mari kita lihat bagaimana menggunakan protokol Kafka untuk mempublikasikan dan berlangganan pesan dalam fungsi Dial.
Dial("kafka://localhost:9092/test_topic")
Seperti protokol lainnya, bagian pertama adalah nama protokol. Kemudian diikuti oleh alamat mendengarkan:localhost:9092
. Kemudian gunakan simbol test_topic
.
Hasil tes: