avatar of 发明者量化-小小梦 发明者量化-小小梦
focar em Mensagem privada
4
focar em
1271
Seguidores

Ensina como usar a API estendida do FMZ para modificar em lote parâmetros em tempo real

Criado em: 2023-12-09 20:39:41, atualizado em: 2025-05-16 17:00:20
comments   2
hits   1004

Ensina como usar a API estendida do FMZ para modificar em lote parâmetros em tempo real

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:

Ensina como usar a API estendida do FMZ para modificar em lote parâmetros em tempo real

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 
}

Primeiro, vamos entender a função RestartRobot da API de extensão FMZ.

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.

  • 1. A oferta real foi criada Para um disco real que foi criado, reiniciá-lo naturalmente usa a interface de API estendida do FMZ - a função RestartRobot.
  • 2. O mercado real ainda não foi criado Se nenhum disco real for criado, não há conceito de “modificar” os parâmetros do disco real. Pertence à criação em lote da operação do disco real. Neste momento, a interface API estendida da função FMZ - NewRobot é usada.

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:

  • 1. Somente o ID do disco real é passado, e a configuração dos parâmetros do disco real não é passada. Este método mantém a configuração dos parâmetros inalterada quando o disco real é parado e reinicia apenas o disco real.
  • 2. Insira o ID do disco real e a configuração dos parâmetros do disco real. Este método inicia a operação real do disco com nova configuração de parâmetros.

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.

Obtenha as informações reais que você deseja operar

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:

  • Estratégia interrompida.
  • Há algo errado com a estratégia, pare.

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.

Modificar parâmetros de configuração de 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):

Ensina como usar a API estendida do FMZ para modificar em lote parâmetros em tempo real

Ensina como usar a API estendida do FMZ para modificar em lote parâmetros em tempo real

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

  • Teste 1A
  • Teste 1B

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:

Ensina como usar a API estendida do FMZ para modificar em lote parâmetros em tempo real

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

END

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.