
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ố:

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
}
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.
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:
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.
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à:
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.
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):


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à:
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:

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"
}
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 đề.