avatar of 发明者量化-小小梦 发明者量化-小小梦
フォロー ダイレクトメッセージ
4
フォロー
1271
フォロワー

FMZ 定量化: 暗号通貨市場における一般的な需要設計例の分析 (パート 2)

作成日:: 2023-12-24 22:24:58, 更新日:: 2023-12-25 17:10:56
comments   1
hits   1511

FMZ 定量化: 暗号通貨市場における一般的な需要設計例の分析 (パート 2)

前回の記事で読者からいただいたコメントに応えて、契約アカウントの振替を監視するプログラム例が必要になりました。今回は、この要件を満たすために Binance Exchange をテスト対象として使用し、その設計方法を学びます。

暗号通貨取引所では、異なるウォレット間での資産の転送など、毎日大量の取引を処理しています。これらの転送をリアルタイムで監視することは、トレーダーや開発者にとって非常に重要です。この記事では、暗号通貨取引所での最近の資産転送を監視するために設計された JavaScript コードの一部を説明し、その主要なコンポーネントについて説明します。

要件を分析する

Binance Exchange のドキュメントを調べたところ、すべての転送情報を照会できる転送履歴インターフェースがあることがわかりました。可能性のある転送記録のみを監視しているため、すべての転送履歴を取得する必要はありません。特定の範囲内で、特定の頻度で最近の転送記録を確認するだけで済みます。新しい転送記録が見つかった場合は、更新され、通知されます。

次のインターフェースを使用します:

// GET /sapi/v1/asset/transfer type, size : 100

では、新しく追加された転送記録をどのように確認するのでしょうか? Binanceのドキュメントを読んだ後、このインターフェースによって返されるデータにはタイムスタンプが含まれていることがわかりました。タイムスタンプを使用して判断するのは非常に簡単です。現在のレコードよりも大きいタイムスタンプを持つレコードがある限り、新しい転送があることを意味します。が発生しました。これを使用してトリガーするだけです。

/sapi/v1/asset/transferインターフェースは、1 回につき最大 100 個のデータを要求します。1 回の検出の終了から次の検出の開始までの間にアカウントで 100 回を超える転送操作が行われない限り、この検出によって低頻度の転送に問題が発生することはありません。現時点では、いくつかの新しい操作記録が欠落している可能性がありますが、これは一般的な需要シナリオには十分です(通常、資金を無茶苦茶に転送する戦略はありません…)。

もちろん、実際の設計では細かい部分がたくさんあります。例えば、書類を確認すると回転方向がたくさんあることがわかり、それぞれの回転方向を監視する必要があります。このコードは定義するvar dicType = {...}すべての転送方向を管理します。

コンテンツをより適切に表示するために、ステータス バー テーブルを使用して、戦略インターフェイスの最後の 5 つの転送情報を出力します。そのため、次のテーブルを作成します。monitorデータを記録するために使用されるオブジェクト。もちろん、転送情報を無期限に記録することはできませんので、転送方向ごとに 100 件のレコードのみを保持します。レコードが 100 件を超える場合、未完了のレコードは削除されます。

コード例

function getRecentTransferHistory(TransType, typeDesc) {
	// GET /sapi/v1/asset/transfer type, size : 100
    
    var rows = null 
    var ret = exchange.IO("api", "GET", "/sapi/v1/asset/transfer", `type=${TransType}&size=100`)
    Log("/sapi/v1/asset/transfer" + `type=${TransType}&size=100`)
    if (ret && typeof(ret.rows) != "undefined" && Array.isArray(ret.rows)) {
        rows = ret.rows
    } else if (ret && typeof(ret.total) != "undefined" && ret.total == 0) {
        rows = []
    } else {
    	Log(TransType, typeDesc, "查询失败", ret)
    }
    
    return rows
}

var monitor = {}
function monitorTransfers() {
    var dicType = {
        "MAIN_UMFUTURE": "现货钱包 --> U本位合约钱包",
        "MAIN_CMFUTURE": "现货钱包 --> 币本位合约钱包",
        "UMFUTURE_MAIN": "U本位合约钱包 --> 现货钱包",
        "UMFUTURE_MARGIN": "U本位合约钱包 --> 杠杆全仓钱包",
        "CMFUTURE_MAIN": "币本位合约钱包 --> 现货钱包",
        "MARGIN_UMFUTURE": "杠杆全仓钱包 --> U本位合约钱包",
        "MARGIN_CMFUTURE": "杠杆全仓钱包 --> 币本位合约钱包",
        "CMFUTURE_MARGIN": "币本位合约钱包 --> 杠杆全仓钱包",
        "FUNDING_UMFUTURE": "资金钱包 --> U本位合约钱包",
        "UMFUTURE_FUNDING": "U本位合约钱包 --> 资金钱包",
        "FUNDING_CMFUTURE": "资金钱包 --> 币本位合约钱包",
        "CMFUTURE_FUNDING": "币本位合约钱包 --> 资金钱包",
        "UMFUTURE_OPTION": "U本位合约钱包 --> 期权钱包",
        "OPTION_UMFUTURE": "期权钱包 --> U本位合约钱包",
        // 统一账户
        "MAIN_PORTFOLIO_MARGIN": "现货钱包 --> 统一账户钱包",
        "PORTFOLIO_MARGIN_MAIN": "统一账户钱包 --> 现货钱包"
    }
    
    Log("开始检测")
    _.each(dicType, function(v, k) {
        var rows = getRecentTransferHistory(k, v)
        var maxTS = 0
        _.each(rows, function(row) {
            if (typeof(monitor[k]) == "undefined") {
            	monitor[k] = {"transType": k, "typeDesc": v, "recentRecords": [], "lastTS": 0}            	
            }

            if (row["timestamp"] > monitor[k]["lastTS"]) {
                monitor[k]["recentRecords"].push(row)
                
                if (monitor[k]["lastTS"] != 0) {
                	Log("检测到新增划转记录", k, v, row, "#FF0000")
                }                
            }
            maxTS = Math.max(maxTS, row["timestamp"])     
        })
        if (rows && rows.length == 0) {
            return 
        }
        monitor[k]["lastTS"] = maxTS

        var sortedArrayAscending = monitor[k]["recentRecords"].slice().sort((a, b) => a.timestamp - b.timestamp)
        monitor[k]["recentRecords"] = sortedArrayAscending

        if (monitor[k]["recentRecords"].length > 100) {
        	monitor[k]["recentRecords"].shift()
        }
        Sleep(1000)
    })
    Log("开始结束")
}


function main() {
    LogReset()
    while (true) {
        monitorTransfers()

        var tbls = []
        _.each(monitor, function(v, k) {
        	var tbl = {
        		"type": "table", 
        		"title": v["typeDesc"], 
        		"cols": ["asset", "amount", "status", "tranId", "time"], 
        		"rows": []
        	}

            var arr = v["recentRecords"].slice().sort((a, b) => b.timestamp - a.timestamp)
            for (var i = 0; i < arr.length; i++) {
            	if (i < 5) {
            		tbl["rows"].push([arr[i]["asset"], arr[i]["amount"], arr[i]["status"], arr[i]["tranId"], _D(arr[i]["timestamp"])])
            	}            	
            }
            tbls.push(tbl)
        })        

    	LogStatus(_D(), "\n", "`" + JSON.stringify(tbls) + "`")
    	Sleep(1000 * 30)
    }
}

コードの概要:

提供されている JavaScript コードには、最近の資産移転を監視するためのシステムを構築するいくつかの関数が含まれています。主なコンポーネントを分解してみましょう。

  • getRecentTransferHistory 関数:

目的: 指定されたパラメータに従って、取引所 API から最近の資産転送履歴を取得します。 パラメータ: TransType (転送タイプ)、typeDesc (タイプの説明)。 API エンドポイント: /sapi/v1/asset/transfer。

  • monitorTransfers 関数:

目的: 定義済みの転送タイプを反復処理し、最新の転送履歴を取得し、新しい転送を記録します。 辞書 (dicType) を使用して、転送タイプを人間が読める説明にマッピングします。 各タイプの最新の転送を追跡するためにモニター オブジェクトを更新します。

  • 主な機能:

目的: 転送を継続的に監視し、最新のデータを表示する無限ループを実行します。 monitorTransfers 関数を定期的に使用してください。 資産、金額、ステータス、取引 ID、タイムスタンプなどの列を含む、転送タイプごとにテーブルを生成します。

主な特徴:

  • 動的転送タイプマッピング:

このコードでは、辞書 (dicType) を使用して転送タイプを説明名にマッピングし、各転送の性質を明確に説明します。

  • リアルタイム監視:

システムは継続的に新しい転送をチェックし、モニター オブジェクトを更新し、検出された変更を記録します。

  • データの提示:

資産、金額、ステータス、取引 ID、タイムスタンプなどの関連する詳細を含む各タイプの転送データを表を使用して表示します。

  • 最近の転送履歴の管理:

各タイプの最新の転送のスクロール リストを維持し、簡潔かつタイムリーな表示を実現します。

実際のテスト

転送は手動で実行され、プログラムは転送操作を検出しました。

FMZ 定量化: 暗号通貨市場における一般的な需要設計例の分析 (パート 2)

FMZ 定量化: 暗号通貨市場における一般的な需要設計例の分析 (パート 2)

END:

提供されている JavaScript コードは、暗号通貨取引所での最近の資産転送を監視するための強力なソリューションを提供します。動的かつリアルタイムであるため、異なるウォレット間の資産の動きを把握したいトレーダーや開発者にとって貴重なツールとなります。このコードは特定のニーズに合わせて変更およびカスタマイズできるため、暗号通貨取引戦略を強化したり、追加の監視機能を開発したりしたい人にとって強固な基盤となります。

この記事は、デザインのアイデアを提供するための出発点にすぎません。皆さんの暗号通貨ビジネスが有益かつ成功することを願っています。