資源の読み込みに... 荷物...

FMZを調査する: ライブ取引戦略間の通信プロトコルの実践

作者: リン・ハーンFMZ~リディア, 作成: 2024-08-08 10:09:21, 更新: 2024-11-05 17:51:27

[TOC]

img

金融市場の急速な発展と定量取引の普及により,ますます多くのトレーダーは自動化された戦略に依存し始めています.このプロセスでは,戦略間のコミュニケーションと調整が特に重要です. FMZ Quant Trading Platformは,取引戦略間の効率的な通信プロトコルを提供することにより,トレーダーがシームレスな戦略ドッキングとリアルタイムデータ共有を達成するのに役立ちます.

この記事では,FMZプラットフォームにおける取引戦略のライブ取引通信プロトコルを調査し,その設計概念,機能特性,実用的な応用における利点について紹介します.詳細なケース分析を通じて,このプロトコルを効率的で安定した戦略コミュニケーションを達成し,取引戦略の実行と利益パフォーマンスを向上させるためにどのように使用するか示します.

FMZを始めてばかりの定量的な取引の熱心者であろうと,経験豊富なプロのプログラマーであろうと,この記事は貴方に貴重な洞察と実践的な操作ガイドを提供します. FMZプラットフォームの強力な機能を探検し,効率的な通信プロトコルを通じて戦略間の連携を達成し,取引効率を改善し,市場機会を把握する方法について学びましょう.

需要シナリオ

    1. 多戦略協力取引 需要シナリオ: 複雑な市場環境では,単一の戦略はさまざまな緊急事態や市場変化に対処できない可能性があります.トレーダーは,トレンド追跡戦略,平均逆転戦略,仲介戦略などの複数の戦略を同時に実行し,これらの戦略がリアルタイムで通信し,市場情報と取引信号を共有し,それによって全体的な取引効率と安定性を向上させたいと考えています.
    1. 市場間仲介 需要シナリオ: トレーダーは,異なる取引市場間の仲介取引を行いたい.例えば,A株式市場と香港株式市場との間の価格差を使用して仲介を行う.特定の市場で価格異常が発生すると,戦略は,仲介機会を把握するために,他の市場の戦略に迅速に通知し,対応する買取販売操作を行う必要があります.
    1. リスク管理とヘッジ 需要シナリオ: ある戦略は,市場における高リスク・高収益の取引を特定し実行する責任があり,もうひとつの戦略は,全体的なリスクの監視とヘッジ操作を行うことに重点を置いています.高リスクの取引中に過度の損失が発生しないようにするために,これらの2つの戦略は,ポジションを適時調整し,リスクをヘッジするために,リアルタイムでデータを通信し,共有する必要があります.
    1. 分散型取引システム 需要シナリオ: 大規模な取引機関は,取引システムの障害耐性およびパフォーマンスを向上させるために,複数の物理サーバーで分散型取引システムを実行したい.これらのサーバーの戦略は,全体的な取引システムの安定性と効率的な動作を確保するために,通信プロトコルを通じてデータを同期し,操作を調整する必要があります.
    1. 市場監視と早期警告 需要シナリオ: 戦略は,市場の動向をリアルタイムに監視する責任がある.市場で大きな変化 (急激な価格急落または急上昇など) が起こると,戦略はリスクを軽減したり,取引機会を把握するために,ポジションを閉じる,ポジションを調整する,ポジションを追加するなどの対応措置をとるために,他の戦略に迅速に通知する必要があります.
    1. ポートフォリオ戦略管理 需要シナリオ: トレーダーは,さまざまな資産クラスへの投資を管理するために,それぞれの戦略が特定の資産クラス (株,債券,先物など) に焦点を当てた戦略のポートフォリオを使用します.これらの戦略は,ポートフォリオ投資の全体的な最適化と収益の最大化を達成するためにコミュニケーションと調整が必要です.

これらの需要シナリオは,実用的なアプリケーションにおけるFMZ取引戦略のさまざまな可能性と利点を示しています.効果的な戦略間のコミュニケーションを通じて,トレーダーは複雑な市場環境に対処し,取引戦略を最適化し,取引効率と利益を改善することができます.

FMZ 封筒通信プロトコルとダイヤル機能

ライブトレード間の通信要件を理解した後,これらの要件をどのように実装するか検討する必要があります. ライブトレードAは,ライブトレードBと情報を交換することを希望するライブトレード以上のものではありません. 要求事項はシンプルに見えますが,一連の通信プロトコルを使用する際には合意する必要があるさまざまな詳細があります. FMZはいくつかの人気のある通信プロトコルをカプセルしました.

mqtt / nats / amqp / カフカ

コミュニケーションアーキテクチャ

コミュニケーションアーキテクチャは

  • サーバー (プロキシ) 通信プロトコルを実行するサーバーは,サブスクライバーとパブリッシャーの間のメッセージをリレーするために必要である.このサーバーは,dockerのシステム (ローカルライブトレーディング通信のために) にローカルに展開されるか,リモートサービス (クロスサーバーライブトレーディング通信のために) として展開できる.
  • 顧客 (加入者,出版社) FMZの戦略ライブトレーディングプログラムは,通信プロトコルのクライアントとして理解できる.戦略リアルタイムプログラムは,出版社 (pub) またはサブ (sub) であり得る.

ダイヤル機能

このプロトコルを FMZ プラットフォームで適用する際には, mqtt / nats / amqp / kafkap プロトコルがDial()機能,およびDial()この機能は,メッセージの公開および購読に使用されます.これらの公開されたメッセージは,プロトコルサーバーを通じて購読されたライブ取引にプロキシ (リレー) されます.したがって,プロトコルサーバを最初に実行する必要があります.実証のために,以下の例でさまざまなプロトコルサーバーイメージ展開を使用します.

API ドキュメンテーションの部分でダイヤルする機能:https://www.fmz.com/syntax-guide#fun_dial

Docker イメージを展開する前に,まずdocker ソフトウェアをインストールすることを忘れないでください.

img

次に FMZ がサポートする通信プロトコルのアプリケーションを調査し 練習しましょう

FMZ プラットフォーム ライブ トレーディング 通信 プロトコル 実践

mqtt プロトコル

MQTT (Message Queuing Telemetry Transport) は,低帯域幅,高レイテンシー,または信頼性のないネットワーク環境に特に適した軽量なメッセージ伝送プロトコルである.1999年にIBMのアンディ・スタンフォード・クラークとアーレン・ニッパーによって提案され,後にISO標準 (ISO/IEC PRF 20922) になった.

MQTT プロトコルの主な特徴:公開/購読モード

  • 投稿: メッセージのプロデューサーは,メッセージをトピックに送信します.
  • サブスクリプション: メッセージ消費者は,興味のあるトピックにサブスクリプションを行い,そのトピックに掲載されたメッセージを受け取ります.
  • ブロッカー: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.

上記の戦略は,同時にトピックを公開し,サブスクリプションします.実行テストは,図のように示されています:

img

また,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で書かれています.

  • 戦略A
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()
}
  • 戦略B
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を例に挙げましょう

    1. 試しにDial()クライアント接続サーバオブジェクトを作成する機能connPub主題メッセージの公開については:

ワルコンパブ = ダイヤル127.0.0.1:4222?topic=pubRobotB”)

ダイヤル関数のパラメータ文字列は,nats://NATS プロトコルが通信に使用されていることを示す.admin単純な検証情報auth admin設定される.以下のようなコンテンツを分離するために,@文字が使用されます.次に,サービスアドレスとポートがあります.127.0.0.1:4222最後に,公開/購読のトピックがあります.topic=pubRobotB?の記号は,前のアドレスから区分するために使用されていることに注意してください.

    1. 試しにDial()クライアント接続サーバオブジェクトを作成する機能connSub主題メッセージのサブスクリプション:

変数で表示する127.0.0.1:4222?topic=pubRobotA”)

唯一の違いはtopic=pubRobotAテーマにサインする必要があるからですpubRobotA戦略Aが情報を送信します

戦略Aにおける購読および出版接続オブジェクトの作成と使用は,上記と同じである.

  • 戦略Aが実行される

img

  • 戦略Bが実行される

img

この方法で,NATSプロトコルアプリケーションの簡単な例が実装され,ライブ取引Aとライブ取引Bが相互通信するためにメッセージに購読し公開します.

amqp プロトコル

amqp プロトコルキュー

アシンクロン通信では,メッセージはすぐに受信者に届かないが,コンテナに格納される.特定の条件が満たされると,メッセージはコンテナによって受信者に送信される.このコンテナはメッセージキューである.この機能を完了するには,両当事者とコンテナとその構成要素は統一された協定と規則を遵守しなければならない.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のメッセージが書き込まれます.次に実行すると,最初の書き込みメッセージが読み返されると見ることができます.図のように:

img

画面上の赤い矢印が示す 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.

検査結果:

img


もっと