Когда количество дисков превышает несколько десятков, а когда их число достигает сотен, очень неудобно поддерживать их вручную. Для этого можно использовать расширенный API FMZ.
В предыдущей статье мы решили, как использовать расширенный API FMZ для мониторинга всех дисков, групповых дисков и отправки инструкций на диски.
Параметры:
Код стратегии
// 全局变量
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
}
Когда нам нужно массово изменить параметры реального диска, а затем запустить реального диска, это сценарий имеет два первых варианта.
Но в любом случае, мысли и действия, которые приходят к нам, очень разные, поэтому мы используемRestartRobot
Функция расширения API используется в качестве примера.
Функция RestartRobot используется двумя способами:
Первый способ не работает для нашего сценария спроса, поскольку мы сами нуждаемся в большом количестве модификаций параметров реального диска.
Не беспокойтесь, мы рассмотрим их по отдельности.
В FMZ, если нужно изменить параметровую конфигурацию диска, то он должен быть в нерабочем состоянии.
Итак, сначала мы должны получить диски с указанными стратегиями, и эти диски находятся вПрекращениеИлиОшибка остановкиВ этом случае мы не можем.
function main() {
var stopRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 4)
var errorRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 5)
var robotList = stopRobotList.concat(errorRobotList)
}
Таким образом, мы получаем всю информацию о диске, которая требует изменения конфигурации, а затем мы получаем более подробную конфигурацию диска.
Например, нам нужно изменить параметры реального диска следующим образом (т.е. политика ID для переменной strategyId):
Эта стратегия состоит из трех параметров, которые используются в качестве эксперимента.
Изменить параметры политики реального диска, но, возможно, мы не хотим менять конфигурацию биржи политики, но для расширенного интерфейса API функции RestartRobot либо не указывать никаких параметров (оригинал не действует только для запуска реального диска), либо все параметры конфигурации должны быть указаны.
Это означает, что перед тем, как мы начнем запускать диск с помощью функции RestartRobot, мы должны сначала использовать расширенный API-интерфейс GetRobotDetail, чтобы получить доступ к текущей конфигурации диска, затем мы заменяем часть параметров, которые мы хотим изменить, перестраиваем параметры конфигурации запуска диска (т.е. параметры, которые будут использоваться при вызове RestartRobot), а затем перезапускаем диск.
Итак, следующее, что мы делаем, это ходим по списку роботов и получаем текущую конфигурацию параметров один за другим./**/
В частности, это информация о деталях реального диска, которую мы должны обработать в дальнейшем.
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)
})
}
После выполнения этой стратегии массового изменения параметров, мой диск:
Изменены параметры при условии неизменности конфигурированных объектов биржи, торговых пар, циклов K-линий:
На странице диска автоматически изменяется на:
И начать работать. Потому что мы указали параметры изменения в вышеприведенном коде:
// 更新参数
var dicParams = {
"pairs" : "AAA_BBB,CCC_DDD",
"col" : "999",
"htight" : "666"
}
Для десятков, сотен дисков массовых модификаций параметров этот метод является более удобным. В данном случае модификация является единым параметром. Конечно, вы также можете настроить свои правила модификации в коде, назначив разные параметры для каждого диска; или назначить разные объекты обмена, сделки и т. д.
Для платформы FMZ все эти потребности могут быть адаптированы, и если у вас есть идеи, пожалуйста, оставьте комментарии, чтобы мы обсудили, изучили и изучили решения.
Пойдемте.Это огромная сумма денег на десятки, сотни дисков и аренду.
Изобретатели количественного измерения - мечтыНекоторые из них используют FMZ для расширения API для упаковки продуктов, и есть много дисков.