Lacunas conhecidas
Lacunas e inconsistências no contrato da API, sinalizadas em vez de preenchidas.
Esta página é uma lista do que o contrato não diz. As páginas de endpoint da seção Referência são geradas a partir do openapi.json e descrevem o que o contrato declara e nada mais. Onde o contrato é omisso, ambíguo ou internamente inconsistente, esta página registra isso em vez de preencher a lacuna com um texto plausível.
Leia-a antes de desenvolver com base em uma operação cujo comportamento você está deduzindo em vez de ler.
Cada item fica sob a parte da API a que pertence. Nada aqui é um compromisso de roadmap. São observações sobre o contrato como ele está hoje.
Linha de base verificada contra a especificação 0.9.90, e cada entrada abaixo é verificada de novo a cada nova versão da especificação por .github/scripts/known_gaps_check.py. Cada entrada registra um predicado contra o contrato em known-gaps-assertions.json. Quando um predicado deixa de valer, a lacuna foi preenchida, e o CI falha até que a entrada seja removida. Entradas que afirmam algo sobre o texto, e não sobre a estrutura, são marcadas como verificadas manualmente e trazem a versão da especificação contra a qual foram lidas pela última vez, que o mesmo gate exige que se mantenha atualizada.
Uma lista de lacunas desatualizada é pior do que nenhuma lista. Entre 0.9.27 e 0.9.63 esta ficou desatualizada. Oito entradas estavam erradas, e três delas descreviam lacunas que o contrato já tinha fechado. É por isso que a verificação agora é mecânica, e não uma promessa de reler.
Negociação
Limites de lote. Nenhum tamanho máximo de lote é declarado para
POST /orders/batch, e o contrato não diz como um lote é contabilizado no limite de requisições (uma requisição, ou uma por elemento).reduce_only. Declarado como booleano sem descrição. Sua interação com os tipos de ordem condicionais e trailing não é especificada.Semântica dos campos de
PreviewResponse. Os oito campos têm tipo, mas não têm descrição no contrato.Direção do disparo. "Adversa" e "favorável" não são definidas formalmente por
sidepara as famílias stop e take profit.Validade × tipos condicionais. O contrato não diz quais valores de
time_in_forcesão válidos para os seis tipos de ordem condicionais (por exemplo,PostOnlyem umaStopMarket).Possibilidade de edição. Além de "ordens de liquidação não podem ser editadas", o contrato não diz se ordens condicionais ou trailing podem ser editadas, nem se uma edição pode alterar
time_in_force.Remoção de
stop_price. Marcado como descontinuado sem versão ou data de remoção informadas.
Posições
leverageé permanentementenullhoje. O contrato diz que ele é "atualmente semprenull", comleverage_error: "margin_state_not_mirrored", e não dá prazo para preenchê-lo. Os clientes não conseguem ler a alavancagem por posição nesses endpoints.Sem filtro por mercado nas posições fechadas.
GET /positions/closedaceita apenaslimitecursor, então não há como restringir a consulta a um único mercado. Ele não aceita nemmarket_idnemsymbol. O campo da resposta foi renomeado parasymbolna0.9.74, e o parâmetro nunca existiu com nenhum dos dois nomes.Janela de retenção não informada.
funding_paidé documentado como "limitado pelo histórico de financiamento que o indexador retém", mas nenhum período de retenção é informado. A paginação por cursor nesses endpoints não faz mais parte desta lacuna:GET /positions/closeddocumenta emlimituma janela retida de 200 registros.429ausente nas posições fechadas.GET /positions/closede seu gêmeo/api/v1declaram apenas200e401. O contrato omite a resposta429que a outra operação de posições declara, embora a mesma camada de limite de requisições se aplique.Somente margem cruzada.
initialMarginé definido "sob o modelo de margem cruzada do motor", e o contrato observa que o indexador não espelha alocações de margem isolada/personalizada. Então a alocação real de uma posição com margem isolada não pode ser lida aqui.Sem contagem ou total de posições abertas. A resposta é um array simples, sem envelope e sem paginação em
GET /positions, então não há um limite documentado de quantas posições uma única resposta pode trazer.
Conta
directionnão é enumerado.POST /account/marginnão declara nenhum schema de requisição. Seu exemplo mostra"direction": "add", e o resumo e a descrição do400sugerem que a remoção é suportada, mas o contrato nunca informa o valor para remoção. Também não nomeia os tipos dos campos nem marca nenhum campo como obrigatório.Duas operações não declaram schema de requisição.
POST /account/depositePOST /account/margintrazem apenas exemplos de requisição, então clientes gerados a partir do contrato recebem corpos de requisição sem tipo para as duas. Suas respostas têm tipo (DepositResponse,AdjustMarginResponse); é o lado da requisição que não é declarado.Dois caminhos de depósito sobrepostos.
POST /account/depositePOST /depositsdepositam garantia e retornamDepositResponse, e o contrato não diz qual preferir nem como diferem operacionalmente. Como as respostas são iguais, o formato retornado não permite distinguir um do outro.Os vocabulários de status divergem.
Withdrawal.statusépending/settled/failed, eFundsEntry.statusépending/submitted/confirmed/failed. O mesmo ciclo de vida tem dois conjuntos de nomes e um número diferente de estágios, então não existe um mapeamento completo entre eles.submittednão tem correspondente emWithdrawal, esettlednão tem correspondente emFundsEntry.A caixa do nível de limite de requisições é inconsistente.
RateLimitStatus.tieré documentado em minúsculas (pro,marketmaker,unlimited). O exemplo do corpo de429retorna"tier": "Pro". As operações administrativas de gestão de níveis usamMarketMakerePro. O contrato não informa uma caixa canônica.A cobertura de
429é irregular. Várias operações sujeitas à mesma camada de limite de requisições declaram apenas200e401: as duas operações de histórico de patrimônio, as duas operações de histórico de ordens, os dois GETs e PUTs de cancelamento na desconexão,GET /withdrawals,GET /deposits,POST /deposits,GET /orders/{order_id}e as duas operações de status do limite de requisições.As janelas de retenção são uma contagem de registros, não uma duração. Cada operação agora informa o tamanho da sua janela retida (1.000 execuções, 500 registros de histórico de ordens, 200 posições fechadas, 720 pontos de patrimônio, 10.000 negociações). Nenhuma operação diz até quando isso volta no tempo, então um cliente não consegue saber se uma varredura cobre uma semana ou um ano. A subcontagem de
volume_30dnão faz mais parte desta lacuna:volume_30d_estimatedinforma qual garantia se aplica.Os máximos de
limitsão menores do que o texto em dois lugares.GET /withdrawalseGET /depositslimitamlimita 100, com padrão de 100, então o parâmetro só pode reduzir a página. Não há como paginar além de 100 registros, porque nenhuma das duas operações aceitacursor.EquityPoint.equityé um número JSON. Todos os outros campos monetários desta tag são strings decimais sem perda. O próprio contrato observa a divergência em relação aPortfolioPoint.equitye orienta os clientes a comparar pelo valor decimal, mas a representação em ponto flutuante continua no wire.early_access_allowedé presente-ou-ausente, não verdadeiro-ou-falso. O contrato diz que ele aparece "apenas quando a restrição de acesso antecipado está ativa", sem informar o que controla a restrição nem o que sua ausência significa para quem chama.Sem nível ou programa de desconto por conta.
AccountFees.tieré semprebase,discountsestá sempre vazio eFeeDiscountnão tem propriedades definidas. As taxas efetivas por mercado dos mercados presentes no buffer de execuções retido atualmente vêm emmarkets. A ausência de um mercado não é evidência sobre a negociação ao longo de toda a vida da conta. Quem chama ainda precisa tratarschedulecomo uma string aberta e distinguirper_market,referencee o sentinelaunknownde valor zero.Position.leverageé permanentementenullhoje em toda resposta que incorpora uma posição (AccountSummary,AccountState), comleverage_error: "margin_state_not_mirrored". ConsulteGET /positions.
Atualizado

