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

WebSocket Market をシームレスに利用できるようにする戦略テンプレート

作者: リン・ハーンFMZ~リディア作成日:2024年10月30日 14:23:04 更新日:2024年11月5日 17:44:35 更新日:2024年11月5日 17:44:35 更新日:2024年11月5日 17:44:35

img

これはFMZが公式に開発したWebSocket市場テンプレートです.すべてのユーザーをコピーして使用してください:https://www.fmz.com/strategy/470349

WebSocket はなぜ必要なのか?

現在,FMZ戦略は主に伝統的なREST APIエンカプスレーションに基づいています.APIアクセス各ステップにはネットワーク接続が確立され,市場データは世論調査を通じて得られます.この方法はシンプルで使いやすいもので,ほとんどのニーズに完全に十分です.

しかし,RESTプロトコルは固有の遅延問題を抱えています.複数の取引ペアと複数の取引戦略が必要である場合,遅延問題は拡大されます.プラットフォームのGo機能が同時に実行できるものの,遅延問題は依然として存在しており,比較的高周波の戦略取引のニーズを満たすことは困難です.また,取引ペアがあまりにも多く,投票頻度があまりにも速い場合は,取引プラットフォームのアクセス頻度制限に遭遇します.

現在,取引所のサーバーも重荷を負っている.それらはすべてWebSocketプロトコルを完全提供し,APIユーザーに推奨している.RESTプロトコルと比較して,WebSocketは持続的な双方向接続方法を提供し,交換がクライアントにデータをリアルタイムでプッシュできるようにし,頻繁な要求と応答を避け,遅延を大幅に削減する.一般的に,REST APIにアクセスする遅延が20ms程度である場合,WebSocketを通じてデータをプッシュする遅延は約2msである.また,WebSocketプロトコルのリンクはプラットフォームアクセス周波数によって制限されず,一度に数十の取引ペアに購読することが可能である.

WebSocket ticker テンプレートへの紹介

FMZ Quant Trading プラットフォームは長年 WebSocket プロトコルをサポートしており,呼び出すことは比較的便利ですが,初心者向けには,複数のサブスクリプションを処理し,複数の交換ティッカーに購読し,それらを効率的かつ便利に組み込むことはまだ複雑です. この公開WebSocketのリアルタイムティッカーデータ加速テンプレートは,この問題を解決します.これは非常に使いやすいし,現在のエンカプセル化されたAPIコールと完全に互換性があります.オリジナルのREST戦略のほとんどは,単にそれらを修正して戦略を加速するために直接使用できます.

主要な特徴:

  • 複数の取引所のサポート: この戦略は,Binance,OKX,Bybit,Bitgetなど,複数の取引所の WebSocket 接続をサポートします.ユーザーは,このテンプレートのパッケージング方法をフォローして,より多くの取引所にサポートすることができます.
  • カスタマイズできるサブスクリプション: 特定の市場チャネル (深度,取引など) の購読と,取引戦略の即時利用のために受信されたデータの効率的な処理を可能にします.
  • 先進的なエラー処理: データフローの信頼性と継続性を確保するためのエラー追跡とWebソケット再接続メカニズムが組み込まれています.

実施原則の簡潔な紹介

この戦略は,TypeScript を使用していることに注意してください. JavaScript にだけ馴染みのある方には,少し奇妙に見えるかもしれません.TypeScript は,JavaScript をベースにしたタイプシステムとより豊かな言語機能を導入しています.複雑な論理を処理する必要がある定量取引などのアプリケーションでは,TypeScript を使用することで潜在的なエラーを削減し,コードの読みやすさと維持性を向上させることができます.したがって,簡単に学習することをお勧めします.

さらに,この戦略は FMZ プラットフォームの非同期メカニズムを使用している.子スレッドは __threadPostMessage 関数を通じてメインスレッドにメッセージを送信することができる.この方法は非同期であり,子スレッドで生成されるデータ更新のメインスレッドに通知するのに適している.メインスレッドと子スレッドは __threadGetData と __threadSetData 関数を通じてデータを共有することができる.この方法はスレッドが共有状態にアクセスして修正することを可能にします.プラットフォームドキュメントと組み合わせてマルチスレッドについて学びたい場合は,この戦略も良い学習例です.

この戦略の主な原則は,WebSocketを通じて主流のデジタル通貨取引所に接続し,定量的な取引決定のためのデータサポートを提供するためにリアルタイムで市場データ (深度情報および取引情報など) を受信することです.具体的実施プロセスは以下のとおりです.

1. WebSocket 接続の設定機能についてsetupWebsocketWebソケット接続を初期化し,市場データを受信するために使用されます.main_exchanges,接続する交換を表示します.

  • MyDial 機能: Webソケット接続を作成し,接続時間を記録し,接続を終了する際に終了時間を出力します.
  • updateSymbols 機能: 定期的に新規購読の要請がないか確認し,必要に応じて現在の取引対リストを更新します.

2. データ処理対象についてsupportsサポートされている交換とそれらの処理機能 (例えばBinance) 各交換の処理機能は,受信されたメッセージを解析し,関連するデータを抽出します.

  • processMsg 機能: 交換からのメッセージを処理し,異なる種類のデータ (深度更新,トランザクションなど) を識別し,統一されたイベントオブジェクトにフォーマットします.

3. サブスクリプションデータ各接続で,システムは,現在の取引ペアに基づいて,関連する市場データチャンネルを購読します.

  • getFunction 機能: 交換名に従って対応する処理関数を取得します.
  • this.wssPublic 機能: WebSocket 接続を初期化してデータ受信を開始します.

4. スレッド管理リアルタイムでデータを受信し コールバック機能でデータを処理します

  • threadMarket 機能: 子スレッドでデータを受信し,最新の深さやトランザクション情報を解析し,保存します.

5. データ取得方法を書き直す各取引所の深度情報と取引情報を得る方法を書き直し,リアルタイムで更新されるデータを返信することに優先します.

テンプレートを使用する方法

  1. 初期化: 使用$.setupWebsocket()ターゲット交換の WebSocket 接続を初期化します
  2. サブスクリプション: システムでは,あなたが取引する商品の関連チャンネル (深度,取引など) に自動的に購読します.
  3. データ収集呼び出しによってGetDepth()そしてGetTrades()WebSocketのリアルタイムデータを使用して自動的に返されます.
  4. エラー処理: この戦略には,接続とデータエラーを記録するための追跡メカニズム,接続が切れた場合,自動的に再接続しようとする試みが含まれます.

EventLoop() 機能が戦略に追加された場合,トリガーメカニズムに変更されます.wss データ更新がある場合,自動的にすぐに取得し,最新のデータがない場合は待機します.これはインテリジェント スリープ機能に相当します.もちろん,直接スリープも使用できます.

function main() {
    $.setupWebsocket()
    while (true) {
        exchanges.map(e=>{
            Log(e.GetName(), e.GetDepth())
            Log(e.GetName(), e.GetTrades())
        })
        EventLoop(100) // trigger by websocket
    }
}

私の前のマルチ通貨取引戦略ガイドを参照してください:https://www.fmz.com/bbs-topic/10508, WebSocket をサポートするために簡単に変更できます:

function MakeOrder() {
    for (let i in Info.trade_symbols) {
        let symbol = Info.trade_symbols[i];
        let buy_price = exchange.GetDepth(symbol + '_USDT').Asks[0].Price;
        let buy_amount = 50 / buy_price;
        if (Info.position[symbol].value < 2000){
            Trade(symbol, "buy", buy_price, buy_amount, symbol);
        }
    }
}

function OnTick() {
    try {
        UpdatePosition();
        MakeOrder();
        UpdateStatus();
    } catch (error) {
        Log("loop error: " + error);
    }
}

function main() {
    $.setupWebsocket()
    InitInfo();
    while (true) {
        let loop_start_time = Date.now();
        if (Date.now() - Info.time.last_loop_time > Info.interval * 1000) {
            OnTick();
            Info.time.last_loop_time = Date.now();
            Info.time.loop_delay = Date.now() - loop_start_time;
        }
        Sleep(5);
    }
}

もっと