FMZ量化:加密货币市场常见需求设计实例解析(二)

Author: 小小梦, Created: 2023-12-24 22:24:58, Updated: 2023-12-25 17:10:56

img

应上期文章中读者留言,需求一个监控合约账户划转的程序例子,本期我们来以币安交易所为测试对象,实现这个需求,一起来学习如何设计。

加密货币交易所每天都会处理大量交易,其中包括不同钱包之间的资产划转。实时监控这些划转对于交易者和开发人员来说至关重要。本文将探讨一段JavaScript代码,该代码旨在监控加密货币交易所上最近的资产划转,并讨论其关键组成部分。

分析需求

查阅了币安交易所的文档,发现有一个划转历史接口可以查询到所有划转信息。由于我们只是监控可能发生的划转记录,所以我们不需要获取所有的划转历史。我们只需要根据一定频率检查近期的一定范围内的划转记录。发现如果有新的划转记录就进行更新、通报。

使用这个接口:

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

那么如何检查新增的划转记录呢?看了币安的文档后发现这个接口返回的数据中有时间戳,用时间戳判断非常简单,只要有比当前记录的最大的时间戳更大的记录,说明有新增的划转动作发生了。以此来触发就可以了。

/sapi/v1/asset/transfer接口每次请求最多100条数据,这种检测对于低频的划转不会产生问题,除非在一次检测结束,下次检测开始前,账户有超过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) 将划转类型映射到易读的描述。 更新 monitor 对象以跟踪每种类型的最新划转。

  • main 函数:

    目的: 运行一个无限循环,持续监控划转并显示最新数据。 定期使用 monitorTransfers 函数。 为每种划转类型生成一个表,包含资产、金额、状态、交易ID和时间戳等列。

关键特点:

  • 动态划转类型映射:

    代码使用字典 (dicType) 将划转类型映射到描述性的名称,为每种划转的性质提供清晰说明。

  • 实时监控:

    该系统持续检查新的划转,更新 monitor 对象并记录任何检测到的更改。

  • 数据呈现:

    使用表格呈现每种类型的划转数据,包括资产、金额、状态、交易ID和时间戳等相关详情。

  • 最近划转历史管理:

    为每种类型保持最近划转记录的滚动列表,确保简洁而及时的显示。

实盘测试

手动进行了一笔划转,程序检测到了划转操作。

img

img

END:

提供的JavaScript代码为监控加密货币交易所上最近的资产划转提供了强大的解决方案。其动态和实时的特性使其成为交易者和开发人员寻求了解不同钱包之间资产动向的有价值工具。此代码可以根据具体需求进行修改和定制,为那些希望增强加密货币交易策略或开发额外监控功能的人提供了坚实的基础。

本文抛砖引玉,提供一个设计思路,愿您的加密货币事业既充满信息又成功!


More

98K-波段追踪_Long 小梦老师 就是现实版的多啦A梦 小梦老师最帅 love you