[TOC]
金融市場の急速な発展と定量取引の普及により,ますます多くのトレーダーは自動化された戦略に依存し始めています.このプロセスでは,戦略間のコミュニケーションと調整が特に重要です. FMZ Quant Trading Platformは,取引戦略間の効率的な通信プロトコルを提供することにより,トレーダーがシームレスな戦略ドッキングとリアルタイムデータ共有を達成するのに役立ちます.
この記事では,FMZプラットフォームにおける取引戦略のライブ取引通信プロトコルを調査し,その設計概念,機能特性,実用的な応用における利点について紹介します.詳細なケース分析を通じて,このプロトコルを効率的で安定した戦略コミュニケーションを達成し,取引戦略の実行と利益パフォーマンスを向上させるためにどのように使用するか示します.
FMZを始めてばかりの定量的な取引の熱心者であろうと,経験豊富なプロのプログラマーであろうと,この記事は貴方に貴重な洞察と実践的な操作ガイドを提供します. FMZプラットフォームの強力な機能を探検し,効率的な通信プロトコルを通じて戦略間の連携を達成し,取引効率を改善し,市場機会を把握する方法について学びましょう.
これらの需要シナリオは,実用的なアプリケーションにおけるFMZ取引戦略のさまざまな可能性と利点を示しています.効果的な戦略間のコミュニケーションを通じて,トレーダーは複雑な市場環境に対処し,取引戦略を最適化し,取引効率と利益を改善することができます.
ライブトレード間の通信要件を理解した後,これらの要件をどのように実装するか検討する必要があります. ライブトレードAは,ライブトレードBと情報を交換することを希望するライブトレード以上のものではありません. 要求事項はシンプルに見えますが,一連の通信プロトコルを使用する際には合意する必要があるさまざまな詳細があります. FMZはいくつかの人気のある通信プロトコルをカプセルしました.
mqtt / nats / amqp / カフカ
コミュニケーションアーキテクチャは
このプロトコルを FMZ プラットフォームで適用する際には, mqtt / nats / amqp / kafkap プロトコルがDial()
機能,およびDial()
この機能は,メッセージの公開および購読に使用されます.これらの公開されたメッセージは,プロトコルサーバーを通じて購読されたライブ取引にプロキシ (リレー) されます.したがって,プロトコルサーバを最初に実行する必要があります.実証のために,以下の例でさまざまなプロトコルサーバーイメージ展開を使用します.
API ドキュメンテーションの部分でダイヤルする機能:https://www.fmz.com/syntax-guide#fun_dial
Docker イメージを展開する前に,まずdocker ソフトウェアをインストールすることを忘れないでください.
次に FMZ がサポートする通信プロトコルのアプリケーションを調査し 練習しましょう
MQTT (Message Queuing Telemetry Transport) は,低帯域幅,高レイテンシー,または信頼性のないネットワーク環境に特に適した軽量なメッセージ伝送プロトコルである.1999年にIBMのアンディ・スタンフォード・クラークとアーレン・ニッパーによって提案され,後にISO標準 (ISO/IEC PRF 20922) になった.
MQTT プロトコルの主な特徴:公開/購読モード
MQTT プロキシサーバーを展開するために,MQTT プロトコルをサポートするソフトウェアのdocker イメージ (eclipse-mosquitto イメージ) を使用しているため,私たちは先行でdockerをインストールしており,詳細については後ほど述べません.
プロキシサーバーの設定ファイルを書く必要があります. プロキシサーバーの設定ファイルは,プロキシサーバーの設定ファイルです.mosquitto.conf
.
# Configure port number and remote access IP
listener 1883 0.0.0.0
# Setting up anonymous access
allow_anonymous true
実行します.
docker run --rm -p 1883:1883 -v ./mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
プロキシサーバーの画像が実行されると,次のものが表示されます.
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
戦略をテストして 実践することができます
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")
}
戦略コードにおけるダイヤル機能の主な用途は:
Dial("mqtt://127.0.0.1:1883?topic=test_topic")
ダイヤル関数の文字列パラメータは,mqtt://
, これはプロトコルの名前であり,その後にリスニングアドレスとポートが続く. 記号test_topic
.
上記の戦略は,同時にトピックを公開し,サブスクリプションします.実行テストは,図のように示されています:
また,2つのライブトレードを使用して,互いにサブスクリプションを行い,トピック情報を公開することもできます.この例を nats プロトコル練習セクションで使用し,他のプロトコルではこの方法を繰り返しません.
NATSプロトコルは,シンプルでテキストベースの公開/サブスクリプションスタイルプロトコルである.クライアントはgnatsd (NATSサーバー) に接続し,gnatsdと通信する.通信は通常のTCP/IPソケットに基づいており,非常に小さな一連の操作を定義する.Newlineは終了を表示する.二進法メッセージ形式を使用する伝統的なメッセージ通信システムとは異なり,テキストベースのNATSプロトコルはクライアント実装を非常に簡単にしており,さまざまなプログラミング言語またはスクリプト言語で簡単に実装することができます.
各議定書には独自の特徴があります. ここでは詳細に説明しませんが,具体的な文書や資料を参照してください.
NATS プロトコル サーバを展開する:
ドッカーラン
名前ナッツ rm -p 4222:4222 -p 8222:8222 ナッツ http_port 8222 auth admin
このドッカーコマンドは nats イメージを自動的にダウンロードして実行し,ポート 4222 はクライアントがアクセスする必要があるポートです. イメージが展開された後,ポート 8222 で http モニターも開きます.
Listening for client connections on 0.0.0.0:4222
Server is ready
NATSサーバーの画像が起動 4222ポートで聴いてる
この2つの戦略のコードは基本的には同じです.それらは,FMZプラットフォーム上で最も使いやすい言語であるJavascriptで書かれています.
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()
}
この2つの戦略は ほぼ同じですが, 互いを公開し, サブスクリプションをすることと, サブスクリプションされたトピック, 公開されたトピック, 公開された情報とは異なります.
戦略Bを例に挙げましょう
Dial()
クライアント接続サーバオブジェクトを作成する機能connPub
主題メッセージの公開については:ワルコンパブ = ダイヤル127.0.0.1:4222?topic=pubRobotB”)
ダイヤル関数のパラメータ文字列は,nats://
NATS プロトコルが通信に使用されていることを示す.admin
単純な検証情報auth admin
設定される.以下のようなコンテンツを分離するために,127.0.0.1:4222
最後に,公開/購読のトピックがあります.topic=pubRobotB
Dial()
クライアント接続サーバオブジェクトを作成する機能connSub
主題メッセージのサブスクリプション:変数で表示する127.0.0.1:4222?topic=pubRobotA”)
唯一の違いはtopic=pubRobotA
テーマにサインする必要があるからですpubRobotA
戦略Aが情報を送信します
戦略Aにおける購読および出版接続オブジェクトの作成と使用は,上記と同じである.
この方法で,NATSプロトコルアプリケーションの簡単な例が実装され,ライブ取引Aとライブ取引Bが相互通信するためにメッセージに購読し公開します.
アシンクロン通信では,メッセージはすぐに受信者に届かないが,コンテナに格納される.特定の条件が満たされると,メッセージはコンテナによって受信者に送信される.このコンテナはメッセージキューである.この機能を完了するには,両当事者とコンテナとその構成要素は統一された協定と規則を遵守しなければならない.AMQPはそのようなプロトコルである.メッセージの送信者と受信者は両方がこのプロトコルに従うことでアシンクロン通信を実装することができます.このプロトコルはメッセージのフォーマットと作業方法を規定します.
各議定書には独自の特徴があります. ここでは詳細に説明しませんが,具体的な文書や資料を参照してください.
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-管理
ドッカー画像を展開するときに,自動的にダウンロードして展開し,完了すると,以下のように表示されます.
2024-08-06 09:02:46.248936+00:00 [info] <0.9.0> Time to start RabbitMQ: 15569 ms
サーバの画像が展開された後,テスト例を書きます.
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")
}
AMQP プロトコルキューを使用するときは,公開されたメッセージがキューに持続することを注意してください.例えば,上記の例コードを実行すると,キューに10のメッセージが書き込まれます.次に実行すると,最初の書き込みメッセージが読み返されると見ることができます.図のように:
画面上の赤い矢印が示す 2 つのログメッセージの時間は一致していないことがわかります. 理由は,戦略コードが最初に実行されたときに,赤いメッセージがキューに読み書きされたものです.
この特徴に基づいて,いくつかの要件を満たすことができます.例えば,戦略を再起動した後,記録された市場データは,初期化計算および他の操作のためのキューから取得できます.
Apache Kafkaは,リアルタイムでストリーミングデータを吸収し処理するために最適化された分散型データストアである.ストリーミングデータは,何千ものデータソースによって継続的に生成され,しばしば同時にデータレコードを送信されるデータである.ストリーミングプラットフォームは,この継続的なデータ流を処理し,順序的におよび漸進的に処理する必要があります.
カフカはユーザーに3つの主要機能を提供する.
カフカは,主にデータストリームに適応するリアルタイムストリーミングデータパイプラインとアプリケーションを構築するために使用されます.メッセージング,ストレージ,ストリーム処理機能を組み合わせ,歴史的データとリアルタイムデータを保存することができます.
カフカプロキシのドッカー画像を展開する:
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
テストコードを用いた試験:
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")
}
カフカプロトコルを Dial 機能のメッセージの公開とサブスクリプションに使用する方法を見てみましょう.
Dial("kafka://localhost:9092/test_topic")
他のプロトコルのように,最初の部分はプロトコルの名前です.次に聞くアドレスが続きます:localhost:9092
. 次に,分隔符として記号 test_topic
.
検査結果: