[TOC]
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.
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
}
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)
}
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.
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:
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) + "`")
}
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.
Observe que os dois nomes de função diferem apenas pelo último s. Como GetPositions é mais semanticamente correto, recomenda-se usar GetPositions no futuro.
Oexchange.GetPositions()
A função tem três formas de chamada:
troca.GetPositions ((() Quando nenhum parâmetro é transmitido, os dados de posição de todas as variedades na dimensão corrente são solicitados de acordo com as configurações dopar de negociação / Código do contrato.
Transferência.GetPositions ((BTC_USD.swap
, ETH_USDT.swap
, ETH_USDT.quarter
, etc.
BTC_USD.swap: contrato perpétuo baseado em moeda do BTC
Transferência.GetPositions ((
Algumas divisões especiais de dimensão dos contratos de câmbio:
USDT.futures_combo: Contrato de combinação de spread da bolsa Deribit.
USD.futures_ff: Contrato de entrega de margem mista da Bolsa de Futures_Kraken.
USD.swap_pf: Futures_Kraken exchange
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("BTC_USDT.swap")
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) + "`")
}
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
Quando os parâmetros doexchange.GetPositions()
Os dados de posição de todos os contratos perpétuos baseados em U listados na bolsa podem ser obtidos (porque o par de negociação atual é BTC_USDT e o contrato é swap, a solicitação é baseada no par de negociação atual e no intervalo de dimensão do contrato).exchange.GetPositions("USDT.swap")
e especificar um intervalo de solicitação.
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âmetrosymbol
O valor da posição em risco deve ser calculado de acordo com o método de classificação da posição em risco.exchange
:
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.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 BTCvar 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
}
O pedido de um lote de dados de mercado para um símbolo especificado tornou-se muito mais simples.
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"))
}
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) + "`")
}
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.
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 é:
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)
}
A função GetOrders também adicionasymbol
Parâmetros, que podem ser usados para especificar um símbolo específico e consultar as ordens inacabadas (ordens pendentes) desse símbolo; também suporta consultar as ordens inacabadas (ordens pendentes) de todos os símbolos na faixa de dimensões especificada.
Oexchange.GetOrders()
A função pode ser chamada das seguintes maneiras:
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", "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) + "`")
}
Quando não forem transmitidos parâmetros, são solicitadas ordens inacabadas (ordens pendentes) de todas as variedades na faixa de dimensões do par de negociação atual (BTC_USDT) e código do contrato (swap).
Quando o parâmetroETH_USDT.swap
Se for especificado, são solicitadas ordens inacabadas (ordens pendentes) do contrato perpétuo baseado em USDT do ETH
Quando a corda"USDT.swap"
Se o pedido for aprovado, são solicitadas as ordens inacabadas (ordens pendentes) de todos os contratos perpétuos baseados em USDT.
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()
.
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.com
sem 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")
}
Esta actualização afecta principalmente o parâmetroid
doexchange.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:
123456
Antes desta atualização, se você quiser chamar a função GetOrder, a ordem Id passado é123456
.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.
O impacto desta actualização naexchange.CancelOrder()
função é a mesma que aexchange.GetOrder()
function.
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
.
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
.
Somente os objetos de troca de futuros suportam essa função. Para a função exchange.GetPosition() para obter dados de posição, um novo nome exchange.GetPositions() é adicionado, e os dois comportamentos são exatamente os mesmos.
Definição antiga: a função exchange.GetPosition(, quando chamada sem especificar quaisquer parâmetros, obtém os dados de posição do contrato específico definido pelo par de negociação atual e código do contrato. Após ajuste e modificação, a nova definição: função exchange.GetPosition(), quando chamada sem especificar quaisquer parâmetros, obtém as posições de todas as variedades na faixa de dimensões determinada pelo par de negociação e código de contrato atualmente definidos.
Por exemplo, o par de negociação atual é BTC_USDT e o código do contrato é swap.
exchange.GetPosition() // Equivalent to calling exchange.GetPosition("USDT.swap")
Esta função solicita os dados de posição dos contratos perpétuos baseados em U de todas as moedas.
Definição antiga: função exchange.GetOrders(), quando chamada sem especificar nenhum parâmetro, obtém todas as ordens incompletas do par de negociação atual. Após ajuste e modificação, a nova definição é: função exchange.GetOrders(), quando chamada sem especificar quaisquer parâmetros, obtém as ordens incompletas de todos os pares de negociação spot.
Definição antiga: função exchange.GetOrders(), quando chamada sem especificar quaisquer parâmetros, obtém todas as ordens não concluídas do contrato específico definido pelo par de negociação atual e código do contrato. Após ajuste e modificação, a nova definição é: função exchange.GetOrders(), quando chamada sem especificar quaisquer parâmetros, obtém todas as ordens incompletas da faixa de dimensão determinada pelo par de negociação atual e código do contrato.
Por exemplo, o par de negociação atual é BTC_USD e o código do contrato é quarto.
exchange.GetOrders() // Equivalent to calling exchange.GetOrders("USD.futures")
Esta função solicita os dados de ordens em aberto de todos os contratos futuros baseados em moedas.
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.
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.
Esta atualização adiciona um campo Símbolo para a estrutura Posição.exchange.GetTicker()
function.
De acordo com a atualização da interface API da estratégia da plataforma, o sistema de backtesting da plataforma foi atualizado de forma síncrona; Além disso, o sistema de backtesting adicionou suporte para:
Os campos deAccount
estrutura devolvida peloGetAccount
A 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.
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)
}
O campoCtValCcy
A unidade de valor de um contrato pode ser: BTC, USD, ETH, etc.
O campoCtVal
registar o valor de um contrato do produto negociado na bolsa, e a unidade é a moeda registada noCtValCcy
- por exemplo:CtVal
é 0,01 eCtValCcy
é