Melhores Práticas
Hábitos que mantêm a sua integração com a Deriv API robusta, eficiente e resiliente. Aplique-os em conjunto com a referência por endpoint.
Gestão de ligações
Abra uma única ligação WebSocket e reutilize-a para cada pedido e subscrição, em vez de abrir uma ligação por chamada. Multiplexe pedidos através do socket partilhado e associe cada resposta ao respetivo pedido utilizando req_id.
Quando a ligação cair, restabeleça-a com recuo exponencial (por exemplo, 1s, 2s, 4s, 8s, com limite máximo) mais um pequeno jitter, em vez de tentar novamente em ciclo fechado. Envie um ping periódico para manter a ligação ativa e detetar desconexões silenciosas antecipadamente.
Para uma ligação autenticada, peça um novo URL de OTP antes de cada reconexão. Cada URL só funciona uma vez.
// keepalive: send a ping on an interval over the shared socket
setInterval(() => socket.send(JSON.stringify({ ping: 1 })), 30000);Limitação de taxa e throttling de pedidos
Limite as solicitações de saída para permanecer dentro dos limites de taxa da API. Coloque as chamadas em fila e regule o seu ritmo em vez de enviar grandes volumes de uma só vez, e utilize debounce nas ações iniciadas pelo utilizador para que uma única interação não gere múltiplos pedidos.
Se atingir o limite de taxa, recue de forma exponencial antes de tentar novamente, aumentando o intervalo após cada rejeição. Prefira subscrições em vez de polling para dados que se atualizam continuamente, para que o servidor envie as alterações em vez de as ter de solicitar novamente.
Pode reconciliar transferências e levantamentos do agente de pagamentos por ID do pedido. Envie um request_id único com cada um e, se a resposta se perder, verifique o respetivo resultado com Transfer status ou Withdrawal status em vez de o enviar novamente. Uma compra não tem consulta por ID do pedido: req_id apenas associa uma resposta ao respetivo pedido. Para evitar uma compra duplicada, compre por ID de proposta: não é possível comprar duas vezes o mesmo ID de proposta.
Para os valores em si — os limites de pedidos por IP e por conta, e os orçamentos partilhados pelos grupos de chamadas WebSocket — consulte Limites.
Autenticação e gestão de tokens
Peça um URL WebSocket autenticado com POST /trading/v1/options/accounts/{accountId}/otp. Envie o seu token no cabeçalho Authorization: Bearer. Consulte a documentação de Opções WebSocket para obter mais detalhes.
Adicione o cabeçalho Deriv-App-ID quando utilizar um token de acesso pessoal (PAT). Os tokens de acesso OAuth 2.0 não precisam deste cabeçalho. Consulte o guia de autenticação para obter mais detalhes.
Ligue-se diretamente ao URL em data.url. O URL contém uma palavra-passe de utilização única (OTP), pelo que não precisa de enviar uma mensagem de autenticação após estabelecer a ligação.
A palavra-passe de utilização única é válida durante 120 segundos e só funciona uma vez. Peça um novo URL de OTP antes de cada reconexão.
Utilize tokens com o menor nível de privilégios exigido pela tarefa, pedindo apenas os âmbitos de que os seus endpoints necessitam, como trade ou account_manage; um token sem um âmbito obrigatório é rejeitado com um erro 403.
Para aplicações direcionadas ao utilizador, utilize o OAuth fluxo Authorization Code 2.0 com PKCE em vez de incorporar tokens. Efetue sempre a troca de tokens no seu back-end, e não no navegador, e valide o parâmetro state no callback antes de utilizar o código de autorização. Os códigos de autorização são de utilização única e de curta duração, pelo que deve trocá-los imediatamente e nunca os armazenar nem registar. Gere um code_verifier e state novos para cada pedido e elimine-os assim que a troca for bem-sucedida. Os tokens de acesso expiram após o número de segundos indicado em expires_in. Deriv não emite tokens de atualização, pelo que deve executar novamente o fluxo de autorização quando um token expira ou uma chamada devolve um erro 401. Se um novo token de acesso também receber um 401, não inicie novamente o fluxo. Em vez disso, verifique o Authorization cabeçalho e o endpoint. Consulte o OAuth guia 2.0 para obter a implementação completa.
Nunca incorpore tokens de API de longa duração em código do lado do cliente, repositórios públicos ou artefactos de compilação. Armazene os segredos do lado do servidor, rode-os regularmente e revogue qualquer token que possa ter sido exposto.
// Run this on your server, or in the browser only with a short-lived OAuth 2.0 access token.
// Never ship a Personal Access Token (PAT) in client-side code.
async function connectAuthenticated(accountId, token) {
const response = await fetch(
`https://api.derivws.com/trading/v1/options/accounts/${accountId}/otp`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
// Add this header for PAT authentication only:
// "Deriv-App-ID": "<app-id>",
},
}
);
if (!response.ok) {
throw new Error(`OTP request failed (${response.status})`);
}
const result = await response.json();
const url = result?.data?.url;
if (!url) {
throw new Error("OTP response did not include a WebSocket URL");
}
return new WebSocket(url);
}
connectAuthenticated("<account-id>", "<token>");
// Request a fresh OTP URL before every reconnect.Tratamento de erros e limpeza de subscrições
Verifique sempre o campo error em cada resposta antes de utilizar os seus dados, e registe o código e a mensagem de erro no seu próprio sistema de logging. Associe as respostas aos pedidos utilizando req_id para que uma falha seja atribuída à chamada correta.
Cancele as subscrições de que já não necessita: utilize forget com um id de subscrição para interromper um único fluxo, e forget_all por tipo de fluxo para interromper todos os fluxos desse tipo. A limpeza evita subscrições perdidas e tráfego desnecessário.
// stop a single stream by its subscription id
socket.send(JSON.stringify({ forget: subscriptionId }));
// stop every stream of a given type
socket.send(JSON.stringify({ forget_all: "ticks" }));Ciclo de vida do contrato
Uma transação percorre um ciclo de vida curto: solicite um preço com proposal, execute-o com buy, acompanhe a posição aberta com proposal_open_contract e feche-a com sell ou deixe-a liquidar no vencimento. Compre com base numa proposta recente em vez de uma cotação desatualizada — os preços têm curta duração. Passe um preço máximo na chamada buy para que as variações entre a cotação e a execução não resultem numa execução menos favorável.
Acompanhe cada contrato aberto subscrevendo proposal_open_contract em vez de fazer polling a portfolio. A subscrição envia atualizações de preço à vista e de lucro e altera os indicadores is_sold e is_expired no momento em que o contrato é liquidado.
Quando is_sold se tornar verdadeiro, chame forget nessa subscrição para libertar o fluxo e evitar a acumulação de subscrições ao longo do tempo.
A compra resposta com um objeto error significa que não foi criado nenhum contrato. Se a resposta se perder ou exceder o tempo limite, verifique statement antes de enviar a compra novamente. Solicite action_type buy, uma date_from imediatamente anterior ao envio e description definido como 1. Faça corresponder a linha pelo respetivo ID da aplicação, montante, shortcode e hora da transação e, em seguida, siga o respetivo contract_id com proposal_open_contract.
statement lista cada compra executada assim que é confirmada, pelo que a ausência de uma linha correspondente significa que não foi comprado nenhum contrato. req_id apenas associa uma resposta ao respetivo pedido. Não é possível comprar duas vezes um ID de proposta, mas uma compra com parâmetros não é desduplicada, pelo que enviar buy: 1 novamente pode abrir um segundo contrato. Por esse motivo, comprar por ID de proposta é a opção mais segura.
Antes de fechar antecipadamente, verifique os indicadores do próprio contrato — utilize sell apenas quando is_valid_to_sell for verdadeiro, e utilize cancel apenas dentro da janela de cancelamento de negociação para transações suportadas. Para os tipos de contrato suportados, defina o stop loss e o take profit com contract_update para que as saídas ocorram do lado do servidor, em vez de monitorizar o fluxo e vender manualmente.
// track an open contract, then release the stream once it settles
socket.send(JSON.stringify({
proposal_open_contract: 1,
contract_id: contractId,
subscribe: 1,
}));
// on each update, when data.proposal_open_contract.is_sold is true:
// socket.send(JSON.stringify({ forget: subscriptionId }));Paginação
Para endpoints que devolvem listas, solicite os dados em páginas em vez de obter tudo de uma só vez. Utilize os parâmetros limit e offset para percorrer os resultados, e mantenha os tamanhos de página moderados para reduzir a latência e a pressão na memória.
Continue a solicitar páginas subsequentes até que uma página devolva menos linhas do que o limit que pediu, o que indica que chegou ao fim do conjunto de dados.
Alguma outra questão? Entrar em contacto