For the complete documentation index, see llms.txt. This page is also available as Markdown.

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 side para as famílias stop e take profit.

  • Validade × tipos condicionais. O contrato não diz quais valores de time_in_force são válidos para os seis tipos de ordem condicionais (por exemplo, PostOnly em uma StopMarket).

  • 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 é permanentemente null hoje. O contrato diz que ele é "atualmente sempre null", com leverage_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/closed aceita apenas limit e cursor, então não há como restringir a consulta a um único mercado. Ele não aceita nem market_id nem symbol. O campo da resposta foi renomeado para symbol na 0.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/closed documenta em limit uma janela retida de 200 registros.

  • 429 ausente nas posições fechadas. GET /positions/closed e seu gêmeo /api/v1 declaram apenas 200 e 401. O contrato omite a resposta 429 que 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

  • direction não é enumerado. POST /account/margin não declara nenhum schema de requisição. Seu exemplo mostra "direction": "add", e o resumo e a descrição do 400 sugerem 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/deposit e POST /account/margin trazem 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/deposit e POST /deposits depositam garantia e retornam DepositResponse, 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, e FundsEntry.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. submitted não tem correspondente em Withdrawal, e settled não tem correspondente em FundsEntry.

  • A caixa do nível de limite de requisições é inconsistente. RateLimitStatus.tier é documentado em minúsculas (pro, marketmaker, unlimited). O exemplo do corpo de 429 retorna "tier": "Pro". As operações administrativas de gestão de níveis usam MarketMaker e Pro. 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 apenas 200 e 401: 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_30d não faz mais parte desta lacuna: volume_30d_estimated informa qual garantia se aplica.

  • Os máximos de limit são menores do que o texto em dois lugares. GET /withdrawals e GET /deposits limitam limit a 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 aceita cursor.

  • 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 a PortfolioPoint.equity e 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 é sempre base, discounts está sempre vazio e FeeDiscount não tem propriedades definidas. As taxas efetivas por mercado dos mercados presentes no buffer de execuções retido atualmente vêm em markets. 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 tratar schedule como uma string aberta e distinguir per_market, reference e o sentinela unknown de valor zero.

  • Position.leverage é permanentemente null hoje em toda resposta que incorpora uma posição (AccountSummary, AccountState), com leverage_error: "margin_state_not_mirrored". Consulte GET /positions.

Atualizado