avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Dạy bạn cách sử dụng API mở rộng FMZ để sửa đổi hàng loạt các tham số thời gian thực

Được tạo ra trong: 2023-12-09 20:39:41, cập nhật trên: 2025-05-16 17:00:20
comments   2
hits   1004

Dạy bạn cách sử dụng API mở rộng FMZ để sửa đổi hàng loạt các tham số thời gian thực

Làm thế nào để sửa đổi các tham số thời gian thực theo từng đợt trên FMZ? Khi số lượng đĩa thực vượt quá hàng chục hoặc thậm chí hàng trăm, sẽ rất bất tiện khi bảo trì nếu bạn phải cấu hình thủ công từng đĩa thực một. Lúc này, bạn có thể sử dụng API mở rộng của FMZ để hoàn tất các thao tác này. Trong bài viết này, chúng ta hãy cùng khám phá một số chi tiết về kiểm soát nhóm và cập nhật tham số.

Trong bài viết trước, chúng ta đã tìm hiểu cách sử dụng API mở rộng của FMZ để giám sát tất cả các đĩa thực, kiểm soát nhóm các đĩa thực và gửi hướng dẫn đến các đĩa thực. Chúng tôi vẫn sử dụng mã gọi giao diện được đóng gói trong bài viết trước làm cơ sở và tiếp tục viết mã để thực hiện sửa đổi hàng loạt các tham số thời gian thực.

Cài đặt tham số:

Dạy bạn cách sử dụng API mở rộng FMZ để sửa đổi hàng loạt các tham số thời gian thực

Mã chiến lược:

// 全局变量
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 
}

Trước tiên, chúng ta hãy tìm hiểu hàm RestartRobot của API mở rộng FMZ.

Khi chúng ta cần sửa đổi các tham số thời gian thực theo từng đợt rồi chạy theo thời gian thực, sẽ có hai tình huống xảy ra trong trường hợp này.

  • 1. Lời đề nghị thực sự đã được tạo ra Đối với đĩa thực đã được tạo, việc khởi động lại đĩa sẽ sử dụng giao diện API mở rộng của FMZ - hàm RestartRobot.
  • 2. Thị trường thực sự vẫn chưa được tạo ra Nếu không có đĩa thực nào được tạo, thì không có khái niệm “sửa đổi” các tham số đĩa thực. Nó thuộc về việc tạo hàng loạt hoạt động đĩa thực. Lúc này, giao diện API mở rộng của hàm FMZ - NewRobot được sử dụng.

Nhưng bất kể sử dụng phương pháp nào, các ý tưởng và hoạt động sau đây đều tương tự nhau, vì vậy chúng ta sẽ bắt đầu vớiRestartRobotHàm API mở rộng này được sử dụng làm ví dụ.

Có hai cách để sử dụng chức năng RestartRobot:

  • 1. Chỉ có ID đĩa thực được truyền vào và cấu hình tham số của đĩa thực không được truyền vào. Phương pháp này giữ nguyên cấu hình tham số khi đĩa thực dừng và chỉ khởi động lại đĩa thực.
  • 2. Nhập ID đĩa thực và cấu hình tham số của đĩa thực. Phương pháp này bắt đầu hoạt động của đĩa thực với cấu hình tham số mới.

Phương pháp đầu tiên không có tác dụng gì với tình huống của chúng ta vì yêu cầu của chúng ta là phải sửa đổi hàng loạt số lượng lớn các tham số thời gian thực. Vì vậy, vấn đề là cấu hình tham số của thị trường thực rất phức tạp, bao gồm cấu hình đối tượng trao đổi, cấu hình tham số chiến lược, thiết lập chu kỳ K-line, v.v.

Đừng lo lắng, chúng ta sẽ khám phá từng cái một.

Nhận thông tin thực tế bạn muốn vận hành

Trên FMZ, nếu bạn muốn sửa đổi cấu hình tham số của đĩa thực, thì đĩa thực đó phải ở trạng thái không chạy. Bởi vì chỉ có đĩa thật không ở trạng thái chạy mới có thể sửa đổi cấu hình tham số. Một đĩa thực sự không hoạt động có thể là:

  • Chiến lược đã dừng lại.
  • Có gì đó không ổn với chiến lược này, dừng lại đi.

Vì vậy, trước tiên chúng ta cần có thị trường thực sự của chiến lược cụ thể và những thị trường thực sự này nằm trongTrạng thái dừnghoặcDừng lại khi có lỗitrạng thái.

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

Bằng cách này, chúng ta đã có được tất cả thông tin đĩa thực cần phải sửa đổi. Tiếp theo, chúng ta cần có được cấu hình chi tiết của đĩa thực.

Sửa đổi các tham số cấu hình đĩa thực

Ví dụ, chiến lược thời gian thực có các tham số mà chúng ta cần sửa đổi như sau (tức là chiến lược có ID chiến lược là biến strategyId):

Dạy bạn cách sử dụng API mở rộng FMZ để sửa đổi hàng loạt các tham số thời gian thực

Dạy bạn cách sử dụng API mở rộng FMZ để sửa đổi hàng loạt các tham số thời gian thực

Chiến lược này có 3 tham số như một thử nghiệm.

Sửa đổi các tham số chiến lược thời gian thực, nhưng chúng ta có thể không muốn sửa đổi cấu hình trao đổi của chiến lược. Tuy nhiên, đối với chức năng RestartRobot giao diện API mở rộng, không chỉ định bất kỳ tham số nào (chỉ cần bắt đầu giao dịch thời gian thực như hiện tại), hoặc tất cả các cấu hình tham số phải được Chỉ định.

Điều này có nghĩa là trước khi chúng ta sử dụng hàm RestartRobot để khởi động đĩa thực, trước tiên chúng ta phải sử dụng hàm GetRobotDetail của giao diện API mở rộng để lấy cấu hình hiện tại của đĩa thực, sau đó thay thế các tham số cần sửa đổi để xây dựng lại. khởi động đĩa thực (tức là gọi Tham số sẽ được sử dụng khi RestartRobot) rồi khởi động lại đĩa thực.

Vì vậy, tiếp theo chúng ta duyệt qua robotList và lấy cấu hình tham số hiện tại từng cái một. Trong đoạn mã sau/**/Phần được chú thích là thông tin chi tiết về giao dịch thực tế và chúng ta cần xử lý dữ liệu này tiếp theo.

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)
    })
}

Sau khi chạy chiến lược điều chỉnh tham số hàng loạt này, khối lượng giao dịch thực tế của tôi là:

  • Bài kiểm tra 1A
  • Bài kiểm tra 1B

Các tham số được sửa đổi trong khi đối tượng trao đổi được cấu hình, cặp giao dịch và giai đoạn K-line vẫn không thay đổi:

Trang thị trường thực tế tự động thay đổi thành:

Dạy bạn cách sử dụng API mở rộng FMZ để sửa đổi hàng loạt các tham số thời gian thực

Và bắt đầu chạy. Bởi vì chúng tôi đã chỉ định các tham số đã sửa đổi trong đoạn mã trên:

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

END

Phương pháp này thuận tiện hơn khi cần sửa đổi hàng loạt các thông số của hàng chục hoặc hàng trăm đĩa thực. Trong ví dụ này, các tham số được sửa đổi thành một tham số thống nhất. Tất nhiên, bạn cũng có thể tùy chỉnh các quy tắc sửa đổi của riêng mình trong mã và chỉ định các cấu hình tham số khác nhau cho mỗi tài khoản thực. Hoặc chỉ định các đối tượng trao đổi, cặp giao dịch khác nhau, v.v.

Đối với nền tảng FMZ, các yêu cầu này có thể được tùy chỉnh và triển khai linh hoạt. Nếu bạn có bất kỳ yêu cầu hoặc ý tưởng nào, vui lòng để lại tin nhắn và chúng ta sẽ cùng nhau thảo luận, nghiên cứu và tìm ra giải pháp cho các vấn đề.