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

Explorando FMZ: Uma nova aplicação de botões da barra de status (Parte 1)

Criado em: 2024-07-25 15:20:47, atualizado em: 2024-07-26 16:10:27
comments   0
hits   881

Explorando FMZ: Uma nova aplicação de botões da barra de status (Parte 1)

Com uma grande atualização na interface da API da plataforma de negociação quantitativa, os parâmetros da interface de estratégia da plataforma, os controles interativos e outras funções foram ajustados, e muitas novas funções foram adicionadas. O artigo anterior apresentou em detalhes as atualizações dos parâmetros da interface e dos controles interativos. Este artigo continua explorando a aplicação do botão da barra de status recém-introduzido do FMZ.COM.

Todo desenvolvedor de estratégia quer criar uma interface de usuário que seja fácil de usar, poderosa e simples no design. Para atingir esse padrão, a FMZ.COM não poupa esforços para atualizar as funções da plataforma e melhorar a experiência do usuário. Projetar controles interativos diretamente na barra de status da página de estratégia é uma atualização baseada nessa demanda.

A seguir, vamos analisar sua aplicação em um cenário de estratégia multivariada.

Cenários de estratégia multiproduto

Seja uma estratégia de arbitragem multivariedade totalmente automática ou uma estratégia de cronometragem multivariedade semimanual. A interface de estratégia precisará ter alguns botões interativos funcionais, como take profit, stop loss, liquidação, confiança planejada, etc. para um determinado produto.

Então, vamos explorar os novos recursos do botão da barra de status com um cenário de uso mais simples. Suponha que nossa estratégia negocie vários símbolos:

Contrato perpétuo BTC_USDT, contrato perpétuo ETH_USDT, contrato perpétuo LTC_USDT, contrato perpétuo BNB_USDT, contrato perpétuo SOL_USDT

Enquanto a estratégia executa a negociação automática, esperamos projetar um botão de abertura para cada produto na barra de status da interface da estratégia. Mas esse botão de posição aberta requer uma série de configurações detalhadas, como:

  • Tipo de ordem: Ordem limitada/Ordem de mercado.
  • A quantidade do pedido: quantidade.
  • O preço do pedido: preço.
  • Direção de negociação: comprar (longo), vender (curto).

Antes desta atualização de plataforma, o botão da barra de status simplesmente acionava uma mensagem de interação do botão. Não há como vincular uma série de controles para configurar mensagens complexas. Esta atualização da interação resolve essa necessidade. Vamos dar uma olhada no design do código. Comentários detalhados são adicionados ao código para facilitar o entendimento de como construir tal função.

Exemplos de design:

// 设置操作的各个品种 BTC_USDT.swap 为FMZ平台定义的品种格式,表示BTC的U本位永续合约
var symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]

// 根据按钮模板构造按钮
function createBtn(tmp, group) {
    var btn = JSON.parse(JSON.stringify(tmp))
    _.each(group, function(eleByGroup) {
        btn["group"].unshift(eleByGroup)
    })

    return btn
}

function main() {
    LogReset(1)

    var arrManager = []
    _.each(symbols, function(symbol) {
        arrManager.push({
            "symbol": symbol,
        })
    })

    // Btn
    var tmpBtnOpen = {
        "type": "button",
        "cmd": "open",
        "name": "开仓下单",
        "group": [{
            "type": "selected",
            "name": "tradeType",
            "label": "下单类型",
            "description": "市价单、限价单",
            "default": 0,
            "group": "交易设置",
            "settings": {
                "options": ["市价单", "限价单"],
                "required": true,
            }
        }, {
            "type": "selected",
            "name": "direction",
            "label": "交易方向",
            "description": "买入、卖出",
            "default": "buy",
            "group": "交易设置",
            "settings": {
                "render": "segment",
                "required": true,
                "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
            }
        }, {
            "type": "number",
            "name": "price",
            "label": "价格",
            "description": "订单的价格",
            "group": "交易设置",
            "filter": "tradeType==1",
            "settings": {
                "required": true,
            }
        }, {
            "type": "number",
            "name": "amount",
            "label": "下单量",
            "description": "订单的下单量",
            "group": "交易设置",
            "settings": {
                "required": true,
            }
        }],
    }

    while (true) {
        var tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []}
        _.each(arrManager, function(m) {
            var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": true}}])
            tbl["rows"].push([m["symbol"], btnOpen])
        })
        
        var cmd = GetCommand()
        if (cmd) {
            Log("收到交互:", cmd)
            
            // 解析交互消息: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
            // 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息
            var arrCmd = cmd.split(":", 2)
            if (arrCmd[0] == "open") {
                var msg = JSON.parse(cmd.slice(5))
                Log("交易品种:", msg["symbol"], ",交易方向:", msg["direction"], ",订单类型:", msg["tradeType"] == 0 ? "市价单" : "限价单", msg["tradeType"] == 0 ? ",订单价格:当前市价" : ",订单价格:" + msg["price"], ",订单数量:", msg["amount"])
            }
        }

        // 输出状态栏信息
        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
        Sleep(1000)
    }
}

Vamos primeiro dar uma olhada no efeito de corrida e depois explicar o design do controle de botão em detalhes. O código da estratégia é executado conforme mostrado abaixo:

Explorando FMZ: Uma nova aplicação de botões da barra de status (Parte 1)

Clique em um botão e uma janela pop-up aparecerá para configurar as informações específicas do pedido:

Explorando FMZ: Uma nova aplicação de botões da barra de status (Parte 1)

Após preencher as informações de abertura nós projetamos.

Explorando FMZ: Uma nova aplicação de botões da barra de status (Parte 1)

Você pode ver que a estratégia recebeu a mensagem e, no código, analisamos a mensagem e exibimos as várias configurações para o pedido. A seguir, vamos dar uma olhada em como esse botão é construído:

Primeiro, definimos um modelo de botão, que é um objeto JSON, e o atribuímos à variável tmpBtnOpen. Incluí as instruções específicas diretamente nos comentários do código abaixo.

    {
        "type": "button",       // 状态栏输出控件的类型,目前仅支持按钮
        "cmd": "open",          // 当按钮触发时,策略中GetCommand函数收到的消息前缀,例如这个例子:open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
        "name": "开仓下单",      // 策略界面,状态栏上的按钮上显示的内容,参考上图
        "group": [{             // 当按钮触发时,弹框中的控件配置设置,这一层的group字段值是一个数组,弹框中的控件根据这个数组顺序自上而下排列
            "type": "selected",               // 第一个控件类型是:selected ,下拉框 
            "name": "tradeType",              // 当状态栏按钮触发时,消息中包含该控件的设置内容,tradeType就是当前这个下拉框控件输入的值的键名。如果选择第一个选项「市价单」GetCommand函数收到的消息中就包含 "tradeType":0 的键值对信息。
            "label": "下单类型",               // 按钮触发时,弹框中当前控件的标题
            "description": "市价单、限价单",    // 当前控件的说明信息,鼠标放在控件右侧“小问号”图标上就会显示这个说明信息。
            "default": 0,                     // 当前控件的默认值,例如当前是下拉框控件,如果不做选择,默认为下拉框第一个选项,通常下拉框的默认值指的是下拉框选项的索引,即第一个是0,然后是1,以此类推。如果下拉框的选项options是key-value形式则默认值指的是value。
            "group": "交易设置",               // 弹框中的控件如果很多,可以分组,这个字段可以设置分组信息
            "settings": {                     // 当前这个下拉框的具体设置
                "options": ["市价单", "限价单"],   // options和下拉框相关的设置,用于设置下拉框中的选项,这个字段值是一个数组,依次排列下拉框中的选项。
                "required": true,                // required表示是否设置为必选(必填)内容。
            }
        }, {
            "type": "selected",         // 这也是一个下拉框类型
            "name": "direction",
            "label": "交易方向",
            "description": "买入、卖出",
            "default": "buy",
            "group": "交易设置",
            "settings": {
                "render": "segment",   // 和默认下拉框控件不同的是,通过render字段可以把下拉框替换为“分段选择器”,如上图中的“买入/卖出”控件。
                "required": true,
                "options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],   // 使用 key-value方式设置options
            }
        }, {
            "type": "number",           // 数值输入框类型控件
            "name": "price",
            "label": "价格",
            "description": "订单的价格",
            "group": "交易设置",
            "filter": "tradeType==1",   // 过滤器,可以用于确定是否显示当前控件,当tradeType==1时,表示是市价单,所以不需要该控件设置价格,所以不显示。
            "settings": {
                "required": true,       // 当该控件激活显示时为必选(必填)
            }
        }, {
            "type": "number",
            "name": "amount",
            "label": "下单量",
            "description": "订单的下单量",
            "group": "交易设置",
            "settings": {
                "required": true,
            }
        }],
    }
  • group Como este é apenas um exemplo, pode haver mais requisitos no design e uso reais, não limitados à direção do pedido, preço, quantidade e tipo de pedido definido ao abrir uma posição. Também pode haver regras de saída projetadas, como ordens de planos de take-profit e stop-loss. Então a nova versão da IU suportagroupCampo que torna conveniente agrupar um grupo de controles na janela pop-up para exibição, como a configuração recolhida “Configurações de transação” na captura de tela acima.

  • required Estrutura do botãogroupOs controles estabelecidos no campo foram aumentadosrequiredO campo de configuração é usado para definir se é obrigatório (obrigatório). Se for definido como obrigatório (obrigatório), mas não for preenchido (selecionado) durante o uso, você não poderá clicar no botão OK para enviar as informações interativas, e um vermelho uma mensagem de aviso é exibida.

  • filter AdicionadofilterO campo é usado para definir dependências de filtro. Por exemplo, no exemplo acima, se o tipo de ordem de mercado for selecionado, o preço da ordem não será necessário.typeé “número”,nameOs controles de “preço” estão ocultos.

  • render Para esses tipos básicos de controles (configurações de campo de tipo): número, sequência de caracteres, selecionado, booleano. Campos adicionadosrenderUsado para definir renderização de controle. Cada controle tem seus próprios componentes de renderização múltiplos. Por exemplo, no exemplo acima, é mais apropriado renderizar o controle da caixa suspensa selecionada como um “seletor de segmento”, porque a caixa suspensa precisa ser clicada duas vezes (a primeira vez para expandir a caixa suspensa , e a segunda vez para selecionar uma opção). Use o componente seletor de segmento , basta clicar e selecionar a opção desejada.

Por fim, leitores atentos podem perguntar, na captura de tela acima, não vejo as informações de controle na caixa pop-up onde você escreveu “Tipo de negociação”, e este “Tipo de negociação” não pertence ao grupo “Configurações de negociação” (ou seja:"group": "交易设置"Esta configuração implementa).

Aqui está uma demonstração de um design que vincula os botões na tabela da barra de status a outras informações na barra de status.createBtnFunção baseada em modelotmpBtnOpenConstrua a estrutura final do botão e escreva outras informações na estrutura do botão durante a construção.

// 构造按钮的时候,绑定当前行的品种名称等信息,给按钮的弹框增加一个控件,并排在首位
var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": true}}])

Então o efeito final é que quando você clica na barra de status na interface de estratégiasymbolparaBNB_USDT.swapAo clicar no botão nesta linha, a caixa de entrada “Tipo de negociação” na janela pop-up será preenchida automaticamente.BNB_USDT.swap

Este artigo apresenta apenas uma pequena parte da aplicação da nova versão da UI. Como o comprimento geral não pode ser muito longo, continuaremos a discutir o design de outros cenários de demanda no próximo artigo.

Obrigado pelo seu apoio!