O recurso está a ser carregado... Carregamento...

Explicação pormenorizada da actualização da API FMZ Quant: Melhoria da experiência de concepção da estratégia

Autora:FMZ~Lydia, Criado: 2024-07-05 09:44:08, Atualizado: 2024-07-25 15:15:03

[TOC]

img

Explicação pormenorizada da actualização da API FMZ Quant: Melhoria da experiência de concepção da estratégia

Prefácio

Após 9 anos de iteração técnica, a plataforma de negociação quântica FMZ foi reconstruída várias vezes, embora como usuários possamos não ter notado. nos últimos dois anos, a plataforma fez muitas otimizações e atualizações em termos de experiência do usuário, incluindo uma atualização abrangente da interface da UI, enriquecimento de ferramentas de negociação quantitativas comumente usadas e adição de mais suporte de dados de backtesting.

Para tornar o design de estratégia mais conveniente, a lógica de negociação mais clara e mais fácil para iniciantes, a plataforma atualizou a interface API usada pela estratégia. Os dockers que usam a versão mais recente podem habilitar esses novos recursos. A plataforma ainda é compatível com as antigas chamadas de interface na maior extensão. As informações sobre os novos recursos da interface API foram atualizadas para a documentação API da FMZ Quant Trading Platform:

Guia de sintaxe:https://www.fmz.com/syntax-guideGuia do utilizador:https://www.fmz.com/user-guide

Então vamos dar uma olhada rápida em quais interfaces foram atualizadas e quais mudanças são necessárias para usar estratégias antigas para torná-las compatíveis com a API atual.

1. Nova interface API

Adicionado a função GetTickers

Para a concepção de estratégias multiproduto e estratégias de monitoramento de mercado completo, a interface de mercado agregada é essencial.

Se o exchange não tiver esta interface (intercâmbios individuais), ao ligarexchange.GetTickers(), é exibida uma mensagem de erro: Não suportado.

Esta função não possui parâmetros e retornará os dados de mercado em tempo real de todas as variedades na interface de mercado agregada da bolsa.

exchange.GetTickers()função é a versão de solicitação completa doexchange.GetTicker()função (olhe com cuidado, a diferença entre esses dois nomes de função é apenas o singular e o plural).

Utilizamos o ambiente de simulação de pontos OKX para testes:

function main() {
    exchange.IO("simulate", true)

    var tickers = exchange.GetTickers()
    if (!tickers) {
        throw "tickers error"
    }

    var tbl = {type: "table", title: "test tickers", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []}
    for (var i in tickers) {
        var ticker = tickers[i]
        tbl.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume])
    }

    LogStatus("`" + JSON.stringify(tbl) +  "`")
    return tickers.length
}

img

Adicionado a função de troca.CreateOrder

O novoexchange.CreateOrder()A função mais importante doexchange.CreateOrder()A função principal do sistema é especificar diretamente o tipo e a direcção da ordem nos parâmetros da função, deixando de depender do par de negociação actual, do código do contrato, da direcção da negociação e de outras configurações do sistema.

Em cenários de colocação de ordens de negociação de várias espécies e em cenários concomitantes, a complexidade do projeto é muito reduzida.exchange.CreateOrder()função sãosymbol, side, price, amount.

Teste utilizando o ambiente de simulação de futuros OKX:

function main() {
    exchange.IO("simulate", true)

    var id1 = exchange.CreateOrder("ETH_USDT.swap", "buy", 3300, 1)
    var id2 = exchange.CreateOrder("BTC_USDC.swap", "closebuy", 70000, 1)
    var id3 = exchange.CreateOrder("LTC_USDT.swap", "sell", 110, 1)

    Log("id1:", id1, ", id2:", id2, ", id3:", id3)
}

img

Desta forma, apenas trêsexchange.CreateOrder()As chamadas de função foram utilizadas para colocar três ordens de futuros de diferentes variedades e direcções.

Adicionado a função de troca.GetHistoryOrders

O novoexchange.GetHistoryOrders()A função é utilizada para obter as ordens de transacção históricas de uma certa variedade.

Para consultar ordens históricas, as interfaces implementadas por várias bolsas variam muito:

  • Alguns suportam consultas paginadas, enquanto outros não;
  • Algumas bolsas têm um período de janela de consulta, ou seja, ordens com mais de N dias não podem ser consultadas;
  • A maioria das exchanges suporta consulta em um momento especificado, mas algumas não; Essas interfaces são encapsuladas com o mais alto grau de compatibilidade e, na utilização real, deve ser prestada atenção para verificar se cumprem os requisitos e as expectativas da estratégia.

A descrição detalhada da função não é repetida aqui, você pode consultar o manual de sintaxe na documentação da API:

https://www.fmz.com/syntax-guide#fun_exchange.gethistoryorders

Testado usando o ambiente de negociação Binance spot:

function main() {
    var orders = exchange.GetHistoryOrders("ETH_USDT")

    // Write to chart
    var tbl = {type: "table", title: "test GetHistoryOrders", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
    for (var order of orders) {
        tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
    }
    
    LogStatus("orders.length:", orders.length, "\n", "`" + JSON.stringify(tbl) +  "`")
}

img

Adicionado a função de troca.GetPositions

A versão antiga da função de aquisição de dados de posição éexchange.GetPosition()Esta atualização adiciona uma nova função de aquisição de posição para melhor combinar a semântica de nomeação da função:exchange.GetPositions(). Ao mesmo tempo, ainda é compatível/actualizado com a função GetPosition.

Oexchange.GetPositions()A função tem três formas de chamada:

  • troca.GetPositions ((() Quando não forem transmitidos parâmetros, os dados de posição são solicitados com base nas configurações do par de negociação/código do contrato em curso.
  • Transferência.GetPositions ((ETH_USDT.swap) Ao especificar informações específicas sobre o produto (o formato do ETH_USDT.swap é definido pela plataforma FMZ), solicitar os dados de posição do produto específico.
  • troca.GetPositions ((("") Solicitar à interface de posição de câmbio para obter todas as dimensões atuais dos dados de posição (divididas de acordo com a dimensão do produto da interface de câmbio) Teste utilizando o ambiente de simulação de futuros OKX:
function main() {
    exchange.IO("simulate", true)

    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")

    var p1 = exchange.GetPositions()
    var p2 = exchange.GetPositions("")

    var tbls = []
    for (var positions of [p1, p2]) {
        var tbl = {type: "table", title: "test GetPosition/GetPositions", cols: ["Symbol", "Amount", "Price", "FrozenAmount", "Type", "Profit", "Margin", "ContractType", "MarginLevel"], rows: []}
        for (var p of positions) {
            tbl.rows.push([p.Symbol, p.Amount, p.Price, p.FrozenAmount, p.Type, p.Profit, p.Margin, p.ContractType, p.MarginLevel])
        } 
        tbls.push(tbl)
    }

    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Quando o parâmetro passou para oexchange.GetPositions()função éETH_USDT.swap, podem ser obtidos os dados de posição dos contratos perpétuos baseados em U da ETH.

img

Quando o parâmetro passou para oexchange.GetPositions()A função é uma cadeia vazia , os dados de posição de todos os contratos baseados em U podem ser obtidos.

2. Atualização da interface API

Atualizar a função Exchange.GetTicker

A principal melhoria da função de mercadoexchange.GetTicker()A função permite solicitar dados de mercado diretamente de acordo com as informações do produto especificadas pelo parâmetro sem o par de negociação atual e o código do contrato. Simplifica o processo de escrita do código. Ao mesmo tempo, ainda é compatível com o método de chamada sem passar parâmetros e é compatível com a velha estratégia da plataforma na maior extensão.

O parâmetrosymbolO valor da posição em risco deve ser calculado de acordo com o método de classificação da posição em risco.exchange:

  • Objeto de troca spot O formato é:AAA_BBB, AAA representa baseCurrency, ou seja, moeda de negociação, e BBB representa quoteCurrency, ou seja, moeda de fixação de preços. Por exemplo: par de negociação spot BTC_USDT.
  • Objeto de troca de futuros O formato é:AAA_BBB.XXX, AAA representa baseCurrency, ou seja, moeda de negociação, BBB representa quoteCurrency, ou seja, moeda de preços, e XXX representa código de contrato, como swap de contrato perpétuo. Por exemplo: BTC_USDT.swap, contrato perpétuo baseado em U do BTC. Testado usando o ambiente Binance Futures:
var symbols = ["BTC_USDT.swap", "BTC_USDT.quarter", "BTC_USD.swap", "BTC_USD.next_quarter", "ETH_USDT.swap"]

function main() {
    exchange.SetCurrency("ETH_USD")
    exchange.SetContractType("swap")

    var arr = []
    var t = exchange.GetTicker()
    arr.push(t)

    for (var symbol of symbols) {
        var ticker = exchange.GetTicker(symbol)
        arr.push(ticker)
    }

    var tbl = {type: "table", title: "test GetTicker", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []}
    for (var ticker of arr) {
        tbl.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume])
    }

    LogStatus("`" + JSON.stringify(tbl) +  "`")
    return arr
}

img

O pedido de um lote de dados de mercado para um símbolo especificado tornou-se muito mais simples.

Atualizar a função GetDepth

Semelhante à função GetTicker, oexchange.GetDepth()A função também adiciona um parâmetro de símbolo. Isso nos permite especificar diretamente o símbolo ao solicitar dados de profundidade.

Testado usando o ambiente Binance Futures:

function main() {
    exchange.SetCurrency("LTC_USD")
    exchange.SetContractType("swap")

    Log(exchange.GetDepth())
    Log(exchange.GetDepth("ETH_USDT.quarter"))
    Log(exchange.GetDepth("BTC_USD.swap"))
}

img

Atualizar a função Exchange.GetTrades

Semelhante à função GetTicker, oexchange.GetTrades()A função também adiciona um parâmetro de símbolo, o que nos permite especificar o símbolo diretamente ao solicitar dados de transações de mercado.

Testado usando o ambiente Binance Futures:

function main() {
    var arr = []
    var arrR = []
    var symbols = ["LTC_USDT.swap", "ETH_USDT.quarter", "BTC_USD.swap"]    

    for (var symbol of symbols) {
        var r = exchange.Go("GetTrades", symbol)
        arrR.push(r)
    }

    for (var r of arrR) {
        arr.push(r.wait())
    }
    
    var tbls = []
    for (var i = 0; i < arr.length; i++) {
        var trades = arr[i]
        var symbol = symbols[i]

        var tbl = {type: "table", title: symbol, cols: ["Time", "Amount", "Price", "Type", "Id"], rows: []}
        for (var trade of trades) {
            tbl.rows.push([trade.Time, trade.Amount, trade.Price, trade.Type, trade.Id])
        }

        tbls.push(tbl)
    }

    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Esta actualização é também compatível com o parâmetro de símbolo especificado peloexchange.Go()função quando se chama a interface API da plataforma simultaneamente.

Atualizar a função Exchange.GetRecords

A função GetRecords foi muito ajustada desta vez. Além de suportar o parâmetro de símbolo para especificar diretamente a informação de tipo dos dados de linha K solicitados, o parâmetro de período original é mantido para especificar o período de linha K e um parâmetro de limite é adicionado para especificar o comprimento de linha K esperado ao solicitar. Ao mesmo tempo, também é compatível com a versão antiga da função GetRecords que só passa no parâmetro de período.

O método de chamada deexchange.GetRecords()função é:

  • troca.GetRecords ((() Se não forem especificados parâmetros, são solicitados os dados de linha K do produto correspondentes ao código do par de negociação/contrato corrente.
  • troca.GetRecords ((60 * 15) Quando apenas for especificado o parâmetro do período da linha K, são solicitados os dados da linha K do produto correspondentes ao par de negociação/código do contrato em curso.
  • exchange.GetRecords ((BTC_USDT.swap) Quando apenas as informações do produto são especificadas, são solicitados os dados da linha K do produto especificado.
  • exchange.GetRecords ((BTC_USDT.swap, 60 * 60) Especificar as informações sobre o produto e o período específico da linha K para solicitar dados da linha K.
  • exchange.GetRecords ((BTC_USDT.swap, 60, 1000) Especificar as informações sobre o produto, o período específico de linha K e o comprimento de linha K esperado para solicitar dados de linha K. Observe que, quando o parâmetro limite excede o comprimento máximo de uma única solicitação da exchange, uma solicitação de chamada será gerada (ou seja, várias chamadas para a interface de linha K da exchange).

Testado usando o ambiente Binance Futures:

function main() {
    exchange.SetCurrency("ETH_USDT")
    exchange.SetContractType("swap")
    
    var r1 = exchange.GetRecords()
    var r2 = exchange.GetRecords(60 * 60)
    var r3 = exchange.GetRecords("BTC_USDT.swap")
    var r4 = exchange.GetRecords("BTC_USDT.swap", 60)
    var r5 = exchange.GetRecords("LTC_USDT.swap", 60, 3000)

    Log("r1 time difference between adjacent bars:", r1[1].Time - r1[0].Time, "Milliseconds, Bar length:", r1.length)
    Log("r2 time difference between adjacent bars:", r2[1].Time - r2[0].Time, "Milliseconds, Bar length:", r2.length)
    Log("r3 time difference between adjacent bars:", r3[1].Time - r3[0].Time, "Milliseconds, Bar length:", r3.length)
    Log("r4 time difference between adjacent bars:", r4[1].Time - r4[0].Time, "Milliseconds, Bar length:", r4.length)
    Log("r5 time difference between adjacent bars:", r5[1].Time - r5[0].Time, "Milliseconds, Bar length:", r5.length)
}

img

Atualizar a função Exchange.GetOrders

A função GetOrders também adicionasymbolParâmetros, que podem especificar o tipo das ordens não concluídas atuais (ordens pendentes) diretamente a serem consultadas; também suporta a consulta de todas as ordens pendentes (independentemente do tipo); e é compatível com o método de chamada original.

Oexchange.GetOrders()A função pode ser chamada das seguintes maneiras:

  • troca.GetOrders ((() Consultar todas as ordens não concluídas para o código do par de negociação/contrato em curso.
  • exchange.GetOrders ((BTC_USDT.swap) Consultar todas as ordens em aberto para contratos perpétuos com margem USDT em BTC.
  • troca.GetOrders("") Consultar todas as ordens inacabadas na dimensão atual da exchange (divididas de acordo com a dimensão da interface API da exchange).

Teste utilizando o ambiente de simulação de futuros OKX:

function main() {
    exchange.IO("simulate", true)

    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")

    // Write to chart
    var tbls = []
    for (var symbol of ["null", "ETH_USDT.swap", ""]) {
        var tbl = {type: "table", title: symbol, cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}

        var orders = null
        if (symbol == "null") {
            orders = exchange.GetOrders()
        } else {
            orders = exchange.GetOrders(symbol)
        }

        for (var order of orders) {
            tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
        }

        tbls.push(tbl)
    }
    
    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Quando não forem transmitidos parâmetros, a solicitação por defeito é para todas as ordens pendentes não concluídas do atual par de negociação BTC_USDT e do contrato perpétuo de swap.

img

Quando oETH_USDT.swapSe o parâmetro for especificado, são solicitadas todas as ordens pendentes do contrato perpétuo do par de negociação ETH_USDT.

img

Quando uma cadeia vazia""Se o pedido for aprovado, todas as ordens não concluídas de todos os contratos com margem USDT são solicitadas.

Atualizar função exchange.GetPosition

Ainda é compatível com a antiga função de nomeação de aquisição de posição e também adiciona o parâmetro de símbolo, que pode especificar as informações de tipo dos dados de posição específicos solicitados. O uso desta função é exatamente o mesmo queexchange.GetPositions().

Atualizaçãoexchange.IOfunção

Paraexchange.IO("api", ...)chamadas de funções, todos os objetos de troca foram atualizados para suportar a passagem direta de endereços de solicitação completos. Por exemplo, se você quiser chamar a interface OKX:

// GEThttps://www.okx.com/api/v5/conta/max-withdrawal ccy: BTC

Suporta gravação direta para o endereço basehttps://www.okx.comsem ter que mudar o endereço de base primeiro e depois chamar a função IO.

Teste utilizando o ambiente de simulação de futuros OKX:

function main() {
    exchange.IO("simulate", true)

    return exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC")
}

img

3. Impacto da interface API

Afeta a função exchange.GetOrder

Esta actualização afecta principalmente o parâmetroiddoexchange.GetOrder(id)O parâmetro id é alterado do id de ordem de troca original para um formato de cadeia contendo o produto de negociação. Todos os IDs de encapsulamento de pedidos na plataforma FMZ estão neste formato.

Por exemplo:

  • O ID de ordem original da troca definido na ordem de troca é:123456Antes desta atualização, se você quiser chamar a função GetOrder, a ordem Id passado é123456.
  • Código do produto designado pela bolsa definida na ordem de troca:BTC-USDT- Não. Observe que isso se refere ao código do produto de negociação nomeado pela bolsa, e não ao par de negociação definido pela plataforma FMZ.

Após esta atualização, o formato do parâmetro id que precisa ser passado para oexchange.GetOrder(id)A função é ajustada para:BTC-USDT,123456.

Primeiro, deixe-me explicar por que este projeto é feito: Como a função CreateOrder foi atualizada para especificar o tipo de ordem diretamente (o tipo de ordem colocada pode ser diferente do par de negociação atualmente definido e do código do contrato). Se o ID de ordem devolvido não conter as informações de tipo, então esse ID de ordem será inutilizável. Porque ao verificar a ordem, não sabemos para que tipo (contrato) é a ordem. A maioria das bolsas requer a especificação de parâmetros que descrevem o código de tipo ao verificar e cancelar ordens.

Como ser compatível com este impacto: Se utilizar oexchange.IOA função para chamar a interface de ordem de troca diretamente para fazer uma ordem, o valor de retorno geralmente contém o símbolo original da troca (código de produto) e o id de ordem original. Da mesma forma, se você usar a interface de encapsulamento de pedidos da plataforma FMZ para fazer um pedido, uma vez que o início do ID da ordem é o código do produto de negociação, se você precisar usar o ID de pedido original, basta excluir o código do produto e a vírgula.

Afeta a função Exchange.CancelOrder.

O impacto desta actualização naexchange.CancelOrder()função é a mesma que aexchange.GetOrder() function.

Afeta a função de troca.

O impacto desta actualização naexchange.Buy()função é a mesma que aexchange.GetOrder()função. O ID de encomenda devolvido peloexchange.Buy()função é uma nova estrutura, por exemplo, o ID devolvido ao colocar uma ordem de futuros na bolsa OKX é:LTC-USDT-SWAP,1578360858053058560.

Afeta a função de troca.

O impacto desta actualização naexchange.Sell()função é a mesma que aexchange.GetOrder()função. O ID de encomenda devolvido peloexchange.Sell()função é uma nova estrutura, por exemplo, o ID devolvido ao colocar uma ordem de futuros na bolsa OKX é:ETH-USDT-SWAP,1578360832820125696.

4. Adaptação estrutural

Estrutura do tick

Esta atualização adiciona um campo Símbolo à estrutura do Ticker, que registra as informações de mercado da estrutura atual do Ticker. O formato deste campo é exatamente o mesmo que o formato do parâmetro de símbolo doexchange.GetTicker() function.

Estrutura de ordem

Esta atualização adiciona um campo Símbolo à estrutura da Ordem, e o formato deste campo é exatamente o mesmo que o formato do parâmetro de símbolo doexchange.GetTicker()função. Esta actualização modifica igualmente o campo ID da estrutura de encomendas, registando as informações do produto e as informações originais do pedido no novo formato ID da encomenda.exchange.GetOrder()O que não vou repetir aqui.

Estrutura da posição

Esta atualização adiciona um campo Símbolo para a estrutura Posição.exchange.GetTicker() function.

5. Sistema de testes de retrocesso

Para atender às necessidades dos usuários, esta atualização será primeiro compatível com a negociação ao vivo, e o sistema de backtesting será adaptado dentro de uma semana.

Atualizações suplementares

1. Novos campos de participação e UPnL na estrutura da conta

Os campos deAccountestrutura devolvida peloGetAccountA função de membro do objecto de troca de futuros foi ampliada.

  • Capital próprio A taxa de juros é a taxa de juros de um ativo de margem, que é a taxa de juros de um ativo de margem.

  • UPnL O lucro e a perda não realizados de todas as posições detidas na moeda do ativo de margem corrente.

2. Função SetMarginLevel atualizada para suportar o parâmetro de símbolo

A função membro SetMarginLevel do objeto de troca de futuros foi atualizada e o símbolo do parâmetro foi adicionado.

Exemplo de ensaio:

function main() {
    exchange.SetCurrency("ETH_USDT")
    exchange.SetContractType("swap")
    
    // The current trading pair is ETH_USDT, the contract code is swap, and the leverage value is set to 10
    exchange.SetMarginLevel(10)
    
    // Directly specify the trading pair BTC_USDT, contract code swap, and set the leverage value to 20
    exchange.SetMarginLevel("BTC_USDT.swap", 20)
}

Mais.