
Como modificar os parâmetros em tempo real em lotes no FMZ? Quando o número de discos reais excede dezenas ou até mesmo chega a centenas, é muito inconveniente fazer a manutenção se você configurar manualmente os discos reais um por um. Neste momento, você pode usar a API estendida da FMZ para concluir essas operações. Neste artigo, vamos explorar alguns detalhes sobre controle de grupo e atualização de parâmetros.
No artigo anterior, resolvemos como usar a API estendida do FMZ para monitorar todos os discos reais, controlar grupos de discos reais e enviar instruções para discos reais. Ainda usamos o código de chamada de interface encapsulado no artigo anterior como base e continuamos a escrever código para realizar modificações em lote de parâmetros em tempo real.
Configurações de parâmetros:

Código de estratégia:
// 全局变量
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
}
Quando precisamos modificar os parâmetros em tempo real em lotes e depois executá-los em tempo real, há duas situações neste cenário.
Mas não importa qual método seja usado, as seguintes ideias e operações são semelhantes, então começaremos comRestartRobotEsta função de API estendida é usada como exemplo.
Há duas maneiras de usar a função RestartRobot:
O primeiro método não é útil para o nosso cenário, porque nossa necessidade é modificar um grande número de parâmetros em tempo real em lotes. Então o problema é que a configuração dos parâmetros do mercado real é muito complicada, incluindo a configuração do objeto de troca, a configuração dos parâmetros da estratégia, a configuração do ciclo da linha K, etc.
Não se preocupe, vamos explorá-los um por um.
No FMZ, se você quiser modificar a configuração dos parâmetros de um disco real, o disco real deverá estar em um estado não em execução. Porque somente o disco real que não está em estado de execução pode modificar a configuração dos parâmetros. Um disco real que não está em operação pode ser:
Então, primeiro precisamos obter o mercado real da estratégia especificada, e esses mercados reais estão emEstado de paradaouParar em caso de errostatus.
function main() {
var stopRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 4)
var errorRobotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, 5)
var robotList = stopRobotList.concat(errorRobotList)
}
Dessa forma, obtivemos todas as informações reais do disco que precisam ser modificadas. Em seguida, precisamos obter a configuração detalhada do disco real.
Por exemplo, a estratégia em tempo real cujos parâmetros precisamos modificar é a seguinte (ou seja, a estratégia cujo ID de estratégia é a variável strategyId):


Essa estratégia tem 3 parâmetros, como um experimento.
Modifique os parâmetros da estratégia em tempo real, mas podemos não querer modificar a configuração de câmbio da estratégia. No entanto, para a função RestartRobot da interface API estendida, nenhum parâmetro é especificado (apenas inicie a negociação em tempo real como está) ou todas as configurações de parâmetros devem ser especificadas.
Isso significa que antes de usarmos a função RestartRobot para iniciar o disco real, devemos primeiro usar a função GetRobotDetail da interface API estendida para obter a configuração atual do disco real e, em seguida, substituir os parâmetros que precisam ser modificados para reconstruir o inicialização do disco real (ou seja, chamar os parâmetros a serem usados quando RestartRobot) e então reiniciar o disco real.
Então, em seguida, percorremos robotList e obtemos a configuração de parâmetros atual, um por um. No código a seguir/**/A parte comentada contém as informações detalhadas da transação real, e precisamos processar esses dados em seguida.
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)
})
}
Depois de executar esta estratégia de modificação de parâmetros em lote, meu volume de negociação real é:
Os parâmetros são modificados enquanto o objeto de troca configurado, o par de negociação e o período da linha K permanecem inalterados:
A página do mercado real muda automaticamente para:

E comece a correr. Porque especificamos os parâmetros modificados no código acima:
// 更新参数
var dicParams = {
"pairs" : "AAA_BBB,CCC_DDD",
"col" : "999",
"htight" : "666"
}
Este método é mais conveniente para modificar em lote parâmetros de dezenas ou centenas de discos reais. Neste exemplo, os parâmetros são modificados para um unificado. Claro, você também pode personalizar suas próprias regras de modificação no código e especificar diferentes configurações de parâmetros para cada conta real. Ou especifique diferentes objetos de troca, pares de negociação, etc.
Para a plataforma FMZ, esses requisitos podem ser personalizados e implementados de forma flexível. Se você tiver quaisquer requisitos ou ideias, deixe uma mensagem e discutiremos, pesquisaremos e aprenderemos soluções para os problemas juntos.