Teach you how to use the FMZ Extension API to modify disk parameters in bulk

Author: The Little Dream, Created: 2023-12-09 20:39:41, Updated: 2023-12-12 21:43:48

img

How to modify disk parameters in bulk on FMZ? When the number of disks is more than a few dozen, when it reaches hundreds, it is very inconvenient to maintain if one disk is configured manually. This time you can use the FMZ extension API to complete these operations.

In the previous article we solved how to use FMZ's extension API to monitor all disks, cluster disks, and send instructions to disks. Still, using the interface call code we wrapped in the previous article as a basis, we continued to write code to achieve batch modification of disk parameters.

The parameters are set:

img

This is the code of the strategy:

// 全局变量
var isLogMsg = true   // 控制日志是否打印
var isDebug = false   // 调试模式
var arrIndexDesc = ["all", "running", "stop"]
var descRobotStatusCode = ["空闲中", "运行中", "停止中", "已退出", "被停止", "策略有错误"]
var dicRobotStatusCode = {
    "all" : -1,
    "running" : 1,
    "stop" : 4,
}

// 扩展的日志函数
function LogControl(...args) {
    if (isLogMsg) {
        Log(...args)
    }
}

// FMZ扩展API调用函数
function callFmzExtAPI(accessKey, secretKey, funcName, ...args) {
    var params = {
        "version" : "1.0",
        "access_key" : accessKey,
        "method" : funcName,
        "args" : JSON.stringify(args),
        "nonce" : Math.floor(new Date().getTime())
    }

    var data = `${params["version"]}|${params["method"]}|${params["args"]}|${params["nonce"]}|${secretKey}`
    params["sign"] = Encode("md5", "string", "hex", data)
    
    var arrPairs = []
    for (var k in params) {
        var pair = `${k}=${params[k]}`
        arrPairs.push(pair)
    }
    var query = arrPairs.join("&")
    
    var ret = null
    try {
        LogControl("url:", baseAPI + "/api/v1?" + query)
        ret = JSON.parse(HttpQuery(baseAPI + "/api/v1?" + query))
        if (isDebug) {
            LogControl("Debug:", ret)
        }
    } catch(e) {
        LogControl("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
    }
    Sleep(100)  // 控制频率
    return ret 
}

// 获取指定策略Id的所有运行中的实盘信息
function getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, robotStatusCode, maxRetry) {
    var retryCounter = 0
    var length = 100
    var offset = 0
    var arr = []

    if (typeof(maxRetry) == "undefined") {
        maxRetry = 10
    }

    while (true) {
        if (retryCounter > maxRetry) {
            LogControl("超过最大重试次数", maxRetry)
            return null
        }
        var ret = callFmzExtAPI(accessKey, secretKey, "GetRobotList", offset, length, robotStatusCode)
        if (!ret || ret["code"] != 0) {
            Sleep(1000)
            retryCounter++
            continue
        }

        var robots = ret["data"]["result"]["robots"]
        for (var i in robots) {
            if (robots[i].strategy_id != strategyId) {
                continue
            }
            arr.push(robots[i])
        }

        if (robots.length < length) {
            break
        }
        offset += length
    }

    return arr 
}

First, let's get acquainted with the RestartRobot function of the FMZ extension API.

When we need to modify the disk parameters in bulk and then run the disk, this scenario has two scenarios first.

  • 1, the disk has been created. For a virtual disk that has already been created, restarting naturally is done using FMZ's extended API interface plugin RestartRobot function.
  • 2 The hard drive has not been created yet The notion of a dynamically modified dynamic disk without creating a disk is no longer a concept, but a batch-built disk run, using the FMZ's extended API interface, the NewRobot function.

But either way, the next thing to thinking and doing is pretty much the same, so we're going to use theRestartRobotThis extended API function is used as an example.

There are two ways to use the RestartRobot function:

  • 1, only input the disk ID, not the disk parameter configuration. This keeps the parameter configuration unchanged when the disk stops, merely restarting the disk.
  • 2, passing the disk ID, also passing the disk parameter configuration. This way, the hard drive starts running with the new parameter configuration.

The first method is not very useful for our demand scenario, because our own needs are to modify a large number of disk parameters in bulk. So the problem arises, the parameter configuration of the disk is very complex, with exchange object configurations, policy parameter configurations, K-line cycle settings, etc.

Don't worry, we'll find out one by one.

Obtain real-time information for operations

In FMZ, if the parameter configuration of a disk is to be modified, the disk must be in non-running state.

  • The policy is suspended.
  • The policy is wrong, stop.

So the first thing we're going to do is we're going to get a disk with the specified policy, and these disks are in theStoppedOrThere is an error stopThe state of the world.

function main() {
    var stopRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 4)
    var errorRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 5)
    var robotList = stopRobotList.concat(errorRobotList)
}

This gives us all the information about the disk configuration that needs to be modified, and then we get the detailed configuration of the disk.

Modify the disk configuration parameters

For example, we need to modify the real disk policy of the parameter as follows (i.e. policy ID for strategyId variable):

img

img

This strategy has three parameters to test.

Change the policy parameters of the disk, but it is possible that we do not want to change the policy exchange configuration, but for the extended API interface RestartRobot function, either no parameters are specified (the original package is not active only to start the disk), or all parameter configurations must be specified.

This means that before we start the disk with the RestartRobot function, we must first use the extended API interface GetRobotDetail to access the current configuration of the disk, and then we replace the part of the parameter that needs to be modified, reconstruct the configuration parameters of the disk start (i.e. the parameters to be used when calling RestartRobot), and then restart the disk.

So the next thing we do is we go through the robots list and we get the current parameter configuration one by one, in the following code./**/The comment section is the details of the disk, and then we need to process the data.

function main() {
    var stopRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 4)
    var errorRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 5)

    var robotList = stopRobotList.concat(errorRobotList)
    _.each(robotList, function(robotInfo) {
        var robotDetail = callFmzExtAPI(accessKey, secretKey, "GetRobotDetail", robotInfo.id)
        
        /*
        {
            "code": 0,
            "data": {
                "result": {
                    "robot": {
                        ...
                        "id": 130350,
                        ...
                        "name": "测试1B",
                        "node_id": 3022561,
                        ...
                        "robot_args": "[[\"pairs\",\"BTC_USDT,ETH_USDT,EOS_USDT,LTC_USDT\"],[\"col\",3],[\"htight\",300]]",
                        "start_time": "2023-11-19 21:16:12",
                        "status": 5,
                        "strategy_args": "[[\"pairs\",\"币种列表\",\"英文逗号间隔\",\"BTC_USDT,ETH_USDT,EOS_USDT,LTC_USDT\"],[\"col\",\"宽度\",\"页面总宽度为12\",6],[\"htight\",\"高度\",\"单位px\",600],[\"$$$__cmd__$$$coverSymbol\",\"平仓\",\"平仓交易对\",\"\"]]",
                        "strategy_exchange_pairs": "[3600,[186193],[\"BTC_USD\"]]",
                        "strategy_id": 131242,
                        "strategy_last_modified": "2023-12-09 23:14:33",
                        "strategy_name": "测试1",
                        ...
                    }
                },
                "error": null
            }
        }
        */

        // 解析交易所配置数据
        var exchangePairs = JSON.parse(robotDetail.data.result.robot.strategy_exchange_pairs)

        // 拿到交易所对象索引、交易对,这些设置是不打算修改的
        var arrExId = exchangePairs[1]
        var arrSymbol = exchangePairs[2]

        // 解析参数配置数据
        var params = JSON.parse(robotDetail.data.result.robot.robot_args)

        // 更新参数
        var dicParams = {
            "pairs" : "AAA_BBB,CCC_DDD",
            "col" : "999",
            "htight" : "666"
        }
        
        var newParams = []
        _.each(params, function(param) {
            for (var k in dicParams) {
                if (param[0] == k) {
                    newParams.push([k, dicParams[k]])  // 构造策略参数,更新上新参数值
                }
            }
        })
        
        // 注意如果数据中有空格需要转码,否则请求的时候会报错
        settings = {
            "name": robotDetail.data.result.robot.name,
            // 策略参数
            "args": newParams,         
            // 策略ID,可以用GetStrategyList方法获取到
            "strategy": robotDetail.data.result.robot.strategy_id,
            // K线周期参数,60即为60秒
            "period": exchangePairs[0],
            // 指定在哪个托管者上运行,不写该属性就是自动分配运行
            "node" : robotDetail.data.result.robot.node_id,
            "exchanges": []
        }
                                
        for (var i = 0 ; i < arrExId.length ; i++) {
            settings["exchanges"].push({"pid": arrExId[i], "pair": arrSymbol[i]})
        }
        Log(settings) // 测试
        var retRestart = callFmzExtAPI(accessKey, secretKey, "RestartRobot", robotInfo.id, settings)
        Log("retRestart:", retRestart)
    })
}

After running this batch modification strategy, my virtual drive:

  • Testing 1A
  • Testing 1B

Modified parameters in case the configured exchange object, trading pair, K line cycle is unchanged:

The page on the hard drive is automatically changed to:

img

This is the first step in the process of making a change to the parameters that we specify in the code above:

        // 更新参数
        var dicParams = {
            "pairs" : "AAA_BBB,CCC_DDD",
            "col" : "999",
            "htight" : "666"
        }

END

For dozens or hundreds of disks, it is relatively convenient to use this method. In this example, the modification is a unified parameter. Of course, you can also customize your own modification rules in the code, specifying a different parameter configuration for each disk.

For the FMZ platform, these needs can be flexibly tailored, any ideas are welcome, and we will explore, research and learn solutions together.


More

allez-zDozens, hundreds of discs, a month's rent is a lot of money.

The Little DreamThere are a few that use the FMZ Extension API to package products, and there are many physical disks.