Ccxt: Streaming (WS, suporte Websocket): Orderbooks, Trades, Balances...

Criado em 26 jul. 2017  ·  346Comentários  ·  Fonte: ccxt/ccxt

Eu gostaria de ver uma nova propriedade de mercado chamada saldos, que funcionaria da mesma forma que os símbolos. Quando você chama fetchBalances(), a propriedade balances é preenchida com uma matriz associativa de moedas com saldos (livre, usado, total, disponível etc.).

Os saldos também seriam atualizados via websocket (quando disponível) ou por chamadas repetidas à API, dependendo dos limites de taxa.

Em última análise, poderíamos fazer algo como:

kraken.fetchBalances();
let myAvailableBTC = kraken.balance.available['BTC'];
let myTotalBTC = kraken.balance.total['BTC'];
enhancement

Comentários muito úteis

@kroitor como está o progresso?

Vamos ver... Eu postei a resposta acima para satisfazer a multidão exatamente 48 horas atrás.

Desde então, dormi duas vezes por aproximadamente 6 horas, ou seja, 12 horas no total, restando 36 horas.
Também fiz várias refeições e fiz algumas outras coisas que levaram aproximadamente 4 horas no total, restando 32 horas. Eu fiz algum trabalho para ganhar dinheiro para viver, que levou aproximadamente 8 horas de tempo, ninguém, exceto algumas pessoas que doaram (obrigado e respeito a eles), na verdade paga pelo trabalho de código aberto, lembra? ) Então, para ter o que comer, temos que trabalhar em outros projetos também.

Isso nos dá um tempo restante de 32-8 = 24 horas, um dia inteiro para trabalhar em ccxt. Então eu passei aproximadamente 4 horas respondendo como está indo para pessoas diferentes aqui e ali. Isso é 20 horas restantes para o trabalho real. Nesse período, encerrei 20 novos problemas (respondi a eles, alguns deles várias vezes) e juntei aproximadamente 30 solicitações de pull com várias correções de bugs, aprimoramentos e edições na base de código existente. Isso é aproximadamente 20 minutos por uma solicitação de emissão/pull. Alguns deles exigem comunicação intensa e demoram mais, outros fecham mais rápido.

Agora, não consigo imaginar como você poderia ter algum progresso sério nessa questão específica dentro desse prazo. E minha resposta e atitude em relação a esse tipo de pergunta está totalmente expressa neste comentário: https://gist.github.com/kroitor/aabecc346a5bded6ead7a82205d8ffc1#gistcomment -2335076

Basicamente, o progresso deste projeto de código aberto também é aberto, então sempre que você se perguntar como está indo, dê uma olhada no histórico de commits)

Todos 346 comentários

Você terá, em breve) Obrigado por postar!

Nós unificamos a API de balanceamento, conforme escrito aqui, na edição #36 . Agora sua solicitação de recurso pode ser implementada facilmente ) Primeiro, adicionaremos um método de saldo sujo que salvaria o saldo em uma instância de mercado. E quando estivermos prontos para liberar as implementações do Websocket, faremos a atualização automática, é claro. Mantenha contato! )

Então, o "saldo sujo" é um ajuste do livro-razão local para refletir quaisquer pedidos que eu fizer? E quanto aos pedidos que atendem? Isso também está sendo rastreado para os saldos?

Sim, quando adicionamos um poller de taxa limitada e métodos de liberação para apis de websocket, o saldo refletirá tudo em tempo real (o mais real possível). Atualmente, os saldos não são recarregados e não são armazenados em cache automaticamente, você precisa fazer isso manualmente, pois acabamos de unificá-los (isso foi muito trabalho por si só). Mas, tendo-os unificados, em breve adicionaremos também o ajuste automático. Quanto ao preenchimento de pedidos, acho que não entendi completamente sua pergunta, mas uma API de saldo geralmente informa um valor (à esquerda) em pedidos, um saldo disponível gratuito e um total, e geralmente há uma interface separada para detalhes de execução (transações, comércios). Também será baseado em fluxo, basicamente, todos os dados, incluindo saldo, pedidos abertos, pedidos parcialmente preenchidos e pedidos fechados, tudo isso deve ser mutuamente consistente.

Como esse problema ainda está em aberto e tive dificuldade em encontrar mais alguma coisa sobre ele (exceto o problema #145, que está vinculado aqui em fechado): Há algo novo em todo o tópico WebSocket?

@Helmi oi! Este problema ainda está em aberto, estamos trabalhando nele e esperamos entregá-lo em breve. Estamos nos aproximando da v2, como você pode ver em nosso controle de versão, onde introduziremos uma grande refatoração e muitos novos recursos . Fique atento para mais atualizações! )

Obrigado pelo alerta rápido. Isso soa incrível. Vá em frente 👍

+1
Alguma palavra sobre a data de lançamento da versão 2.0?

@alexmipego , estamos trabalhando intensamente para entregar a primeira versão o mais rápido possível, espero que este mês.

Obrigado pelo esforço! Eu sou um fã!

@kroitor você escreveu:

Estamos nos aproximando da v2, como você pode ver em nosso controle de versão, onde introduziremos uma grande refatoração e muitos novos recursos )

Existe uma maneira de dar uma olhada no código v2 e WebSocket e na refatoração principal? Eu não poderia encontrá-lo em nenhum lugar.

Onde o versionamento é gerenciado? Eu não poderia encontrá-lo.

@nitzanav

Existe uma maneira de dar uma olhada no código v2 e WebSocket e na refatoração principal? Eu não poderia encontrá-lo em nenhum lugar.

A refatoração está acontecendo agora na ramificação principal (houve muitas mudanças desde então), e o trabalho em websockets também está a caminho, mas não há um único lugar que contenha tudo agora, o trabalho é feito em forks principalmente ... Aqui está um exemplo disso: https://github.com/ccxt/ccxt/pull/751

Onde o versionamento é gerenciado? Eu não poderia encontrá-lo.

A fonte única da versão é executada em cada compilação no Travis CI de package.json com o script vss.js . Mais sobre isso: https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md.

Obrigado pelas informações e por este projeto incrível!

@kroitor Vai estar disponível nos três idiomas como de costume?

@rubobaquero sim, esse é o ponto, se pudéssemos lançar uma implementação em apenas um único idioma, adicionar suporte para ws não levaria tanto tempo) A principal dificuldade é unificar todos eles.

Quaisquer atualizações da linha do tempo na implementação do websocket.

@GoChartingAdmin sim, estamos no processo de mesclar este PR: https://github.com/ccxt/ccxt/pull/751 , portanto, espere ter as primeiras implementações de um wrapper ws genérico nos próximos dias.

@kroitor Ainda não concluí minha implementação do EtherDelta. Este PR permite a implementação de websocket com todas as operações básicas? Está completo o suficiente para eu dar uma facada nele?

@fredfortier infelizmente ainda não... É uma primeira abordagem, e é

  • não unificado (específico para troca)
  • não portátil (específico do idioma)

Ainda estamos trabalhando na unificação dos WS (essa é a parte mais difícil). Se você quiser se aprofundar na história dos websockets no ccxt, aqui está uma visão geral dele (contém várias outras implementações em JS, que estão mais próximas de um estado unificado): https://gist.github.com/kroitor/7dce1d23a10937ab8c07a5451f17ccf2

Para PHP podemos criar um wrapper em torno de alguma biblioteca, por exemplo: https://github.com/amphp/websocket
O fato é que estaria disponível apenas para PHP 7+ (podemos fazê-lo como sugestão/coisa opcional)

Eu não quero parecer ingrato ou autoritário porque este é um projeto incrível, mas você tem prometido um lançamento habilitado para WS por um tempo.

Talvez você deva criar um projeto no Github para que ele possa ser rastreado mais facilmente para que outros possam contribuir e fazer uma redação bruta da documentação simples da API proposta para que possamos comentar sobre ele para feedback quando for 'mais barato' mudar?

Conheço muito bem a dor de arquitetar coisas demais e não receber feedback cedo.

Pelo que li, o que você está fazendo parece bastante ambicioso e talvez um v3 quando estamos esperando por um v1.

Eu não quero parecer ingrato ou autoritário porque este é um projeto incrível, mas você tem prometido um lançamento habilitado para WS por um tempo.

Estamos fazendo o trabalho principal no código base para entregá-lo o mais rápido possível.

Talvez você deva criar um projeto no Github para que ele possa ser rastreado mais facilmente para que outros possam contribuir e fazer uma redação bruta da documentação simples da API proposta para que possamos comentar sobre ele para feedback quando for 'mais barato' mudar?

Isso é exatamente como pensamos, vamos lançar um subconjunto de trocas primeiro, para que a comunidade possa aprender a partir daí, mas precisamos que ele passe em nossos testes atuais, pelo menos, antes de podermos lançá-lo. Espero sua compreensão.

Conheço muito bem a dor de arquitetar coisas demais e não receber feedback cedo.

Gostaríamos muito de receber o feedback inicial, essa é a razão para fazer o trabalho de preparação agora em primeiro lugar.

Impressionante!

Já que você está falando sobre passar nos testes e eu vejo algum PR para WS, isso deve significar que você decidiu uma implementação, e a API para ela e uso?

Talvez seja uma boa ideia eliminar rapidamente uma seção de rascunho no Manual marcada como WIP para que possamos visualizar e fornecer feedback sobre a API e o uso (se necessário)?

É melhor dizermos agora se achamos que vemos problemas.

Talvez seja uma boa ideia eliminar rapidamente uma seção de rascunho no Manual marcada como WIP para que possamos visualizar e fornecer feedback sobre a API e o uso (se necessário)?

Esta é uma das nossas principais prioridades agora, juntamente com um rascunho da implementação em si. Vamos documentá-lo assim que tivermos um layout de rascunho (wip). Nossa equipe é muito pequena e estamos fazendo o possível para acompanhar o suporte e também adicionar novas funcionalidades. O WS está a caminho, só precisamos de um pouco mais da sua paciência. THX!

Legal, obrigado.

Ainda sugiro que você veja o uso do Github Projects.
Bom para gerenciamento e visibilidade básicos de Roadmap.

Ei pessoal - sou bem novo aqui, mas mergulhei no ccxt nas últimas duas semanas. Se eu puder oferecer uma sugestão sobre o WIP e para satisfazer alguns de nós aqui, castores ansiosos, interessados ​​em colocar nossas mãos em alguma funcionalidade [não testada/não documentada]. Muitos de nós pensam em código e em minha humilde experiência, juntar alguns exemplos de teste simples em um notebook ipython faria maravilhas para satisfazer os dois lados: podemos brincar com alguns exemplos e os contribuidores seniores implicitamente desenvolvem um esboço do conteúdo que 'vai para o WIP e depois para a documentação. Além disso, um benefício muitas vezes ignorado ou desconhecido do github é que ele realmente executa notebooks Jupyter e, portanto, permite que todos se beneficiem de um mini workbench no estilo Quantopia, se você desejar.

De qualquer forma, apenas um pouco de reflexão. Mantenha o bom trabalho.

Existe alguma lista organizada do trabalho do websocket que está em andamento para que outros possam tentar ajudar?

Oi!

@mmehrle

Ei pessoal - sou bem novo aqui, mas mergulhei no ccxt nas últimas duas semanas. Se eu puder oferecer uma sugestão sobre o WIP e para satisfazer alguns de nós aqui, castores ansiosos, interessados ​​em colocar nossas mãos em alguma funcionalidade [não testada/não documentada].

A principal dificuldade nesta tarefa é fornecer algumas funcionalidades em desenvolvimento/não documentadas. Quando o temos em um estado experimental, isso significa que temos tudo (o outro trabalho de lá é trivial). Tê-lo em estado experimental é nossa maior prioridade agora. Basicamente, você está perguntando se é possível fazer 90% do trabalho de pensamento agora, para que os usuários possam fazer os outros 10%. Bem, sim, isso é possível, e é exatamente com isso que estamos ocupados.

@bolsa

Existe alguma lista organizada do trabalho do websocket que está em andamento para que outros possam tentar ajudar?

A principal dificuldade não está em fazer a rotina, mas sim no próprio design portátil e robusto . Vamos publicar o projeto de implementação assim que o tivermos. Se você puder criar um design portátil e robusto adequado agora – seus pensamentos sobre isso são bem-vindos.

@kroitor Primeiro, deixe-me dizer que todos apreciam o trabalho que a equipe está fazendo.

Todos nós estamos pedindo a mesma coisa - basta escrever um rascunho da API que você espera expor no momento para suporte ao websocket, para que possamos ver o que você planeja fornecer e fornecer feedback. É isso.
Você está trabalhando nisso há meses, certamente a primeira coisa que fez foi descobrir os casos de uso e ter uma ideia das adições da API ao CCXT e ao pseudocódigo.

Vamos, os usuários deste módulo, ver isso agora e fornecer feedback.

Este trabalho está em andamento há muitos meses e está bem atrás do cronograma que você continuou oferecendo. Naturalmente, alguns de nós estão cada vez mais desconfiados sobre sua falta de vontade e razões para não compartilhar, e o atraso contínuo, e querem ajudar.

@kroitor Mate, basta adicionar uma seção 'Realtime' ao manual, marcada como WIP, com pseudocódigo mostrando o uso da API proposta, com init/config, fluxo de eventos de exemplo - até mesmo um link para um GIST rápido e sujo, apenas em JS .
Isso funcionará bem por enquanto, para que possamos ver como será como consumidor do módulo CCXT.

Então talvez você deva considerar fazer uma atualização rápida aqui com uma estimativa realista de quando você publicará algo com o qual podemos brincar.
Você não deve nada a ninguém, mas tem muita gente esperando.

Tendo passado por uma situação parecida com a sua, prometendo e não entregando, repetidas vezes, aprendi que é melhor lançar cedo e muitas vezes tudo o que eu tinha, pois as pessoas querem ajudar, e receber feedback antecipado foi muito melhor em termos de engajamento da comunidade, e fazendo mudanças quando eram mais baratas em termos de esforço.

Também estou realmente precisando desse recurso e estou pronto para gastar meu tempo em testes e feedback.

"_A principal dificuldade não está em fazer a rotina, mas sim no design portátil e robusto adequado._ Vamos publicar o rascunho da implementação assim que o tivermos. Se você puder criar um design portátil e robusto adequado, agora - seus pensamentos sobre isso são bem-vindos."

Sim, por mais que eu queira começar a contribuir, eu tenderia a concordar quando se trata dos aspectos de design disso. Não é trivial e será chato redesenhar mais tarde. Até que você resolva tudo isso, permanecemos ansiosos ;-)

@kroitor algum rascunho que eu possa ver agora?

@jjhesk trabalhando para adicionar a especificação ao Manual, conforme solicitado por @TimNZ . Ainda não há projeto de implementação.

Acho que a primeira fase precisaria ser apenas obter as configurações do websocket para serem gerenciáveis ​​em cada configuração JS básica. Porque o estilo a ser implementado em cada linguagem será totalmente diferente. Mas se pudesse ser tratado universalmente apenas para criar o URL certo, isso seria útil. Pensamentos?

@pursehouse nossos pensamentos começaram com isso https://gist.github.com/kroitor/aabecc346a5bded6ead7a82205d8ffc1

Esta é apenas a introdução de uma introdução, todo o capítulo de Streaming e tudo o que se segue será publicado no Manual, espero, em breve. Isso acabará se transformando em uma especificação para suporte de WS, conforme solicitado aqui.

Tem que ser feito de forma compatível em 3 linguagens: JS, Python (2 e 3) e PHP, respeitando estas regras: https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING .md

@kroitor ok, acho que o rascunho está bem completo aqui. Mais uma coisa que precisa ser abordada é o suporte à versão do websocket e seu gerenciamento.

@kroitor como está o progresso?

@kroitor como está o progresso?

Vamos ver... Eu postei a resposta acima para satisfazer a multidão exatamente 48 horas atrás.

Desde então, dormi duas vezes por aproximadamente 6 horas, ou seja, 12 horas no total, restando 36 horas.
Também fiz várias refeições e fiz algumas outras coisas que levaram aproximadamente 4 horas no total, restando 32 horas. Eu fiz algum trabalho para ganhar dinheiro para viver, que levou aproximadamente 8 horas de tempo, ninguém, exceto algumas pessoas que doaram (obrigado e respeito a eles), na verdade paga pelo trabalho de código aberto, lembra? ) Então, para ter o que comer, temos que trabalhar em outros projetos também.

Isso nos dá um tempo restante de 32-8 = 24 horas, um dia inteiro para trabalhar em ccxt. Então eu passei aproximadamente 4 horas respondendo como está indo para pessoas diferentes aqui e ali. Isso é 20 horas restantes para o trabalho real. Nesse período, encerrei 20 novos problemas (respondi a eles, alguns deles várias vezes) e juntei aproximadamente 30 solicitações de pull com várias correções de bugs, aprimoramentos e edições na base de código existente. Isso é aproximadamente 20 minutos por uma solicitação de emissão/pull. Alguns deles exigem comunicação intensa e demoram mais, outros fecham mais rápido.

Agora, não consigo imaginar como você poderia ter algum progresso sério nessa questão específica dentro desse prazo. E minha resposta e atitude em relação a esse tipo de pergunta está totalmente expressa neste comentário: https://gist.github.com/kroitor/aabecc346a5bded6ead7a82205d8ffc1#gistcomment -2335076

Basicamente, o progresso deste projeto de código aberto também é aberto, então sempre que você se perguntar como está indo, dê uma olhada no histórico de commits)

@dmitriz obrigado ! Respondi lá)

Parece que não há como receber
notificações para os novos comentários em Gists,
então eu gostaria de propor mover a discussão aqui,
onde temos esta e outras instalações agradáveis.

Em relação ao comentário @kvdveer em
https://gist.github.com/kroitor/aabecc346a5bded6ead7a82205d8ffc1#gistcomment -2403346
Concordo que cada idioma deve usar seu próprio idioma preferido
e que minhas sugestões são principalmente focadas no JS.

No entanto, seria triste ter a "subclasse" forçada em linguagens que não precisam dela.
Eu acho o código JS baseado em classe muitas vezes muito difícil de entender, porque o encapsulamento é muitas vezes quebrado com classes que se referem a detalhes internos umas das outras cujas definições estão espalhadas por um grande número de arquivos.

Recentemente, me deparei com um ecossistema inteiro de bibliotecas de fluxo ao redor
https://github.com/pull-stream/pull-stream
mantido por @dominictarr (que é um dos contribuidores mais prolíficos da comunidade JS-Node). Tanto o código quanto a API são muito elegantes e simples e não fazem uso de classes.

@kroitor Eu tenho testado sobre o recurso websockets. Eu usei react/ratchet e evenement em php e ws e EventEmitter em javascript. Não sei se isso pode ser uma abordagem válida para ccxt, mas criei exemplos de php e js para conectar o websocket cex e obter atualizações do livro de pedidos, e funciona (muitas coisas para verificar, mas vejo atualizações no log de execução). Se você acha que poderia ser um bom ponto de partida, gostaria de testar o python também.

Desculpe, esqueci o link do github: https://github.com/lfern/ccxt/tree/feature/websockets

@lfern legal, você trabalhou em uma estrutura para as configurações de websocket por troca? Acho que esse foi o verdadeiro obstáculo

@pursehouse Eu tentei colocar todo o código relacionado aos websockets fora do código escrito para cada troca. Desta forma, defini uma classe base AsyncConnection

https://github.com/lfern/ccxt/blob/feature/websockets/js/base/async/async_connection.js

que define apenas estes métodos: connect, close, send e sendJson. Essa classe base herda de EventEmitter e emitirá eventos relacionados a eventos de websockets. Neste teste eu defini três eventos:

  • 'mensagem' quando mensagem recebida da conexão,
  • 'erro' quando o erro ocorreu e
  • 'fechar' quando a conexão é fechada pelo servidor.

Eu defini uma classe filha WebsocketConnection, de AsyncConnection,

https://github.com/lfern/ccxt/blob/feature/websockets/js/base/async/websocket_connection.js

que implementa uma conexão websocket simples (se alguma troca definir um tipo de conexão diferente, você pode definir novas classes filhas de AsyncConnection, como pusher in bitstamp). No Exchange.js você pode capturar esses eventos

https://github.com/lfern/ccxt/blob/feature/websockets/js/base/Exchange.js#L1176

e invocar funções personalizadas definidas em classes de trocas em *.js.

Em cex.js eu defini o método _asyncOnMsg

https://github.com/lfern/ccxt/blob/feature/websockets/js/cex.js#L539

que obtém a mensagem recebida do websocket, analisa-a e faz o que for necessário. Modifiquei a classe Exchange para herdar de EventEmitter também, para que você possa enviar eventos de cex.js. Neste teste eu implementei apenas o processo de livro de pedidos, então quando o método _asyncOnMsg detecta que o livro de pedidos foi recebido, ele processa e emite o evento 'ob'.

https://github.com/lfern/ccxt/blob/feature/websockets/js/cex.js#L563

Este evento pode ser capturado do programa principal para implementar qualquer ação no recebimento. Eu defini o método _asyncSubscribeOrderBook em cex.js

https://github.com/lfern/ccxt/blob/feature/websockets/js/cex.js#L596

que é invocado do método asyncSubscribeOrderBook em Exchange.js. Neste método _asyncSubscribeOrderBook você pode gerar a mensagem a ser enviada ao websocket para fazer a assinatura do livro de pedidos (você definiria para cada troca).

No momento, a estrutura de configuração para conexões assíncronas é assim:

'assíncrono': {
'tipo': 'ws',
'url': ' wss://ws.cex.io/ws/ ',
'wait4readyEvent': 'auth',
},

onde type é o tipo de conexão (Websockets neste caso), url é a url do websocket e wait4readyevent define o evento que você deve esperar até poder assinar ou enviar qualquer comando para o websocket (no cex você deve fazer autenticação antes de enviar qualquer assinatura solicitação). Mas essa estrutura deve ser revisada quando novas conexões assíncronas forem adicionadas. Eu testei em node e php, e parece que pode funcionar.

https://github.com/lfern/ccxt/blob/feature/websockets/examples/js/async-orderbook-cex.js

https://github.com/lfern/ccxt/blob/feature/websockets/examples/php/async_orderbook_cex.php

Acho que poderia ser um bom ponto de partida para implementar websockets em exchanges, mas não quero continuar se você acha que não é.

@lfern parece um bom começo para mim. Eu tentaria tirar esses grandes blocos de instruções if do método cex._asyncOnMsg , se você não quiser que esse método acabe gigante em cada troca a longo prazo. _async_orderBookSubscribe ou o que for...

porque eu acho que idealmente... você teria uma lista de métodos e sua chave websocket para que um método único mais genérico pudesse executar a verificação de dados. Portanto, a configuração de troca teria uma matriz de chaves e seu método correspondente para processar esses dados. Então a classe Exchange seria o único método que precisaria de uma lógica extensa escrita nela para verificar o que fazer com o resultado. Ou até mesmo tê-los 1:1 nomeados
em vez de if( e === 'order-book-subscribe' ) .... , chame algo como cex._async_eventOrderBookSubscribe semelhante ao conceito de mapeamento de método já existente

talvez experimente mais algumas trocas com sistemas de soquetes da web muito diferentes para ver quais problemas/refinamentos surgem.

lembre-se de que um fator-chave será quanto menos código precisa existir por troca que pode ser tratado genericamente

Gostaria de compartilhar esta implementação de websocket para Binance com código totalmente funcional:
https://github.com/zoeyg/binance/issues/57

Uma parte importante é a reutilização de funções e a separação de interesses.
Por exemplo, toda a parte relacionada ao WebSocket é completamente encapsulada nesta função:

// general purpose websocket factory
const WebSocket = require('ws')
const createWS = path => cb => 
  new WebSocket(path).on('message', cb)

O resto são funções puras que podem ser compostas e testadas isoladamente.

@dmitriz Eu não uso streams antes, mas você acha que essa abordagem poderia ser usada em outros tipos de conexões? Bitstamp usa uma conexão Pusher para trades, orderbook e tickers, e no Gemini você tem que se conectar a uma url ws diferente para cada símbolo. Você conhece uma biblioteca semelhante para implementá-lo em pyhton e PHP?

@lfern
URL ws diferente não deve fazer diferença, você apenas compõe a fábrica createWS com outra função adequada getUrl .

Não tenho experiência com Pusher, isso é algum tipo de wrapper em torno do WS?
Então substituiria a fábrica createWS por uma fábrica própria, com a mesma ideia:

const createPusher = (channel, event, key) => cb => 
  new Pusher(....).on(event, cb)

ou algo desse tipo
(Eu não sei a sintaxe exata, mas eles geralmente são semelhantes, então estou apenas inventando.)

Eu não tenho tanta experiência com Python ou PHP
mas o princípio deve ser o mesmo - você cria a função de uso geral
que inscreve sua função de retorno de chamada no fluxo.
Se for geral e reutilizável, você pode isolá-lo bem do resto do código.

@dmitriz @lfern o código do socket não vai dentro da classe exchange, vai nas classes específicas da linguagem. As classes de troca têm apenas informações de configuração e talvez um pouco de lógica específica de troca.
não se preocupe com qual biblioteca nodejs usar, porque essa parte não é relevante para obter a capacidade geral de funcionar.

a chave é fazer com que a estrutura de configuração da classe de troca seja capaz de lidar com qualquer coisa que a variedade de trocas possa lançar nela.

Muito provavelmente faria sentido para a biblioteca apenas suportar a construção/leitura dos dados para os soquetes, não tomar uma decisão sobre qual biblioteca de soquetes usar

@bolsa

o código do soquete não vai dentro da classe de troca, ele vai nas classes específicas da linguagem.

Poderia explicar a quais classes se refere?
A classe Exchange sob /js/base , da qual as trocas herdam, é a específica do idioma? Então, quais classes não são específicas do idioma?

não se preocupe com qual biblioteca nodejs usar, porque essa parte não é relevante para obter a capacidade geral de funcionar.

Concordo que é bom manter essas bibliotecas em um só lugar.
Onde você os colocaria?

a chave é fazer com que a estrutura de configuração da classe de troca seja capaz de lidar com qualquer coisa que a variedade de trocas possa lançar nela.

Se pudermos supor que as exchanges sempre retornam algum JSON, é isso que as funções do receptor serão passadas como argumentos. Ou você quer dizer alguns pós-processamento dos dados com base em determinadas configurações?

Muito provavelmente faria sentido para a biblioteca apenas suportar a construção/leitura dos dados para os soquetes, não tomar uma decisão sobre qual biblioteca de soquetes usar

Na verdade, seria bom usar alguma interface genérica. Como no meu exemplo, onde a assinatura da função tem apenas url e callback , que podem ser encaixados em qualquer outra biblioteca de soquetes.
Talvez alguma abstração de objeto source contendo todas as informações necessárias para recuperar o fluxo?

Mas no final, a biblioteca ainda terá que escolher qual lib de soquete usar, não é?

Apenas as classes como binance ou gdax não são específicas do idioma. Os outros são específicos do idioma.

O que é necessário é uma estrutura de configuração/método que possa existir em cada classe de troca que criaria os dados necessários para criar uma conexão de soquete. Ou seja, o URL e os dados de postagem/obtenção em potencial incluídos. Em seguida, outro conjunto de regras/métodos para analisar os dados que retornam em cada ciclo desses websockets.

Existem muitos conceitos de qual biblioteca específica baseada em eventos alguém quer/precisa usar, então ter esses recursos para fazer o manuseio simples de preencher as informações de conexão do soquete e processar os resultados dessa conexão faz com que possa haver um específico ou barragem de diferentes bibliotecas de soquete implementadas para uso. Porque você ainda precisa implementar código para processar esses dados.

$exchange = new \ccxt\binance();
$socketInfo = $exchange->getSocket( $someIdeaOfParams );
$socketLibrary = \SomeSocketLib();

\Amp\Loop::run( function () use ( $streamsUrl, $exchange ) {
$connection = $socketLibrary->open( $socketInfo['url'], $socketInfo['post'] );
while( $message = yield $connection->receive() ) {
/// stuff..
}
}

etc...

é uma maneira de projetar específico para tentar lidar com a conexão de soquete real.

o principal obstáculo é um conceito de configuração repetível viável que funcione em todas as exchanges. O resto é secundário e nem é realmente importante estar dentro da biblioteca... a menos que as pessoas sintam vontade de enviar exemplos para diferentes bibliotecas de soquete

@dmitriz acho que você precisa entender melhor a funcionalidade para avaliar isso... deixe @lfern continuar seu trabalho

@bolsa

@dmitriz acho que você precisa entender melhor a funcionalidade para avaliar isso... deixe @lfern continuar seu trabalho

Acho este comentário bastante rude, especialmente de alguém que nunca contribuiu para este projeto.

@dmitriz desculpe, cara, suas perguntas estão muito confusas sobre como a divisão entre o que pode ser reutilizado e o que não pode. frustrante para explicá-lo, apenas espere.

este é um projeto incrível!

qual é a linha do tempo do suporte à API do websocket?

@imhazige está praticamente nas mãos de @lfern no momento, você pode entrar e ajudar se tiver tempo

@bolsa

ok, obrigado, acho que deve ser esse recurso https://github.com/lfern/ccxt/tree/feature/websockets

Vou reproduzir meu comentário de #3023

Olá pessoal, preciso de uma ajuda em relação a esta biblioteca. Eu sou um pouco novo em programação no mundo javascript e estou usando isso para construir alguns cálculos de dados de back-end.

Estou tentando passar por todas as bolsas e baixar seus tickers. No loop estou construindo uma estrutura json onde posso passar por todos os dados para fazer cálculos. Eu gostaria de fazer isso buscar mais rápido, pois estou planejando construir um cliente web com alguns serviços, começando com um marketcap de moedas em tempo real. A busca do Websocket estará disponível para ccxt?

É viável fazer assim? Você pode conferir a fonte aqui .

@jraicr eu recomendaria ramificar do trabalho que @lfern começou e tentar continuar seu trabalho em obter um formato genérico para as configurações por troca para lidar com a construção de URL e o processamento de resultados. O código para realmente criar um soquete provavelmente deve ser mantido separado por causa de quão diferente cada linguagem usa soquetes. Mas adicionar uma biblioteca opcional funcional como exemplo certamente ajudaria as pessoas depois que a lógica básica do sistema de configuração do websocket fosse construída.

E também leia as muitas notas que adicionamos sobre detalhes neste tópico :)

Eu tenho testado neste recurso https://github.com/lfern/ccxt/tree/feature/websockets . Já testei a carteira de pedidos com gateio, binance, cex e coincheck, mas acho que seu design ainda não é robusto o suficiente. Eu gostaria de testá-lo com outras trocas de websockets. Você sabe onde encontrar as exchanges mais importantes com suporte a websocket (não o protocolo push por enquanto)?

Obrigado

@lfern você pode querer olhar para gdax, bitmex, bitfinex também... esperamos compilar a lista completa em ccxt... → Documentação da API do Exchange.

@lfern sim, como ele disse, teste essas e das exchanges mais bem avaliadas e vá descendo a lista até sentir que ajustou as coisas o suficiente

Testei o lbank & zb websocket orderbook com sucesso, mas tenho algumas dúvidas:

  1. Eu criei um objeto/dicionário de contexto para colocar todas as informações temporais que você precisa sobre o gerenciamento de websocket. Este dicionário pode ser acessado a partir de qualquer código de troca (por exemplo, binance.js) para que você possa obter/definir quaisquer dados de/para ele. Se você precisar armazenar um valor nesse contexto, poderá fazer desta maneira:
let ethBtcSymbol = this.context['ob']['ETH/BTC'];
ethBtcSynbol['ob'] = obReceived;

Mas quando isso é transpilado para PHP, você não pode obter uma referência a this.context['ob']['ETH/BTC'], você realmente obtém uma cópia deste dicionário, então você não define esse valor neste .contexto. Acho que a única maneira de fazer isso é codificar dessa maneira em .js:

this.context['ob']['ETH/BTC']['ob'] = obReceived;

Você sabe como podemos resolver isso?

  1. Eu defini todos os novos métodos com prefixo "assíncrono", você acha que isso é bom ou é melhor outro prefixo ou não usar prefixos nestas funções?

  2. Como poderíamos mesclar esse código no ccxt? Você acha que isso pode ser mesclado em uma ramificação separada ou é melhor continuar nessa ramificação?

https://github.com/lfern/ccxt/tree/feature/websockets-multiple

Acho que precisamos que outras pessoas testem esse código e obtenham feedback delas. É a primeira vez que uso o asyncio e o reacphp e tenho certeza de que cometi muitos erros na implementação.

@lfern se você é melhor com JS, então continue resolvendo todas as coisas de JS. Vou tentar verificar os problemas do PHP o mais rápido possível. Mas sugiro não abreviar coisas como _asyncHandleOb . demorei um pouco para descobrir o que "ob" significava :) poderia também manter as coisas o mais detalhadas possível.
Quanto à questão de nomenclatura para async ou qualquer outra coisa... Eu acho que ir com socket ou websocket pode ser melhor porque existem mais conceitos assíncronos do que apenas websockets ... para evitar problemas futuros. E menos confusão contra a configuração js : async

Mas quando isso é transpilado para PHP, você não pode obter uma referência a this.context['ob']['ETH/BTC'], você realmente obtém uma cópia deste dicionário, então você não define esse valor neste .contexto.

Isso mesmo, arrays PHP são copiados por valor, não por referência (ao contrário de JS e Python).

Acho que a única maneira de fazer isso é codificar dessa maneira em .js:

this.context['ob']['ETH/BTC']['ob'] = obReceived;

Você sabe como podemos resolver isso?

Receio que a única maneira de resolver isso de maneira transpilável é criar um conjunto de métodos de classe base para trabalhar com referências de objeto ou usar a sintaxe da sua linha acima.

Mas sugiro não abreviar coisas como _asyncHandleOb.

Eu concordaria com @pursehouse aqui, "OrderBook" ou "orderbook" seria um nome muito mais amigável para "ob".

Eu defini todos os novos métodos com prefixo "assíncrono", você acha que isso é bom ou é melhor outro prefixo ou não usar prefixos nestas funções?

Eu prefiro não usar prefixos. Eu usaria a nomenclatura de método que seria explícita no que está fazendo sem prefixos duplicados. Normalmente, está na forma de "verb-noun(s)", como "updateData", "saveFile", "fetchOrderBook", "createOrder", "handleOrderBookDeltaUpdate"...

Como poderíamos mesclar esse código no ccxt? Você acha que isso pode ser mesclado em uma ramificação separada ou é melhor continuar nessa ramificação?

https://github.com/lfern/ccxt/tree/feature/websockets-multiple

Vamos começar a colocar isso em uma ramificação separada do CCXT. No entanto, precisaremos retrabalhar o próprio código WS um pouco para torná-lo compatível com SignalR, WS puro/personalizado e protocolos socket.io (esses são os três tipos de streaming mais populares usados ​​comumente em muitas exchanges). E para isso teremos que ter certeza de que não estamos usando nenhuma variável global ou nenhuma variável de instância. Caso contrário, isso pode produzir muitos conflitos na simultaneidade assíncrona (já os estamos tendo em Python devido a variáveis ​​de instância como self.last_http_response e similares).

Ou seja, se você puder evitar o uso this.context['ob'] e usar o argumento da função para passá-lo, isso ajudaria a resolver um pouco o problema de "cópia por valor" acima e também tornaria o código mais robusto. Assim, trocaríamos as variáveis ​​globais e de instância por variáveis ​​de escopo local e por geradores assíncronos. Dessa forma, evitaríamos possíveis conflitos no futuro. Isso, no entanto, seria uma mudança significativa no seu código. Geralmente, preferimos funções sem estado puras (que não alteram um estado global ou estado de instância). Métodos de estado sujos geralmente entram em conflito uns com os outros em um ambiente simultâneo (condições de corrida, etc...).

Como poderíamos mesclar esse código no ccxt? Você acha que isso pode ser mesclado em uma ramificação separada ou é melhor continuar nessa ramificação?

Um pouco mais sobre essas questões... Começaremos coletando uma lista de exchanges habilitadas para ws, e adicionaremos uma coluna WS à tabela de nossas exchanges, então começaremos a preenchê-la. Com sorte, teremos uma dúzia de trocas com suporte WS na primeira versão estável dele. Feito isso, vamos merge-lo no branch master. E continuaremos adicionando o restante deles a partir daí.

Vamos começar a colocar isso em uma ramificação separada do CCXT. No entanto, precisaremos retrabalhar o próprio código WS um pouco para torná-lo compatível com SignalR, WS puro/personalizado e protocolos socket.io (esses são os três tipos de streaming mais populares usados ​​comumente em muitas exchanges). E para isso teremos que ter certeza de que não estamos usando nenhuma variável global ou nenhuma variável de instância. Caso contrário, isso pode produzir toneladas de conflitos na simultaneidade assíncrona (já os estamos tendo em Python devido a variáveis ​​de instância como self.last_http_response e similares).

Eu não sei como fazer isso sem variáveis ​​de instância, porque você deve manter o livro de pedidos ativo e modificá-lo a cada atualização delta e processá-lo na mesma ordem em que você os recebe do websocket. Então eu acho que você não pode processar mensagens recebidas de websockets usando threads diferentes. (mas não entendo muito de assíncrono). Talvez essa abordagem não seja boa para atingir esse requisito.

De qualquer forma, acho que não é uma boa ideia testar mais exchanges antes que essas mudanças no código WS (para torná-lo compatível com esses protocolos: SignalR, ...) estejam prontas. Mas não sei como colaborar neste trabalho. Eu pensei que isso poderia ser alcançado desenvolvendo um wrapper sobre esses protocolos e, usando EventEmitter, emitindo eventos 'on-open', 'on-message', 'on-error' e 'on-close'. Mas se essa não for uma boa abordagem, talvez seja melhor começar de novo e definir uma nova classe/interface que funcione bem com todos esses protocolos.

Talvez introduza alguma dica para o transpilador JS para PHP usar a referência & em vez de copiar?
http://php.net/manual/en/language.references.whatdo.php

Talvez introduza alguma dica para o transpilador JS para PHP usar a referência & em vez de copiar?

Sim, isso pode ser uma solução alternativa, no entanto, o objetivo é manter a base de código limpa em linguagens de destino puras, caso contrário, essas dicas já estariam em todo este repositório. Preferimos adicionar um método básico como updateArrayByReference (&array) .

@lfern

Eu não sei como fazer isso sem variáveis ​​de instância, porque você deve manter o livro de pedidos ativo e modificá-lo a cada atualização delta e processá-lo na mesma ordem em que você os recebe do websocket.

A maneira usual de fazer isso não é usar variáveis ​​de instância, em vez disso, você passa uma referência ao livro de pedidos para o método de manipulação de atualização, juntamente com os próprios dados de atualização. Então, se você passar as referências apropriadas por toda a cadeia de chamadas, não precisaremos de variáveis ​​de instância, certo?

O principal problema com variáveis ​​de instância (essas são quase variáveis ​​"globais") é quando as respostas assíncronas ficam fora de ordem, você pode ter muitos efeitos colaterais, conflitos e inconsistências com métodos que fazem mutação dessas variáveis ​​de instância. Como eu disse, tivemos alguns desses mais cedo, então é melhor não repetir o erro novamente.

ok, @kroitor . Talvez alguém com uma grande experiência em python asyncio possa dar uma olhada em exchange.py. Não consegui encontrar onde deveria colocar essa variável local (livro de pedidos ao vivo e outras variáveis ​​de status) para ser visível em qualquer método de troca que lida com mensagens assíncronas do websocket. Se isso não for possível com o código real escrito em python, teremos que adaptar o código do nó e do PHP às alterações necessárias para assíncrono no modo multithread.

@lfern

Talvez alguém com uma grande experiência em python asyncio possa dar uma olhada em exchange.py.

Existem dois arquivos exchange.py , um para a versão python de sincronização e outro para a versão python assíncrona, derivados da versão de sincronização. Então, você provavelmente está procurando https://github.com/ccxt/ccxt/blob/master/python/ccxt/async/base/exchange.py

Ou posso ter entendido mal a pergunta, se sim, por favor me avise.

Não consegui encontrar onde deveria colocar essa variável local (livro de pedidos ao vivo e outras variáveis ​​de status) para ser visível em qualquer método de troca que lida com mensagens assíncronas do websocket.

Não se preocupe com isso, basicamente, o que quero dizer é, em vez de fazer isso:

function initializeOrderBook (snapshot) {
    this.context['ob'] = { ... snapshot ... }; // new orderbook state, for example
    this.ws.handler = this.updateOrderBook
}

function updateOrderBook (deltas) {
    const oldOrderBook = this.context['ob'];
    const newOrderBook = parseDeltas (deltas, oldOrderBook);
    this.context['ob'] = newOrderBook;
}

...

↓ em vez do acima, é melhor fazer algo assim (pseudocódigo):

// a base method
function initializeOrderBook (snapshot) { 
    const newOrderBook = new ccxt.IncrementalOrderBook ({ ... snapshot ... }) // initialize it
    // should pass by ref in PHP in the base code, class instances are passed by reference
    this.ws.handler = (deltas) => {
        const updatedOrderBook = this.updateOrderBook (newOrderBook, deltas) 
        this.orderBookUpdated (updatedOrderBook)
    }
    return newOrderBook; // return it, don't store it in an instance variable
}

function updateOrderBook (orderBookInstance, deltas) {
    // mutate orderBookInstance
    orderBookInstance.update (deltas)
    return orderBookInstance;
}

No segundo exemplo, o próprio livro de pedidos é um objeto "passado por referência" e retornado das chamadas, portanto, nenhuma chamada interfere uma na outra gravando em um estado compartilhado. As primitivas de sincronização devem estar no próprio livro de pedidos. Não tenho certeza se estou explicando isso com este exemplo ...

Além disso, não é recomendado misturar assíncrono + threads. É melhor usarmos apenas a simultaneidade encadeada ou apenas a simultaneidade assíncrona (preferida), e você não pode realmente usar as duas simultaneidades ao mesmo tempo, pois elas começam a... uhm... competir.

O que eu quis dizer no meu post anterior é que devemos apenas passá-lo junto com os argumentos para todas as chamadas interessadas nele e retornar o valor atualizado dessas chamadas, em vez de gravar na variável de instância. Isso deve ocorrer com o PHP, mesmo quando o valor é passado por cópia.

Um dos pontos-chave do PHP5 OOP que é frequentemente mencionado é que "objetos são passados ​​por referências por padrão". Isto não é completamente verdadeiro.
Uma referência PHP é um alias, que permite que duas variáveis ​​diferentes escrevam no mesmo valor. A partir do PHP5, uma variável de objeto não contém mais o próprio objeto como valor. Ele contém apenas um identificador de objeto que permite que os acessadores de objeto encontrem o objeto real. Quando um objeto é enviado por argumento, retornado ou atribuído a outra variável, as diferentes variáveis ​​não são aliases: elas guardam uma cópia do identificador, que aponta para o mesmo objeto.

Espero que isso ajude, será um prazer responder se você tiver mais perguntas sobre isso.

Obrigado @kroitor , tenho certeza que está implícito aqui, mas, desculpe, ainda não consigo perceber. Por favor, deixe-me segui-lo do seu exemplo de código:

// a base method in Exhange.js
function initializeOrderBook (snapshot) { 
    const newOrderBook = new ccxt.IncrementalOrderBook ({ ... snapshot ... }) // initialize it
    // should pass by ref in PHP in the base code, class instances are passed by reference
    this.ws.handler = (deltas) => {
        const updatedOrderBook = this.updateOrderBook (newOrderBook, deltas) 
        this.orderBookUpdated (updatedOrderBook)
    }
    return newOrderBook; // return it, don't store it in an instance variable
}
// a base methid in Exchange.js
function updateOrderBook (orderBookInstance, deltas) {
    // mutate orderBookInstance
    orderBookInstance.update (deltas)
    return orderBookInstance;
}

Em cex.js eu defini um método de entrada para analisar qualquer mensagem recebida do websocket.

/* ...*/
processWebsocketIncomingMessage (msg) {
  // parse msg
  if (orderbook snapshot) {
    let orderBook = this.initializeOrderBook (msg.snapshot);
    return orderbook;
  } else if (orderbook delta) {
    /* here I need to recover incremental orderbook and then*/
  } else if (orderbook subscription) {
    /* here I need to recover a promise set when I send a subscription message (in other cex.js method) to tell the user subscription succeded*/
   }
}

Este método é invocado do Exchange.js:

/* receive msg from websocket */
let orderbook = this.processWebsocketIncommingMessage(msg);

Com este modelo, acho que tenho um problema porque não sei se a mensagem de entrada é uma mensagem do livro de pedidos no Exchange.js (isso é don no cex.js), mas no caso de eu poder salvar essa variável do livro de pedidos e depois recuperá-lo no Exchange.js, para que eu possa injetá-lo (quando a mensagem delta for recebida) neste método processWebsocketIncommingMessage sem salvá-lo em uma variável de instância?

Desculpe, claro que é trivial, mas agora não consigo ver como fazê-lo.

@lfern desculpe, provavelmente estou confundindo você mais do que esclarecendo qualquer coisa) Mas de qualquer forma, não vamos nos concentrar em variáveis ​​de instância, na verdade, podemos nos safar com variáveis ​​de instância também. Basicamente, não há problema com sua implementação de processWebsocketIncomingMessage (msg) no ambiente assíncrono – este código não irá desencadear um conflito, porém, acessar uma variável de instância pode ser um problema em um ambiente encadeado (com PHP). Mais ainda, o PHP passa todos os argumentos por cópia, a menos que sejam instâncias de uma classe.

Assim, temos as seguintes escolhas:

  • projete uma classe OrderBook independente para evitar o uso das variáveis ​​de instância e torne-a uma instância única por encadeamento:
// in main thread:
let exchangeInstanceInQuestion = new ccxt.cex ({ ... })

// in each worker thread:
let orderbook = new ccxt.OrderBook (exchangeInstanceInQuestion)

o orderbook irá então encapsular o método processIncomingOrderBookDelta assim como outros métodos necessários, e o usuário terá uma instância separada do orderbook em cada thread...

  • ou adicione métodos básicos de sincronização primitivos para realmente tornar o código thread-safe:
processWebsocketIncomingMessage (msg) {
  // parse msg
  if (orderbook snapshot) {
    let orderBook = this.initializeOrderBook (msg.snapshot);
    return orderbook;
  } else if (orderbook delta) {

    // lock // ←-------------- added

    /* here I need to recover incremental orderbook and then*/

    // unlock // ←-------------- added

  } else if (orderbook subscription) {
    /* here I need to recover a promise set when I send a subscription message (in other cex.js method) to tell the user subscription succeded*/
   }
}

Então, você está certo, não há uma maneira fácil de evitar as variáveis ​​de instância e tornar esse thread-safe, sem levar em consideração a segurança do thread desde o início do design do código. Não estamos seguros para threads neste momento, portanto, para contornar todo esse problema, é necessária uma instância de troca separada por thread para evitar possíveis corridas. Esta pode ser uma boa solução para o problema – basicamente, devemos desencorajar todos de compartilhar as instâncias entre os tópicos em primeiro lugar.

Em última análise, deve ser um dos seguintes:

  • um livro de pedidos por fio
  • ou uma troca por fio
  • ou tem que conter mutexes sincronizados

Espero que faça sentido.

PS Para mim, na verdade, há muito pouco sentido em encadear o manuseio da conexão WS - isso não é algo que deve ser encadeado, em vez disso, um pool de encadeamentos deve gerenciar re/conexões WS separadas.

UPD. desculpe os erros de digitação

@lfern qual branch devo procurar se quiser testar o recurso websocket mais recente?
este https://github.com/lfern/ccxt/tree/feature/websockets
ou este https://github.com/lfern/ccxt/tree/feature/websockets-multiple

Eu acho que é menos importante resolver o conceito de como usar soquetes para os usuários, tanto quanto isolar a criação de chamadas e a análise de pacotes para que eles possam ser usados ​​por um método de chamada de soquete pré-fabricado em potencial ou por seus próprios ciclos do que um exemplo poderia ser distribuído para cada idioma

Estou realmente ansioso para ver poder usar o recurso de soquete com a versão mais recente do ccxt, no navegador usando javascript.

@imhazige o branch atual é https://github.com/lfern/ccxt/tree/feature/websockets-multiple Você pode encontrar um exemplo em async_orderbook.js (o mesmo para ,php e .py). Este exemplo espera parâmetros:

exemplos de nós/js/async_orderbook.js[mercado2...]

A carteira de pedidos é implementada em cex, gateio, binance, bitmex, lbank e zb. As atualizações delta do livro de pedidos precisam ser revisadas, mas se você definir o modo detalhado, poderá ver as mensagens recebidas e o evento do livro de pedidos será emitido.

@lfern

Obrigada.

Acabei de testar o example/js/async_orderbook.js, descobri que o proxy não funcionou.

A opção detalhada está aberta, posso ver que a solicitação é através do proxy. mas não funcionou, cada vez lança um erro de tempo limite de solicitação.

Testei então outro exemplo sem websocket, como live-ticker.js, ainda não funcionou. enquanto na última ramificação mater do repositório ccxt, o exemplo funciona.

Acho que é porque a base de código está muito atrás da ramificação mater do repositório ccxt.

É possível mesclar o código mais recente do ccxt?

E eu tenho uma pergunta, o websocket suporta proxy?

@imhazige
mesclado com ccxt master. Eu não testei através de um proxy. Estou apenas fazendo alguns testes e acho que precisamos de outra variável de configuração para o proxy websocket, porque:

anexado ao URL, como https://proxy.com/https ://exchange.com/api...

não funciona.

@lfern

Obrigado, vejo que o código fundiu o ccxt master v1.14.240. agora o proxy http funciona.

mas quando tento o proxy websocket, não funcionou.

Testei com a url do proxy no código de exemplo http://185.93.3.123 :8080/, não funcionou

Funcionou no seu caso?

Testei com a url do proxy no código de exemplo http://185.93.3.123 :8080/, não funcionou

Desculpe, se não é isso que você estava pedindo.

@kroitor

Obrigado pelos exemplos.

para http, basta usar proxies CORS.

mas ao usar o websocket, estava pensando em usar desta forma https://github.com/imhazige/node-http-connect-proxy , depois de tentar, não funcionou em algum país. :(, eu não tenho idéia agora.

htto-proxy-agents parece funcionar bem com o websocket do nó.

exemplo.js

    const proxy = process.env.http_proxy || 'http://185.93.3.123:8080' // HTTP/HTTPS proxy to connect to
    const agent = new HttpsProxyAgent (proxy)
    exchange = new ccxt[id] ({
        apiKey: apiKey,
        secret: secret,
        enableRateLimit: true,
        verbose: true,
        agent: agent,
    });

Mas o Autobanh/asyncio(python) não está funcionando ao tentar usar o proxy:

2018-06-22T11:32:03 connection to tcp:104.20.34.190:443 established
2018-06-22T11:32:03 CONNECT ws.cex.io:443 HTTP/1.1
Host: ws.cex.io:443


2018-06-22T11:32:03 received HTTP response:

b'HTTP/1.1 400 Bad Request\r\nServer: cloudflare\r\nDate: Fri, 22 Jun 2018 10:32:01 GMT\r\nContent-Type: text/html\r\nContent-Length: 171\r\nConnection: close\r\nCF-RAY: -\r\n\r\n'


2018-06-22T11:32:03 received HTTP status line for proxy connect request : HTTP/1.1 400 Bad Request
2018-06-22T11:32:03 received HTTP headers for proxy connect request : {'server': 'cloudflare', 'date': 'Fri, 22 Jun 2018 10:32:01 GMT', 'content-type': 'text/html', 'content-length': '171', 'connection': 'close', 'cf-ray': '-'}
2018-06-22T11:32:03 failing proxy connect ('HTTP proxy connect failed (400 - BadRequest)')
2018-06-22T11:32:03 dropping connection to peer tcp:104.20.34.190:443 with abort=True: None
2018-06-22T11:32:03 _connectionLost: None
Traceback (most recent call last):
  File "src/py/async-orderbook.py", line 84, in <module>
    loop.run_until_complete(main())
  File "C:\Users\Luis\AppData\Local\Programs\Python\Python36\lib\asyncio\base_events.py", line 468, in run_until_complete
    return future.result()
  File "src/py/async-orderbook.py", line 64, in main
    await exchange.async_subscribe('ob', symbol)
  File "c:\users\luis\documents\projects\ccxt\python\ccxt\async\base\exchange.py", line 669, in async_subscribe
    await self._async_ensure_conx_active(event, symbol, True)
  File "c:\users\luis\documents\projects\ccxt\python\ccxt\async\base\exchange.py", line 480, in _async_ensure_conx_active
    await self.async_connect()
  File "c:\users\luis\documents\projects\ccxt\python\ccxt\async\base\exchange.py", line 490, in async_connect
    await async_connection.connect()
  File "c:\users\luis\documents\projects\ccxt\python\ccxt\async\async\websocket_connection.py", line 90, in connect
    await future
Exception: connection was closed uncleanly (None)

@lfern

Testei os exemplos com a opção de agente

const proxy = process.env.http_proxy || 'http://185.93.3.123:8080'; // HTTP/HTTPS proxy to connect to
  const agent = new HttpsProxyAgent(proxy);
  exchange = new ccxt[id]({
    apiKey: apiKey,
    secret: secret,
    enableRateLimit: true,
    verbose: true,
    agent: agent
  });
  exchange.on('err', (err, conxid) => {
    try {
      console.log(err);
      exchange.asyncClose(conxid);
    } catch (ex) {
      console.log(ex);
    }
  });

obter um erro

fetch:
 binance GET https://api.binance.com/api/v1/exchangeInfo
Request:
 {}
 undefined

Error: [RequestTimeout] binance GET https://api.binance.com/api/v1/exchangeInfo request timed out (10000 ms)

           at e  js/base/Exchange.js:388  throw new RequestTimeout (this.id + ' ' + method + ' ' + url + ' request timed …

o servidor proxy http://185.93.3.123 :8080 está em execução? que tipo de servidor proxy é?

Desculpe, não tenho um servidor proxy na minha rede e não queria perder tempo instalando-o para teste, então tentei um proxy gratuito de free-proxy-list.net . Acho que esses proxies nem sempre estão disponíveis.

@lfern

ok, obrigado, eu quis dizer que o proxy não funcionará em "algum país".

então como posso usar esse recurso via npm? ou tenho que importar o código compilado diretamente?

Em um ambiente de desenvolvimento eu clone de lfern/ccxt em uma pasta local
(./ccxt) e crie um novo projeto (./test). Então exec 'npm init', 'npm
instale ccxt -save' e 'npm link ../ccxt'. Ou se preferir, você pode
importar diretamente.

@lfern

É bom saber, obrigado.

@lfern

Eu quero adicionar o recurso websocket okex, existe algum guia de desenvolvimento para a implementação?

@imhazige Desculpe, ainda não há nenhum documento pronto. Eu adicionei algumas dicas em
https://github.com/lfern/ccxt/blob/feature/websockets-multiple/WEBSOCKETS.md
mas você pode olhar para cex.js, porque acho que a assinatura do livro de pedidos é semelhante ao okex. De qualquer forma, me mande
qualquer pergunta sobre isso e eu ajudaria você a habilitá-lo.

@imhazige talvez você possa usar este esqueleto como ponto de partida:

...
,
            'asyncconf': {
                'conx-tpls': {
                    'default': {
                        'type': 'ws',
                        'baseurl': 'wss://real.okex.com:10441/websocket',
                    },
                },
                'methodmap': {
                },
                'events': {
                    'ob': {
                        'conx-tpl': 'default',
                        'generators': {
                            'url': '{baseurl}',
                            'id': '{id}',
                        },
                    },
                },
            }
...
  _asyncOnMsg (data, conxid = 'default') {
    let msg = this.asyncParseJson (data);
    console.log(msg);
  }
  _asyncSubscribe (event, symbol, nonce) {
        if (event !== 'ob') {
            throw new NotSupported ('subscribe ' + event + '(' + symbol + ') not supported for exchange ' + this.id);
        }
        this.asyncSendJson ({
          event: 'addChannel',
          channel: 'ok_sub_spot_' + pairId + '_depth',
        });
    }

Muito obrigado, vou dar uma olhada hoje.

Em 28/06/2018 00:43, lfern escreveu:
>

@imhazige https://github.com/imhazige talvez você possa usar isso
esqueleto como ponto de partida:

...
,
'asyncconf': {
'conx-tpls': {
'predefinição': {
'tipo': 'ws',
'baseurl': ' wss://real.okex.com :10441/websocket',
},
},
'mapa de métodos': {
},
'eventos': {
'ob': {
'conx-tpl': 'padrão',
'geradores': {
'url': '{baseurl}',
'Eu fiz}',
},
},
},
}
...
_asyncOnMsg (data,conxid = 'default') {
let msg= this.asyncParseJson (dados);
console.log(msg);
}
_asyncSubscribe (evento,símbolo,nonce) {
if (evento !== 'ob') {
throw new NotSupported ('subscribe ' + event + '(' + symbol+ ') not supported for exchange ' + this.id);
}
this.asyncSendJson ({
evento: 'addChannel',
canal: 'ok_sub_spot_' + pairId + '_depth',
});
}


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/ccxt/ccxt/issues/56#issuecomment-400748176 ou
silenciar o fio
https://github.com/notifications/unsubscribe-auth/AD7pFvG0YcY0lhX9tlQ_YdNpyrb0mkeaks5uA7YlgaJpZM4OjakB .

@lfern
Para este método asyncSubscribe (event, symbol) , poderíamos adicionar um terceiro parâmetro params , para que possamos adicionar parâmetros de cliente como depth , e para futuros pedidos, ele precisa de um parâmetro de contract_type

@imhazige Claro! Eu acho que é melhor obter um livro de pedidos completo para gerenciar um livro de pedidos local corretamente, mas esse parâmetro de profundidade pode ser útil para notificar um livro de pedidos de tamanho fixo. Faça qualquer alteração que precisar, pois o código atual é apenas uma proposta e algumas trocas de websocket foram testadas.

Temos uma lista de todas as trocas que oferecem uma conexão websocket (de qualquer tipo). Eu coletei um total de ~ 25-30 dessas trocas e poderia adicionar à lista que você pode manter no seu final

@kroitor o que você acha de adicionar essas colunas à lista de troca ccxt (ws ver, wsDoc)?
https://github.com/lfern/ccxt/tree/feature/websockets-multiple

@lfern claro, farei isso em breve. No entanto, se você não se importa, eu colocaria essa coluna no wiki na seção Streaming (ainda não existe). Eu não colocaria isso na lista principal do README.md ainda, porque se eu fizer isso, as pessoas noob não vão ler nada e vão pensar que essas colunas indicam suporte a websocket no CCXT e apenas nos inundarão com perguntas sobre ws e tudo isso, que não é o que precisamos agora) Então, se você não se importa, eu abriria uma nova seção sobre streaming em nosso Wiki por enquanto. Fará isso em breve. Isso estaria disponível para edição e envio de urls e outras coisas para nossa base de conhecimento.

Acabei de descobrir que o proxy websocket não funcionará no navegador para okex, ele também precisa permitir o cabeçalho de origem cruzada.

Oi @lfern

Estava tentando usar o binance ws.

Parece que a função _asyncHandleObRestSnapshot que gerencia a lógica de binance sobre o lastUpdateId u e U, é chamada apenas uma vez na recuperação do snapshot.

Além disso, acredito que haja um problema com o método mergeOrderBookDelta e searchIndexToInsertOrUpdate. Este último parece que o OB precisa ser classificado para encontrar o elemento certo e, em última análise, excluí-lo em mergeOrderBookDelta, o que nunca acontece pelo menos usando binance websocket :(

Estou trabalhando na refatoração de funções em classes base (removendo o prefixo 'async' nos métodos) e adicionando alguns métodos de classe para acessar dados de contexto. Espero estar pronto esta semana.

@lfern , feliz em saber que a refatoração será útil, enquanto isso, você poderia dar uma olhada no fluxo de dados de mercado para binance que não está retornando os dados corretos? Tentando consertá-lo do meu lado, mas você pode encontrar a solução mais rápido. Você pode verificar no site da binance para ver se há um grande número de discrepâncias.

String _async removida dos métodos e métodos de contexto adicionados para acessar dados de contexto do websocket. Talvez fosse melhor fazer isso em uma classe separada, mas acho que é necessário modificar o script de transpilação. Esses métodos de contexto não são seguros para threads, mas acho que dessa forma podem ser implementados quando necessário. De qualquer forma, cada conexão websocket tem seus próprios dados de contexto, e acho que cada conexão websocket deve ser gerenciada por um único thread. Estes são os novos métodos de contexto para obter/salvar dados:

    _contextGetEvents(conxid) // get events dictionary ('ob', 'tickers', ...)
    _contextGetSymbols(conxid, event) // get symbols from event 
    _contextResetEvent(conxid, event) // reset event dictionary
    _contextResetSymbol(conxid, event, symbol) // reset symbol dictionary ({'subscribed': false, 'subscribing': false, 'data':{}})
    _contextSetSubscribed (conxid, event, symbol, subscribed) // return subscribed status for event/symbol
    _contextIsSubscribed (conxid, event, symbol) // set subscribed status for event/symbol
    _contextSetSubscribing (conxid, event, symbol, subscribing) // return subscribing status for event/symbol
    _contextIsSubscribing (conxid, event, symbol) // set subscribing status for event/symbol
    _contextGetSymbolData(conxid, event, symbol) // get symbol user defined dictionary
    _contextSetSymbolData(conxid, event, symbol, data) // set symbol user defined dictionary
    _contextSet (conxid, key, data) // set data to user defined dictionary (to store any user defined data)
    _contextGet (conxid, key) // get from user defined dictionary

Próximo passo: fazer alguns testes nos métodos de mesclagem de livros de pedidos. Claro que tem algo errado!!!

@anymos Acabei de adicionar um teste para updateBidAsk e agora acho que está funcionando bem.

@imhazige Fiz alterações no seu código okex para torná-lo transpilável e usar métodos de contexto.

@lfern

Excelente!

https://github.com/lfern/ccxt/tree/feature/websockets-multiple é a ramificação oficial para o desenvolvimento do WebSocket? Estou interessado em contribuir.

@wardbradt é um ramo significativo para isso sim. Nada é realmente "oficial" ainda eu acho. Mas a ajuda é muito apreciada, é altamente provável que seja o fork mesclado, eu acho

Que ajuda é necessária nesse ramo? Existe um documento em algum lugar com as etapas restantes e quem está trabalhando no quê? Eu gostaria de arranjar tempo para ajudar com as implementações de python, se puder.

Eu acho que seria bom se você pudesse tentar adicionar suporte a websocket para qualquer exchange e escrever aqui algum feedback sobre problemas que você encontra ou se essa abordagem não é realmente uma boa maneira de adicionar websockets em ccxt. Com esse feedback, os proprietários do projeto ccxt aceitam/rejeitam a mesclagem deste branch.

Há um documento inicial com algumas dicas sobre como você pode adicionar suporte ao websocket:
https://github.com/lfern/ccxt/blob/feature/websockets-multiple/WEBSOCKETS.md

Mas qualquer dúvida sobre isso, por favor, escreva um comentário nesta edição e eu responderei.

Ei, não tenho tempo no momento para integrar, mas tenho este exemplo para uma classe base e uma classe estendida para converter uma carga útil de pacote kline de troca específica em um formato genérico de troca cruzada para usar pelo sistema. Para PHP, é um grande benefício ter uma classe estruturada para armazenar essas coisas em vez de uma conversão de método. Suponho que o código do nó seja o mesmo, só não lido tanto com isso

class SocketCandleKLineBinance extends SocketCandleKLine {
    public function __construct( $payload )   {
        $this->interval             = $payload->k->i;
        $this->start_time           = $payload->k->t;
        $this->trades_count         = $payload->k->n;
        $this->price_open           = $payload->k->o;
        $this->price_high           = $payload->k->h;
        $this->price_low            = $payload->k->l;
        $this->price_close          = $payload->k->c;
        $this->volume               = $payload->k->v;
        $this->taker_base_volume    = $payload->k->V;
        $this->taker_quote_volume   = $payload->k->Q;
    }
}

e..

class SocketCandleKLine {
    public $interval;
    public $start_time;
    public $trades_count;
    public $price_open;
    public $price_high;
    public $price_low;
    public $price_close;
    public $volume;
    public $taker_base_volume;
    public $taker_quote_volume;
    public $lowest_ask;
    public $highest_bid;
}

Eu também preferiria usar classes para armazenar os dados, mas ao fazer a transpilação do código .js recebo erro ao acessar atributos de qualquer classe

let x = $payload.k;

Eu recebo este código transpilado em PHP

$x = $payload.k;

Claro que poderia ser feito modificando o script transpile, mas não é fácil para mim.

Talvez pudéssemos definir alguns utilitários de wrapper fora do código .js transpilável para que você possa acessar qualquer dicionário retornado de funções ccxt para classes como esta.

oh isso é estranho... sim, eu não sei como funciona o transpiler.. talvez @kroitor ?

@lfern o problema com a transpilação genérica de classes interpretadas (sem qualquer tipagem estrita e com fechamentos) é que é muito difícil adivinhar qual variável é qual tipo sem uma travessia AST em escala real em tempo de execução e sem introspecção / sem entrar no v8/python/php "bytecode" por assim dizer... Vou descobrir algo como uma solução rápida para isso.

Eu recebo este código transpilado em PHP

Na verdade, esse problema em particular é específico do PHP e deve ser facilmente solucionado, deixe-me trabalhar um pouco no transpile.js , retornarei em breve. Só precisa adicionar algumas exceções para o operador ponto.

Obrigado @kroitor , vejo que você não cria classes em código transpilável de trocas .js, então suponho que poderia ser difícil de implementar. Eu tentei evitá-lo neste ramo. De qualquer forma, acho que é mais importante agora que outros contribuidores tentem implementar outras trocas de livros de pedidos do websocket e obtenham feedback deles. Se eles gostarem da maneira como estamos implementando websockets, podemos adicionar classes propostas por @pursehouse

Vejo que você não cria classes em código de trocas .js transpilável, então imaginei que poderia ser difícil de implementar

Sim, você está absolutamente certo, eu pensei o mesmo inicialmente... Acabei de revisar e tentei adicionar uma correção rápida, mas... não funcionou bem) Agora estou procurando uma solução rápida para transpile corretamente o ponto sem escapar dele e sem ajustar o código, deixando todos os literais de string intactos, puramente por meio do transpilador... Acho que vou precisar de um pouco mais de tempo, mas vou descobrir e irá informá-lo o mais rápido possível.

Adicione o link doc do websocket api na lista de tabelas para algumas trocas:
https://github.com/lfern/ccxt/blob/feature/websockets-multiple/README.md

Lfern você está no telegram ou no discord? Eu tenho algumas questões.

EDIT: Um grupo de folga ccxt-dev seria bom. Isso existe?

Em qui, 12 de julho de 2018 às 09:01 lfern [email protected] escreveu:

Adicione o link doc do websocket api na lista de tabelas para algumas trocas:
https://github.com/lfern/ccxt/blob/feature/websockets-multiple/README.md


Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/ccxt/ccxt/issues/56#issuecomment-404563014 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AFQFAllW7QM1RwVI_U-3BTGoV3LqumQOks5uF3LRgaJpZM4OjakB
.

desculpe @skeller88 . Não tenho conta no telegram/discord por enquanto. Se você não se importa, escreva-os aqui e eu tento responder rapidamente.

@GoChartingAdmin , você se importaria de postar sua lista de troca de websockets para adicionar a esta lista?

@lfern vou tentar adicionar o suporte da Binance no binance-websocket-support, um
branch que eu desviei lfern/feature/websockets-multiple
https://github.com/skeller88/ccxt/tree/feature/binance-websocket-support .
Então eu vou enviar um PR contra websockets-multiple. Isso funciona?

Estou tentando executar example/py/websocket-orderbook.py usando "binance" e
vendo o erro abaixo. O self.wsconf Dict está vazio no tempo de execução. Há
já algum código em binance.js assim como o websocket-orderbook.py já
trabalhando para você usando binance? Eu vou assumir que não era.

Traceback (most recent call last):
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py",
line 1664, in <module>
    main()
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py",
line 1658, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py",
line 1068, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Applications/PyCharm
CE.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in
execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File
"/Users/shanekeller/Documents/lfern_ccxt/examples/py/websocket-orderbook.py",
line 81, in <module>
    loop.run_until_complete(main())
  File "/Users/shanekeller/anaconda/lib/python3.6/asyncio/base_events.py",
line 467, in run_until_complete
    return future.result()
  File
"/Users/shanekeller/Documents/lfern_ccxt/examples/py/websocket-orderbook.py",
line 61, in main
    await exchange.websocket_subscribe('ob', symbol, {'limit': limit})
  File
"/Users/shanekeller/Documents/lfern_ccxt/python/ccxt/async/base/exchange.py",
line 712, in websocket_subscribe
    raise ExchangeError('Not valid event ' + event + ' for exchange ' +
self.id)
ccxt.base.errors.ExchangeError: Not valid event ob for exchange binance
binance requires to release all resources with an explicit call to the
.close() coroutine.
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x10c483dd8>

Em sex, 13 de julho de 2018 às 09:08 lfern [email protected] escreveu:

@GoChartingAdmin https://github.com/GoChartingAdmin , você se importaria de
postar sua lista de troca de websocket para adicionar a esta lista?


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/ccxt/ccxt/issues/56#issuecomment-404878798 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AFQFApUvfY_oNwHXIIOjxPXdP1Bel4lYks5uGMYBgaJpZM4OjakB
.

Desculpe @skeller88 . Não estou confirmando alterações de arquivos transpilados .py e .php. Talvez eu tivesse que confirmar esses arquivos também. Você tem que fazer npm install e então npm run-script transpile para obter o arquivo binance.py transpilado. Então websocket-orderbook.py funcionaria

Depois de executar o transpile, o websocket-orderbook.py funciona. eu vejo binance
já tem suporte para livro de pedidos do websocket, então vou tentar adicionar o websocket
suporte de livro de pedidos para bittrex. O websocket deles está em beta, então se eu não conseguir
que está funcionando, vou adicioná-lo para gdax. Parece bom?

Algum teste foi escrito? Não estou encontrando nenhum ainda.

Você está esperando para adicionar o código python e php até que lfern/ccxt seja aprovado
para mesclar em ccxt/ccxt?

Em sex, 13 de julho de 2018 às 14h23, lfern [email protected] escreveu:

Desculpe @skeller88 https://github.com/skeller88 . eu não estou cometendo
alterações de arquivos transpilados .py e .php. Talvez eu tivesse que me comprometer
esses arquivos também. Você tem que fazer npm install e depois npm run-script
transpile para obter o arquivo binance.py transpilado. Em seguida, websocket-orderbook.py
trabalharia


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/ccxt/ccxt/issues/56#issuecomment-404957677 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AFQFAhc61obJP9u6Y9Yu5iqWP6-s-0Htks5uGQ_XgaJpZM4OjakB
.

Eu acho que Gdax websocket doc é melhor que bittrex, mas ainda estamos testando, então qualquer troca pode ser interessante para verificar se é fácil de implementar. A única restrição é não implementar trocas que usem protocolo pusher (como bitstamp), ou pubnut.com, somente conexões websocket "raw" são suportadas neste ramo.

Algum teste foi escrito? Não estou encontrando nenhum ainda.

Desculpe, acho que não é fácil escrever testes que simulem uma conexão websocket. Não penso nisso, mas suponho que podemos criar uma subclasse Websocket que emule uma conexão websocket, mas essa classe seria criada para cada troca... Talvez alguém neste tópico possa nos dar algumas idéias sobre isso,.

Você está esperando para adicionar o código python e php até que lfern/ccxt seja aprovado
para mesclar em ccxt/ccxt?

Sim, eu pensei que isso poderia ser confirmado quando essa ramificação fosse mesclada. Mas se você acha que commitar o código transpilado facilita a vida de quem quiser testá-lo em php ou python eu vou confirmar esse código também! Talvez @kroitor possa nos dizer se isso seria uma boa ideia, ou é melhor não confirmar o código transpilado por enquanto.

Tentei conectar o websocket gdax. Veja este ramo
https://github.com/lfern/ccxt/compare/feature/websockets-multiple...skeller88:feature/websockets-multiple-gdax?expand=1 .
Achei a análise e a configuração do wsconfg um pouco confusas. Isto
parece que toda a razão para essa análise é construir urls de websocket
que estão conectados, como no caso de binance. Mas para gdax, apenas um
url está conectado e vários canais são inscritos via
solicitações de assinatura nessa conexão de websocket. Para gdax, não
parece que a definição de URL por nível de evento e a interpolação de variável são
necessário certo? Então essa configuração pode ser opcional.

Estou recebendo um erro de tempo limite quando tento me conectar ao websocket gdax.
Estou sem tempo para trabalhar nisso por alguns dias, mas vou tentar ajudar
o tanto que eu conseguir.

Em sex, 13 de julho de 2018 às 16:15 lfern [email protected] escreveu:

Eu acho que Gdax websocket doc é melhor que bittrex, mas ainda estamos
testes, então qualquer troca pode ser interessante para verificar se é fácil
implemento. A única restrição é não implementar exchanges que usem
protocolo pusher (como bitstamp) ou pubnut.com, apenas websocket "raw"
conexões é suportada nesta ramificação.

Algum teste foi escrito? Não estou encontrando nenhum ainda.

Desculpe, acho que não é fácil escrever testes que simulem um websocket
conexão. Não penso nisso, mas suponho que podemos criar um Websocket
subclasse que emula uma conexão websocket, mas essa classe seria
criado para cada troca... Talvez alguém neste tópico possa nos dar
algumas idéias sobre isso,.

Você está esperando para adicionar o código python e php até que lfern/ccxt seja aprovado
para mesclar em ccxt/ccxt?

Sim, eu pensei que isso poderia ser confirmado quando esta ramificação fosse
mesclado. Mas se você acha que cometer o código transpilado torna a vida
mais facil quem quiser testar em php ou python vou commitar esse codigo
também! Talvez @kroitor https://github.com/kroitor possa nos dizer se isso
seria uma boa idéia, ou é melhor não confirmar o código transpilado por enquanto.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/ccxt/ccxt/issues/56#issuecomment-404976377 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AFQFAiQDi3R9BmZDxnTbVYsgAeXjJFRuks5uGSoGgaJpZM4OjakB
.

sim, então deve haver um conceito genérico para construir a url de abertura, que precisa da capacidade de aceitar objetos para construir a url. bem como precisa que o socket chama para adicionar assinaturas como um conceito genérico que aceita objetos.
então, separadamente, todos esses tipos de objetos precisam de sua própria estrutura central que cada troca pode estender para o formato de e para o formato ccxt

Sim, você está certo @skeller88 . A interpolação de variáveis ​​não é realmente útil por enquanto, porque as trocas implementadas pelo websocket atuais, exceto o binance, têm apenas um websocket para todos os eventos. Acho que precisamos de algo que o Exchange.js possa usar para saber o que fazer quando receber um comando de assinatura/cancelamento de assinatura no evento/símbolo. Exchange.js gerencia conexões de websocket, então precisamos de algo em cada troca que nos informe o que fazer em cada comando de assinatura:

  • quando vários canais em apenas um websocket: na assinatura e se o websocket não estiver aberto, abra o websocket, redefina o contexto. Se ainda estiver aberto, não faça nada, ao cancelar a assinatura, feche o websocket (ou não) se não houver mais assinaturas ativas e redefina o contexto do websocket.
  • quando vários canais em um websocket, mas conexões de url diferentes para cada canal (binance): na assinatura/cancelamento de assinatura, você precisa se reconectar ao websocket usando um URL diferente (gerado com assinaturas/cancelamentos anteriores) e redefinir o contexto do websocket. Ao cancelar a assinatura, se for o último fluxo ativo, feche o websocket.
  • when pusher: cada evento/símbolo tem sua própria informação de conexão do websocket, então precisamos de algo que mapeie o evento/símbolo para a configuração do pusher.
  • quando cada evento ou evento/símbolo corresponde a um websocket diferente: na assinatura abra o websocket para evento/símbolo, redefina o contexto; ao cancelar a inscrição, feche o websocket para evento/símbolo.

Ainda não encontro uma troca para este último caso, mas a interpolarion variável seria útil para obter o websocket de origem para as informações do evento/símbolo.

Talvez seja melhor tirar isso da configuração e criar métodos, invocados do Exchange.js, que forneçam essas informações para gerenciar o pool de conexões do websocket.

@lfern é por isso que sugiro focar nos recursos individuais necessários para processar dados enviados ou recebidos com o soquete; em vez de resolver como usar soquetes em geral.
Dessa forma, os requisitos podem ser divididos em fases e, potencialmente, liberar os recursos principais da funcionalidade com exemplos de como usá-los, pode ser seguido com um futuro (e problema muito mais complicado) de uma maneira genérica de chamar os soquetes. O que terá muito mais apoio da comunidade porque os blocos de construção existirão.
Porque qualquer que seja o estilo de soquete que você criar para JS, agora também há um novo estilo de soquete necessário para PHP e Python. Portanto, forçar o lançamento a incluir uma solução de soquete completo significa que eles também precisam ser resolvidos. e para PHP, isso seria complexo para dizer o mínimo .. porque não é orientado a eventos como JS é, então para eu enviar as respostas para meu banco de dados ou qualquer outra coisa após o CCXT processá-lo, eu preciso estar na linha de ...

// $streamsUrl would be populated by the CCXT Binance socket url generator based on objects passed to it
\Amp\Loop::run( function () use ( $streamsUrl, $exchange ) {
    /** <strong i="9">@var</strong> \Amp\Websocket\Connection $connection */
    $connection = yield Websocket\connect( $streamsUrl );
    while( $message = yield $connection->receive() ) {
        $payload = yield $message->buffer();
// this decode line would be replaced with the CCXT decoder for Binance
        $decode = json_decode( $payload );
// this switch would use the CCXT generic format for a socket packet
        switch( $decode->data->e ) {
            case "kline":
// methods do save my data
            break;
        }
        yield new Delayed( 1000 );
    }
} );

então, se você resolver os blocos de construção, as pessoas poderão implementar seus sistemas para usá-lo. e talvez uma solução de soquete genérica que possa passar pacotes para o sistema de desenvolvedores surja com o tempo.

@pursehouse para mim o acima se resume a uma decomposição de método adequada e flexível. No entanto, eu concordo que fazer coisas assíncronas com PHP pode ser complicado, pode até exigir uma solução de encadeamento ou um wrapper somente PHP7 ... mais difíceis de manter ou transpilar. Acho que nosso objetivo final é mover o máximo possível para a classe base para fins de unificação.

@kroitor certo, então não tente resolver as habilidades do soquete agora, apenas concentre-se nos blocos de construção:

  • geração de URL
  • criação de pacotes
  • processamento de pacotes

porque agora parece que muito tempo está sendo gasto em como fazer soquetes em geral, o que não vai resolver em todos os idiomas. E parece ser o aspecto mais difícil no que diz respeito a torná-lo uma solução genérica, e mesmo que os soquetes genéricos sejam resolvidos para JS, todos esses blocos de construção ainda são necessários para funcionar em todas as trocas. Então, por que não fazer os blocos de construção primeiro e talvez incluir algum código de exemplo sobre como usá-los. Em seguida, uma solução de soquete genérica pode ser trabalhada e provavelmente terá uma escala maior de colaboradores.

@lfern Fará até amanhã EOD

@lfern Estava passando pela lista - você adicionou Bistamp. Bitstamp atualmente usa Pusher. Eu pensei que o Pusher estava fora do escopo nesta fase

@GoChartingAdmin , sim, você está certo. Acho que poderíamos adicionar todas as trocas com websocket e talvez adicionar uma coluna para apontar que o protocolo pusher não está disponível. O que você acha?

@lfern concordo. Isso eliminará Bitstamp e Quionex

Obrigado pessoal por trabalhar no WS! Você precisa de alguma ajuda para que isso aconteça mais rápido? Além disso, você tem um ETA quando isso estará ok? Minha empresa precisa muito desse recurso e podemos alocar 1 ou 2 desenvolvedores se necessário.

@GoChartingAdmin Adicionado clumn "Ws Protocol" na tabela leia-me.

@backnight em posts recentes algumas mudanças foram propostas. Mas acho que seria melhor que outras pessoas pudessem escrever código para outras exchanges para que pudéssemos perceber que a implementação atual do ws é realmente uma boa implementação. Não sei se alguém está tentando fazer isso, ou modificando essa implementação de alguma forma, mas estou aguardando algum feedback sobre isso. Se essa implementação for aceita (com quaisquer alterações propostas), acho que novas trocas podem ser adicionadas muito rapidamente.

@lfern Apenas para informação. Recentemente, consegui integrar APIs não websocket (signalR ou Pusher) em nosso aplicativo. Atualmente, oferecemos suporte ao WS para mais de 21 trocas em nosso aplicativo GoCharting . Veja a produção ao vivo para um cliente signalR abaixo

https://gocharting.com/terminal/IN/CRYPTO/ADT%7CBTC/BitTrex

Vou contribuir com algumas dessas peças quando tivermos coberto os websockets normais. Percebi que todos são meros wrappers em torno da implementação nativa do websocket e, portanto, podem ser implementados sem outras bibliotecas de terceiros

image

@lfern

um bug posivel? - erro de socket não aberto ao invocar websocketSubscribe

na filial https://github.com/lfern/ccxt/tree/feature/websockets-multiple

isso é como acontecer em uma rede lenta quando se conecta ao okex.

é estranho que o soquete ainda não esteja aberto ao invocar o websocketSubscribe.

Pilha de erros:

Erro: não aberto I20180905-18:02:28.011(8)? em WebSocket.send (node_modules/ws/lib/WebSocket.js:360:18) I20180905-18:02:28.011(8)? em WebsocketConnection.send (ccxt-websocket/js/base/websocket/websocket_connection.js:77:28) I20180905-18:02:28.012(8)? em WebsocketConnection.sendJson (cxt-websocket/js/base/websocket/websocket_base_connection.js:37:14) I20180905-18:02:28.012(8)? em okex.websocketSendJson (ccxt-websocket/js/base/Exchange.js:1866:31) I20180905-18:02:28.012(8)? em okex._websocketSubscribe (ccxt-websocket/js/okex.js:295:14) I20180905-18:02:28.012(8)? em Promise.asyncApply (ccxt-websocket/js/base/Exchange.js:2092:14)

isso não será facilmente reproduzido.

@kroitor Obrigado pelo projeto incrível. Existe algum exemplo mostrando como obter negociações via websocket?
E quais trocas são suportadas até a data

@amit2103

Existe algum exemplo mostrando como obter negociações via websocket?

Não tenho certeza se é possível via websocket, você não pode usar rest api?
https://github.com/lfern/ccxt/blob/feature/websockets-multiple/examples/js/bitfinex-fetch-trades.js

E quais trocas são suportadas até a data

https://github.com/lfern/ccxt/tree/feature/websockets-multiple#supported -cryptocurrency-exchange-markets

@lfern oi, você poderia adicionar um exemplo de livro de pedidos de busca de websocket da binance?

Oi @djoffrey , em examples/js/websocket-orderbook.js você pode encontrar um exemplo para buscar o livro de pedidos. Execute-o com estes parâmetros e você poderá buscar e obter eventos das informações do livro de pedidos:

node examples/js/websocket-orderbook.js binance 'no-apikey-required' 'no-key-required' 10 ETH/BTC

O primeiro parâmetro é o ID da exchange, o segundo/terceiro são api-key/secret (não exigido pela binance), o quarto é o número de lances/asks a serem obtidos e o quinto e os seguintes são o símbolo a ser obtido.

Ei pessoal, e que tal FIX API? O CoinbasePro suporta isso e abriria as portas para as bolsas de negociação clássicas (ações/...). http://en.wikipedia.org/wiki/Financial_Information_eXchange Não sei quais outras Crypto-Exchanges suportam este padrão.

ATUALIZAÇÃO: Encontrei um bom artigo... https://algosforcryptos.com/trading-apis-top-crypto-exchanges/

A API FIX está disponível para:

  • Bitfinex
  • Bitstamp
  • BTCC
  • CEX.io
  • CoinbasePrime
  • CoinbasePro
  • GÊMEOS
  • HitBTC

Significa que uma implementação da API FIX (que também está transmitindo como websocket, tanto quanto eu entendo) cobriria instantaneamente 8 (ok 7) exchanges de criptomoedas, além de muitas exchanges tradicionais.

Já existem implementações de nodeJS para a API FIX nas quais o ccxt pode contar com um acesso unificado a fluxos FIX e Websocket. Apenas uma ideia... :)

Eu odeio ser esse cara, mas algum progresso nisso? Não me interpretem mal, eu acho incrível que você esteja distribuindo um projeto tão incrível de graça, mas a implementação do websocket foi supostamente quase concluída há mais de um ano.
Simplesmente usar uma solicitação HTTP em um loop, como em alguns exemplos, não é uma boa solução para o meu projeto.
Então, existe algum ETA para isso?
Mais uma vez, obrigado pelo excelente projeto :)

@bramvbilsen Talvez você precise começar a implementá-lo no ccxt. Acho que @kroitor e todos os outros desenvolvedores ficariam felizes se você pudesse rascunhar como gostaria de implementar com ccxt (permitindo a função de retorno de chamada em vez de retornar uma promessa, eu acho). Assim que chegar à FixAPI (tenho também muitas outras tarefas na minha lista) provavelmente começarei com isso, pois aprecio muito o trabalho da comunidade ccxt (especialmente @kroitor hoje em dia). Eu quero dar algo de volta para a comunidade. Mas, como a questão "há um ano", também levará algum tempo. ;-)

@TechupBusiness Não me entenda mal, eu não me importaria de fazer isso. Mas a razão pela qual eu estava olhando para o ccxt é porque eu não tenho muito tempo, infelizmente.

@bramvbilsen Essa é provavelmente a razão pela qual a maioria de nós desembarcou aqui: economizar tempo como o recurso mais escasso. :)

PS Eu também adoraria ver um tipo de ccxt para interações blockchain/DLT um dia.

@TechupBusiness Exatamente!

Se o seu projeto precisa disso e as exchanges têm suporte a websocket, por que não escrever seu próprio wrapper. É muito mais fácil do que escrever algo que se encaixe em uma camada de abstração unificada que o pessoal da ccxt está tentando fazer. Já existem muitas implementações para trocas populares como binance, bitfinex, bitstamp, etc. Não há razão para que você deva fazer um loop em solicitações HTTP se tiver uma API de websocket disponível para você

@soliveira-vouga Não estou fazendo isso, atualmente estou usando as implementações de websocket de diferentes exchanges. Mas pensei ter visto que é isso que os exemplos neste repositório fazem para obter dados "ao vivo".

O branch feature/websockets-multiple pode ser usado em python?

Trocas com suporte a ws (js/py/php) em feature/websockets-multiple branch
@quazzuk , @tommuhm , @yevsev , @imhazige , @beijingkaka , @firepol , obrigado pela ajuda!!

| troca | tipo ws | eventos |
|---------------|-----------|---------- ----------|
|binance | ws | comércio de cotações de livros de encomendas ohlcv |
|bitmex | ws | livro de encomendas |
|bitstamp | empurrador | livro de encomendas |
|cex | ws (autenticação) | livro de encomendas |
|checagem de moedas | ws | livro de encomendas |
|coinbaseprime | ws | livro de encomendas |
|coinbasepro | ws | livro de encomendas |
|gateio | ws | livro de encomendas |
|gêmeos | ws | livro de encomendas |
|hadax | ws | livro de encomendas |
|hitbtc2 | ws | livro de encomendas |
|huobipro | ws | livro de encomendas |
|lbanco | ws | livro de encomendas |
|líquido | empurrador | livro de encomendas |
|okex | ws | livro de encomendas |
|poloniex | ws | livro de encomendas |
|zb | ws | livro de encomendas |

Alguém sabe sobre outro url (https://algosforcryptos.com/trading-apis-top-crypto-exchanges/) para obter mais trocas que suportem conexões websocket ou pusher?

@lfern Estou tentando descobrir como funciona a parte python. Onde está a configuração do URL do websocket para cada troca? e os eventos disponíveis?

perguntar exceção nunca foi recuperada
futuro:exception=ExchangeError('Livro de pedidos de evento inválido para exchange binance',)>
Traceback (última chamada mais recente):
Arquivo "websocket-playground.py", linha 59, em main
aguardar exchange.websocket_subscribe(evento, símbolo, parâmetros)
Arquivo "/home/user/crypto/ccxt/python/ccxt/async_support/base/exchange.py", linha 773, em websocket_subscribe
raise ExchangeError('Not valid event ' + event + ' for exchange ' + self.id)
ccxt.base.errors.ExchangeError: livro de pedidos de evento inválido para troca binance

obrigado

@ rg687 Ainda não estou confirmando arquivos gerados em PHP e Python do processo de transpilação. Você deve executar npm run transpile na pasta base ccxt para obtê-los. Você encontrará uma estrutura de configuração `wsconf' com eventos válidos ('ob' para orderbook)

@rg687 talvez você deva executar npm run export-exchanges antes da transpilação para garantir que exchange.json seja gerado.

@ rg687 Ainda não estou confirmando arquivos gerados em PHP e Python do processo de transpilação. Você deve executar npm run transpile na pasta base ccxt para obtê-los. Você encontrará uma estrutura de configuração `wsconf' com eventos válidos ('ob' para orderbook)

@lfern Acabei de testar com python e funcionou bem com algumas trocas que testei. Bom trabalho cara!

Vejo que muitas trocas importantes foram implementadas.

Idéias quando o bitfinex será implementado?

adicionado livro de pedidos do websocket para therock, theocean, bitfinex2

@lfern Posso perguntar quando você planeja mesclar 'websockets-multiple' ao mestre?

@AlexeyZelenin Eu realmente não sei se esse desenvolvimento é maduro o suficiente para fazer uma solicitação push para master. Se os proprietários de ccxt pensarem assim, eu adicionaria uma solicitação push para master. Mas acho que eles precisam verificar se o código desenvolvido e as dependências adicionadas podem ser mescladas no branch master.

@lfern ótimo trabalho sobre bitfinex2, acabei de testar e funciona muito bem.
Eu também testei o cex (WS autenticado).

Posso relatar alguns problemas que encontrei? Eu testei alguns exemplos de websocket em examples/py :

(aliás, acho que pode ser uma boa ideia colocar alguns exemplos com uso (sinta-se à vontade para copiar/adaptar o seguinte) no arquivo WEBSOCKETS.md , noob friendly.) De qualquer forma, aqui estão minhas descobertas:

  • websocket-poloniex-orderbook.py , (na linha 11 substitua import ccxt.async por import ccxt.async_support ) uso ./websocket-poloniex-orderbook.py funciona
  • websocket-playground.py , o uso ./websocket-playground.py bitstamp ob BTC/EUR funciona como um encanto
  • websocket-orderbook.py , (na linha 11 substitua import ccxt.async por import ccxt.async_support ), use:

    • um símbolo: ./websocket-orderbook.py bitstamp None None 5 BTC/EUR

    • vários símbolos ./websocket-orderbook.py bitstamp None None 5 BTC/EUR XRP/EUR

Após cerca de 5 segundos, recebo este erro:

Traceback (most recent call last):
  File "/opt/projects-python/ccxtws/examples/websocket-orderbook.py", line 81, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
    return future.result()
  File "/opt/projects-python/ccxtws/examples/websocket-orderbook.py", line 74, in main
    await exchange.websocket_unsubscribe('ob', symbol)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/base/exchange.py", line 825, in websocket_unsubscribe
    self._websocket_unsubscribe(conxid, event, symbol, oid, params)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/bitstamp.py", line 941, in _websocket_unsubscribe
    self.websocketSendJson(payload)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/base/exchange.py", line 669, in websocketSendJson
    websocket_conx_info['conx'].sendJson(data)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/websocket/websocket_base_connection.py", line 31, in sendJson
    self.send(json.dumps(data))
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/websocket/pusher_light_connection.py", line 172, in send
    if json_data['event'] == 'subscribe':
KeyError: 'event'

./websocket-orderbook.py binance None None 5 NANO/BTC BTC/USDT : parece funcionar bem, mas depois de cerca de 30s ele falha com KeyError:'limit' .

Acho que as linhas await asyncio.sleep(5) são responsáveis ​​por isso. Se eu aumentar, por exemplo, para 20, funcionará 20 segundos. É possível modificar o exemplo para que funcione para sempre?

Também eu esperava que vários websockets funcionassem simultaneamente, o que não é realmente o caso.

Por favor, corrija todos os ccxt.async com ccxt.async_support nos exemplos se houver outras sobras.

Obrigado novamente pelo ótimo trabalho. Eu estava realmente ansioso para ter uma boa biblioteca suportando muitas trocas e isso faz o trabalho.

Obrigado! @firepol , seu traceback me ajuda a encontrar dois bugs:

  • um símbolo: ./websocket-orderbook.py bitstamp None None 5 BTC/EUR
  • vários símbolos ./websocket-orderbook.py bitstamp None None 5 BTC/EUR XRP/EUR

Após cerca de 5 segundos, recebo este erro:

Traceback (most recent call last):
  File "/opt/projects-python/ccxtws/examples/websocket-orderbook.py", line 81, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
    return future.result()
  File "/opt/projects-python/ccxtws/examples/websocket-orderbook.py", line 74, in main
    await exchange.websocket_unsubscribe('ob', symbol)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/base/exchange.py", line 825, in websocket_unsubscribe
    self._websocket_unsubscribe(conxid, event, symbol, oid, params)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/bitstamp.py", line 941, in _websocket_unsubscribe
    self.websocketSendJson(payload)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/base/exchange.py", line 669, in websocketSendJson
    websocket_conx_info['conx'].sendJson(data)
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/websocket/websocket_base_connection.py", line 31, in sendJson
    self.send(json.dumps(data))
  File "/opt/projects-javascript/ccxt/python/ccxt/async_support/websocket/pusher_light_connection.py", line 172, in send
    if json_data['event'] == 'subscribe':
KeyError: 'event'

Isso é causado por um erro de tempo limite de cancelamento de assinatura. A assinatura do pusher retorna um evento ack, mas o unsubscription não retorna nenhum evento e o código de binance estava esperando por ele.
./websocket-orderbook.py binance None None 5 NANO/BTC BTC/USDT : parece funcionar bem, mas depois de cerca de 30s ele falha com KeyError:'limit' .

se você deseja assinar as atualizações do livro de pedidos da binance em um segundo símbolo de mercado, você precisa se reconectar ao websocket com parâmetros de URL adicionais. Quando o websocket é reconectado, suas variáveis ​​de contexto são redefinidas, então o parâmetro "limit" salvo no contexto é perdido e causa esse erro " keyerror:limit ". Neste tipo de trocas (streams) temos que armazenar esses parâmetros de configuração em variáveis ​​persistentes de contexto.

Obrigado novamente por sua ajuda!

Obrigado a você @lfern pelas soluções rápidas, eu aprecio.

Percebi outra coisa, testando vários websockets na mesma exchange, por exemplo:

./websocket-orderbook.py bitfinex2 None None 5 BTC/USDT XRP/USDT

Começo a ver as atualizações do BTC/USDT imediatamente, mas antes de ver qualquer coisa sobre o XRP/USDT tenho que esperar cerca de 5 segundos.

Eu acho que isso é causado pelo await asyncio.sleep(5) isso é realmente necessário?

Se eu tentar com 3 pares:

./websocket-orderbook.py bitfinex2 None None 5 BTC/USDT XRP/USDT

Mesmo: BTC/USDT aparece imediatamente, após 5 segundos vejo atualizações de XRP/EUR, então tenho que esperar mais 5 segundos para ver atualizações de ETH/EUR. Assim, imagine que você deseja monitorar 11 pares, você verá as atualizações do último par somente após 50 segundos. Isso é um tipo de limitação de taxa para websockets?

Além disso, no exemplo websocker-orderbook, parece que o websocket é descadastrado e re-subscrito a cada 5 segundos. Algo não parece correto neste exemplo.

Tentei comentar o primeiro await asyncio.sleep(5) , mas parece que só subscreve o primeiro par.
Tentei colocar um valor menor, 1 segundo: await asyncio.sleep(1) então o delay agora é muito baixo.
Eu coloquei um valor alto para o segundo sono: await asyncio.sleep(2000000) assim ele é cancelado somente mais tarde. Isso tem uma implicação? O que acontece se o websocket for desconectado antes? 5 segundos foi uma maneira de fazê-lo se inscrever novamente em um evento desses? Existe um evento acionado se uma assinatura de um websocket não funcionar mais? Seria bom ter um exemplo para lidar com uma desconexão do websocket corretamente, por exemplo, tente se inscrever novamente após 2 minutos quando a conexão do websocket for perdida.

Obrigado pelo seu feedback

Olá, depois de mais alguns testes, eu realmente desenvolvo meu próprio projeto e o abri aqui: https://github.com/firepol/ccxt-websockets-db-updater

@lfern Estou com problemas para me conectar a mais de um par na binance, talvez você possa ajudar a corrigir isso? Pelo que vi em minha outra ferramenta que codifiquei (também baseada em outra biblioteca, então não sou totalmente especialista em websockets), a binance e o GDAX precisam de um "registro de produto" antes de assinar cada livro de pedidos. Não sei o que isso significa, mas pode ser por isso que o binance não funciona se eu tentar conectar em paralelo como fiz no meu programa.

Veja: https://github.com/firepol/ccxt-websockets-db-updater/issues/1

@firepol , a binance usa streams na conexão websocket. Você precisa abrir o websocket com todos os símbolos que deseja observar: wss://stream.binance.com :9443/stream?streams=//

A primeira vez que você tentar se inscrever na biblioteca websocket abra o websocket com apenas um stream:wss ://stream.binance. com:9443/stream?streams=NANOBTC@profundidade

enquanto a primeira assinatura for bem-sucedida, se você tentar assinar o segundo símbolo, o driver binance ws precisará fechar a conexão anterior e abrir o websocket com uma nova URL: wss://stream.binance.com :9443/stream? streams=NANOBTC@depth/ETHBTC@depth e a primeira ação de abertura do websocket é fechada antes de ser bem-sucedida.

Não sei como lidar com isso corretamente, talvez antes de fechar o driver da binance tenha que esperar até que a primeira assinatura seja bem-sucedida. mas a função close não é assíncrona e precisamos ter certeza de que a conexão ws anterior está fechada antes de conectar com a nova URL. Por enquanto, você não deve se inscrever em paralelo na mesma bolsa

Olá, depois de mais alguns testes, eu realmente desenvolvo meu próprio projeto e o abri aqui: https://github.com/firepol/ccxt-websockets-db-updater

@lfern Estou com problemas para me conectar a mais de um par na binance, talvez você possa ajudar a corrigir isso? Pelo que vi em minha outra ferramenta que codifiquei (também baseada em outra biblioteca, então não sou totalmente especialista em websockets), a binance e o GDAX precisam de um "registro de produto" antes de assinar cada livro de pedidos. Não sei o que isso significa, mas pode ser por isso que o binance não funciona se eu tentar conectar em paralelo como fiz no meu programa.

Veja: firepol/ccxt-websockets-db-updater#1

ATUALIZAÇÃO: muito obrigado @lfern por consertar meu pequeno projeto, eu agradeço!

TL;DR: @lfern me ajudou a fazer funcionar a assinatura de vários websockets da mesma exchange, em paralelo. Dê uma olhada no meu script: https://github.com/firepol/ccxt-websockets-db-updater

@lfern thxpela sua resposta, btw notei uma pequena coisa com bitfinex2, o timestamp está faltando.

Para o binance permitir vários pares, talvez você possa se inspirar na biblioteca xchange-stream, mesmo que seja java, talvez algumas ideias possam ser úteis para o CCXT também? em particular, verifique ProductSubscription. Veja, por exemplo, como eu uso (não sou especialista, alguém me ajudou a fazê-lo funcionar) aqui:

https://github.com/firepol/crypto-websockets/blob/dev/src/main/java/com/github/firepol/cryptows/ExchangeManager.java

Veja em processWebsockets :

        pairsByExchange.forEach((exchangeName, pairsCollection)->{
            if (Arrays.asList(NEED_PRODUCT_REGISTRATION).contains(exchangeName)) {
                pairsCollection.pairs.forEach(pair->{
                    StreamingExchange exchange = getStreamingExchange(exchangeName);
                    ProductSubscription productSubscription = ProductSubscription.create()
                        .addOrderbook(pair)
                        .build();
                    exchange.connect(productSubscription).blockingAwait();
                    subscribeOrderBook(exchange, pair);
                });
            } else {
                StreamingExchange exchange = getStreamingExchange(exchangeName);
                exchange.connect().blockingAwait();
                pairsCollection.pairs.forEach(pair->subscribeOrderBook(exchange, pair));
            }
        });

Basicamente o primeiro if verifica se o nome da exchange está no array NEED_PRODUCT_REGISTRATION (que contém gdax, binance, talvez outras exchanges apareçam) e se estiver se conecta ao websocket passando a assinatura do produto. Como isso é tratado eu não sei exatamente, mas vamos dar uma olhada no código-fonte aqui:

Aqui a classe ProductSubscription

Aqui como é usado, por exemplo, em BinanceStreamingExchange.java

    private BinanceStreamingService createStreamingService(ProductSubscription subscription) {
        String path = API_BASE_URI + "stream?streams=" + buildSubscriptionStreams(subscription);
        return new BinanceStreamingService(path, subscription);
    }

Até aí tudo bem como você já mencionou, como isso é tratado no xchange-stream não tenho certeza, vejo que a mensagem é tratada na super classe, talvez você possa dar uma olhada e ter mais sorte em entendê-la?

Oi @lfern durante mais testes (tentando manter muitas conexões vivas por um longo período), encontrei mais problemas:

  • bitstamp, ws para btc/usd parece assinar, mas nenhum valor é retornado. Veja a documentação do bitstamp websocket , para qualquer outro par além de btc/usd, o nome do canal é order_book_{currency_pair} , mas para btc/usd não é order_book_btcusd , mas simplesmente order_book .
  • bitstamp: datetime é sempre: 1970-01-18T20:58:45.806Z
  • bitfinex: datetime e timestamp são ambos nulos
  • bitfinex: valores de volume para pedidos são retornados com valores negativos, por exemplo -240, esperado: 240
  • cex parece ser bastante instável: testei muitas conexões e cex é a que mais desconecta. Os websockets Cex precisam ser autenticados. Se você quiser testar isso e não tiver uma conta, você pode se registrar em cex.io Eu sei que pode não ser um problema de sua implementação, mas seria bom ter um exemplo mostrando como reconectar. Estou trabalhando nisso em python e ainda não consegui encontrar uma solução para isso.

Em geral, verifique o timestamp e datetime, até agora um trabalho muito bom!
Obrigado novamente e abração

Obrigado @firepol pelo feedback.

  • problemas de assinatura de data e hora de bitstamp e btc/usd foram corrigidos
  • Não consigo encontrar informações de carimbo de data/hora nas mensagens do livro de pedidos da bitfinex. Então prefiro não preencher esses valores com hora local.
  • os valores negativos do bitfinex também são corrigidos.
  • Vou adicionar um novo exemplo com exemplo de reconexão. Talvez tenhamos que alterar o relatório de erros com mensagens de erro mais detalhadas.

Olá @lfern ,

Eu verifiquei seu último commit , mas a mensagem de commit é enganosa, pois diz "bitfinex", mas o arquivo mudou bitstamp.js. Eu acho que você esqueceu de incluir as alterações do bitfinex ou confundiu o bitstamp com as alterações do bitfinex que você estava prestes a confirmar?

Sobre lidar com desconexões, tentei tentar algo no meu projeto (que aliás já salva dados em um banco de dados, eu uso Postgres, mas você pode testar também com SQLite). Eu criei uma exceção personalizada (WsError), que eu levanto em: https://github.com/firepol/ccxt-websockets-db-updater/blob/master/utils.py :

    @exchange.on('err')
    async def websocket_error(err, conxid):  # pylint: disable=W0612
        error_message = type(err).__name__ + ":" + str(err)
        error_stack = traceback.extract_stack()
        logging.error(f'{exchange.id}: {error_message}')
        logging.error(error_stack)
        print(f'{exchange.id}, {datetime.datetime.now()}, {error_stack}')
        await exchange.close()

E pegue aqui: https://github.com/firepol/ccxt-websockets-db-updater/blob/master/ob_updater.py

    except WsError as wse:
        print(f'Canceling: {wse}')
        ob_subscriptions[wse].cancel()

Tenho certeza que estou fazendo algo errado, ainda sou um noob em programação assíncrona em python.

Idealmente, eu gostaria que o programa ob_updater.py capturasse a exceção por troca (é por isso que adicionei as tarefas em um dicionário, da seguinte maneira:

            # make a list of tasks by exchange id
            ob_subscriptions[exchange.id] = asyncio.ensure_future(utils.subscribe_ws('ob', exchange, symbols, limit,
                                                     pp, args.debug, args.verbose, session))

A ideia era então cancelar corretamente a tarefa (que acho que não está sendo cancelada corretamente agora, pois reclama que teve que ser aguardada) e depois criar uma nova da mesma troca. Isso seria o melhor.

Se você puder incluir isso em seus exemplos de repositório, tentarei aprender com isso e aplicar ao meu projeto separado. Saúde

adicionados novos exemplos para recuperação de erro de websocket.

  • websocket-recover-connection.js
  • websocket-recover-connection.py

@firepol , o que você acha do processo de recuperação? Talvez pudesse ser mais fácil.

Oi @lfern , tentei rapidamente seu novo exemplo em python: /websocket-recover-connection.py (troca: cex, passei minha chave/segredo de API, pares: apenas 'BTC/USD'

subscribe: BTC/USD
KeyError:'ok'
  File "/home/firepol/env/ccxtws/lib/python3.6/site-packages/ccxt/async_support/base/exchange.py", line 711, in websocket_connection_message
    self._websocket_on_message(conxid, msg)
  File "/home/firepol/env/ccxtws/lib/python3.6/site-packages/ccxt/async_support/cex.py", line 563, in _websocket_on_message
    getattr(self, method)(contextId, msg, oid, resData)
unsubscribing all ...
  File "/home/firepol/env/ccxtws/lib/python3.6/site-packages/ccxt/async_support/cex.py", line 570, in _websocket_handle_auth
unsubscribe: BTC/USD
    if msg['ok'] == 'ok':
ExchangeError:not recoverable error
unsubscribing all ...
unsubscribe: BTC/USD

Como diz o erro, parece que não há chave 'ok' na msg. Você tentou isso em python, com cex?

Incrível trabalho e ramo @lfern , muito obrigado.
Em relação ao 'ob', é possível obter apenas o primeiro instantâneo e depois as atualizações conforme elas vêm, não tudo (por exemplo, com uma opção)? Vejo no código (pelo menos, ao imprimir no meio do caminho as mensagens recebidas da exchange) que o patch de dados é feito pelo código ccxt.
Muito Obrigado

Desculpe @firepol , não testei com o CEX, preciso concluir o processo de verificação do CEX para gerar uma nova chave de API. Testado com bitfinex2, gemini e bitstamp

Obrigado @maayank , acho que precisamos manter uma cópia do livro de pedidos dentro do ccxt, para que você possa obter uma cópia do livro de pedidos ao invocar o método websocketFetchOrdebook. Pode ser possível adicionar um atributo adicional ao objeto de evento 'ob' com as últimas alterações recebidas (como o atributo 'info' ccxt com a resposta original recebida da troca nos métodos CCXT REST). Mas algumas trocas sempre enviam um instantâneo (por exemplo, bitstamp). Nesses casos, o ccxt apenas substitui a cópia interna do livro de pedidos por uma nova.

Não é difícil adicionar este novo parâmetro 'info' com os últimos pedidos/lances recebidos (preço/valor), ou poderíamos definir um novo evento 'rawob' que envia apenas snapshot e atualizações, mas antes de adicionar isso eu gostaria de saber o que as outras pessoas pensam sobre isso.

Em relação ao 'ob', é possível obter apenas o primeiro instantâneo e depois as atualizações conforme elas vêm, não tudo (por exemplo, com uma opção)? Vejo no código (pelo menos, ao imprimir no meio do caminho as mensagens recebidas da exchange) que o patch de dados é feito pelo código ccxt.
Muito Obrigado

@lfern é o seu script aqui (https://github.com/lfern/ccxt/blob/feature/websockets-multiple/examples/py/websocket-orderbook.py) pode ser executado de forma independente?

adicionado suporte websocket cobinhood: orderbook/trade/ticker/ohlcv

@mishaker Sim, você pode executar este exemplo para imprimir uma tabela simples de lances/pedidos do livro de pedidos ao vivo. É um script de console, e só testei no windows/cygwin, mas acho que teria que funcionar no console linux.

@lfern é o seu script aqui (https://github.com/lfern/ccxt/blob/feature/websockets-multiple/examples/py/websocket-orderbook.py) pode ser executado de forma independente?

@lfern talvez uma pergunta noob, mas tenho este erro ao tentar executar seu script:

Task exception was never retrieved
future: <Task finished coro=<subscribe() done, defined at example.py:67> exception=AttributeError("'binance' object has no attribute 'on'",) created at example.py:64>
source_traceback: Object created at (most recent call last):
  File "example.py", line 194, in <module>
    main()
  File "example.py", line 64, in main
    asyncio.ensure_future(subscribe (ex, exchange['symbols'], config['symbolDefaults']), loop=loop)
Traceback (most recent call last):
  File "example.py", line 69, in subscribe
    @exchange.on('err')
AttributeError: 'binance' object has no attribute 'on'

Talvez eu deva incluir algo antes de executar o script?

Desculpe @mishaker. Eu não estou cometendo código python transpilado. Portanto, você deve executar npm run trasnspile antes de executar qualquer script python do websocket.

suporte websocket upbit adicionado: orderbook/trade/ticker

Olá, como posso obter pedidos por hora para a casa de câmbio binance?
Como posso obter pedidos com carimbo de data/hora?
Existe um método ccxt?

@lfern algumas novidades do meu lado: atualizei meu repositório e agora funciona muito bem. Deixei rodando uma noite inteira em uma VM com 2 CPUs e 2 GB de ram e não tive (aparente) desconexão do websocket ... o disco rígido estava girando bastante, devo dizer, então considerarei uma configuração em que o banco de dados está na memória, SQLlite tem esse recurso.

Compartilhando um pequeno problema: notei alguns conflitos se o binance e o cexio fossem executados ao mesmo tempo. Basicamente, não há problema em executar muitas exchanges e binance. Mas se eu executar apenas cexio + binance, o binance recebe alguns erros. Eu tive que desabilitar a captura de erros por causa disso. Também não capturar esses erros não tem efeito e tudo é atualizado, então não sei por que recebo esses eventos de erro. talvez você possa dar uma olhada se puder reproduzi-lo do seu lado também? Eu criei um problema no meu repo: https://github.com/firepol/ccxt-websockets-db-updater/issues/4 vou adicionar o erro de pilha, mas se você tentar meu repo usando o --verbose e opções --debug você notará imediatamente.

Para mudar de tópico: Eu queria saber se você também pode adicionar suporte a websockets para bittrex ? Ficarei feliz em fazer mais testes e mais trocas, melhor.

Cara de trabalho incrível, eu amo o recurso de websockets, ansioso para que ele seja mesclado no mestre!

Aliás, como você não comete o código transpilado do python no repo, criei um repo que leva apenas os arquivos python (transpilados), para facilitar o uso no meu repo: https://github.com/firepol/ccxt-websockets
(talvez um projeto paralelo seja automatizar isso, então, em cada atualização do seu lado, um pipeline do Travis transpilará o código e atualizará meu repositório sem que eu faça isso manualmente ...).

@lfern , em relação ao bitfinex e timestamps, eles enviam timestamps se você enviar um evento "conf" na assinatura com o sinalizador apropriado (grep for "Timestamp in milissegundos." em
https://docs.bitfinex.com/v2/docs/ws-general
).
(também @firepol , pelo que vejo ele levantou)
Eu posso escrever um patch e enviá-lo para sua filial, ou se for mais fácil para você alterar apenas FYI.

@maayank , adicionado tratamento de carimbo de data/hora do livro de pedidos agora.

@firepol , desculpe !!!, estou tentando conseguir algum tempo esta semana para verificar seu problema e adicionar suporte ao bitrex

@firepol Acabei de adicionar suporte websocket ao bittrex. Essa exchange usa o signalr e está usando nossa implementação interna de websocket (talvez seja necessário criar uma nova classe de websocket para o signalr posteriormente). Testei hoje à tarde e está funcionando perfeitamente.

Eu encontrei um problema de transpilação PHP:
Este código javascript

'connectionData': '[{"name":"c2"}]',

é transpilado para PHP assim

'connectionData' => [array ("name":"c2")]'

Vou mesclar ccxt/master a este branch para verificar se foi corrigido.

Olá @lfern thx por implementar o bittrex! Testei e funciona!

Talvez a próxima grande troca possa ser kraken? Eu li que eles adicionaram recentemente suporte ao websocket: https://blog.kraken.com/post/2019/websockets-public-api-launching-soon/

Ele será lançado oficialmente em alguns dias, mas é possível testá-lo já usando o sandbox.

suporte websocket no kraken. No momento, apenas o URL do websocket do sandbox está ativo. Para testá-lo agora, você precisa alterar a configuração de baseurl para sandboxurl.

Você pode me dizer quanto dinheiro eu tenho? Obrigado!

Ei pessoal! Em primeiro lugar, @lfern @firepol - obrigado por impulsionar esta grande iniciativa como WS, acho que toda a comunidade ccxt está muito animada com isso.

Eu estava tentando mergulhar nele. E eu tenho os seguintes resultados. Primeiro, comecei com este script: https://github.com/lfern/ccxt/blob/feature/websockets-multiple/examples/py/websocket-orderbook.py
e acabou de sair sem saída:

v:py fcl$ python3 websocket-orderbook.py
v:py fcl$

Então eu continuei com este repositório - https://github.com/firepol/crypto-websockets
configure APIs, configurações, pasta de dados, etc. Então ele é executado, mas nenhuma saída, nenhuma atividade, e o banco de dados está vazio:

v:ccxt-websockets-db-updater fcl$ ./ob_tester.py -e binance -s ETH/BTC --debug
^CCFechando Loop
Depois de concluído
v:ccxt-websockets-db-updater fcl$ cat cryptows.db
???N!!?gtableorder_bookorder_bookCREATE TABLE order_book (
id INTEIRO NÃO NULO,
exchange_name VARCHAR(20) NOT NULL,
base VARCHAR(10) NOT NULL,
citação VARCHAR(10) NOT NULL,
lado VARCHAR(3) NOT NULL,
preço DECIMAL NÃO NULO,
volume DECIMAL NÃO NULO,
classificar INTEGER NOT NULL,
datetime DATETIME NOT NULL,
CHAVE PRIMÁRIA (id)

Eu apreciaria se você pudesse me indicar a direção para depurá-lo corretamente.

Oi @Fcl69 , no websocket-multiple branch os módulos python não são transpilados do código do nó. Se você tentar este exemplo:

 python3 examples/py/websocket-playground.py kraken ob ETH/XTC limit:1

e você obtém algo assim:

Task exception was never retrieved
future: <Task finished coro=<main() done, defined at examples/py/websocket-playground.py:19> exception=ExchangeError('Not valid event ob for exchange kraken',)>
Traceback (most recent call last):
  File "examples/py/websocket-playground.py", line 58, in main
    await exchange.websocket_subscribe(event, symbol, params)
  File "c:\users\luis\documents\projects\ccxt\python\ccxt\async_support\base\exchange.py", line 826, in websocket_subscribe
    raise ExchangeError('Not valid event ' + event + ' for exchange ' + self.id)
ccxt.base.errors.ExchangeError: Not valid event ob for exchange kraken
kraken requires to release all resources with an explicit call to the .close() coroutine. If you are creating the exchange instance from within your async coroutine, add exchange.close() to your code into a place when you're done with the exchange and don't need the exchange instance anymore (at the end of your async coroutine).
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000022292D4C860>

então você tem que transpilar o código com:

npm run transpile

e então você obtém todo o código python pronto para testar.

websocket-orderbook.py script limpa a tela do console para atualizar os dados da carteira de pedidos conforme são recebidos das exchanges, talvez essa limpeza tenha removido o erro de stacktrace impresso.

diz:
v:ccxt fcl$ npm executar transpile

[email protected] transpile /Users/v.golban/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt
nó transpilar

internal/modules/cjs/loader.js:611
jogar errar;
^

Erro: Não é possível encontrar o módulo 'ololog'
em Function.Module._resolveFilename (internal/modules/cjs/loader.js:609:15)
em Function.Module._load (internal/modules/cjs/loader.js:535:25)
em Module.require (internal/modules/cjs/loader.js:663:17)
at require (internal/modules/cjs/helpers.js:20:18)
em Objeto.(/Users/v.golban/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt/transpile.js:5:14)
em Module._compile (internal/modules/cjs/loader.js:734:30)
em Object.Module._extensions..js (internal/modules/cjs/loader.js:745:10)
em Module.load (internal/modules/cjs/loader.js:626:32)
em tryModuleLoad (internal/modules/cjs/loader.js:566:12)
em Function.Module._load (internal/modules/cjs/loader.js:558:3)
npm ERR! código ELIFECYCLE
npm ERR! erro 1
npm ERR! [email protected] transpilar: node transpile
npm ERR! Sair do estado 1
npm ERR!
npm ERR! Falha no script de transpilação [email protected].
npm ERR! Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.
npm WARN Local package.json existe, mas node_modules está faltando, você pretendia instalar?

npm ERR! Um log completo desta execução pode ser encontrado em:
npm ERR! .npm/_logs/2019-01-31T22_15_59_360Z-debug.log

e então:

v:ccxt fcl$ cat .npm/_logs/2019-01-31T21_11_25_875Z-debug.log
0 info funcionou se terminar com ok
1 cli verbose [ '/usr/local/Cellar/node/11.9.0/bin/node',
1 cli verbose '/usr/local/bin/npm',
1 cli verbose 'executar',
1 verbose cli 'transpilar']
2 informações usando [email protected]
3 informações usando [email protected]
4 script de execução detalhado [ 'pretranspile', 'transpile', 'posttranspile' ]
5 informações sobre o ciclo de vida [email protected] ~pré-transpilar: [email protected]
6 informações do ciclo de vida [email protected] ~transpile: [email protected]
7 ciclo de vida detalhado [email protected] ~transpile: unsafe-perm in lifecycle true
8 ciclo de vida detalhado [email protected] ~transpile: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/Documents/_personal/_work/ccwd/bin/ccwd /ccxt_lfern/ccxt/node_modules/.bin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ local/share/dotnet:~/.dotnet/tools
9 ciclo de vida detalhado [email protected] ~transpile: CWD: ccxt_lfern/ccxt
10 ciclo de vida bobo [email protected] ~transpile: Args: [ '-c', 'node transpile' ]
11 ciclo de vida bobo [email protected] ~transpile: Retornado: código: 1 sinal: nulo
12 info lifecycle [email protected] ~transpile: Falha ao executar script de transpilação
13 pilha detalhada Erro: [email protected] transpile: node transpile
13 pilha detalhada Status de saída 1
13 pilha detalhada em EventEmitter.(/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
13 pilha detalhada em EventEmitter.emit (events.js:197:13)
13 pilha detalhada em ChildProcess.(/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 pilha detalhada em ChildProcess.emit (events.js:197:13)
13 pilha detalhada em mayClose (internal/child_process.js:978:16)
13 pilha detalhada em Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)
14 pacotes detalhados [email protected]
15 verbose cwd ccxt_lfern/ccxt
16 verboso Darwin 16.7.0
17 verbose argv "/usr/local/Cellar/node/11.9.0/bin/node" "/usr/local/bin/npm" "run" "transpile"
18 nó detalhado v11.9.0
19 verbose npm v6.5.0
20 código de erro ELIFECYCLE
21 erro errno 1
22 erro [email protected] transpile: node transpile
22 erro Status de saída 1
23 error Falha no script de transpile [email protected].
23 error Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.
24 saída detalhada [ 1, true ]

Desculpe, acho que você deve executar npm install primeiro para instalar os módulos do nó.

foi mal
mas então:
v:ccxt fcl$ npm executar transpile

[email protected] transpile /Users/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt
nó transpilar

internal/modules/cjs/loader.js:611
jogar errar;
^

Erro: não é possível encontrar o módulo './exchanges.json'
em Function.Module._resolveFilename (internal/modules/cjs/loader.js:609:15)
em Function.Module._load (internal/modules/cjs/loader.js:535:25)
em Module.require (internal/modules/cjs/loader.js:663:17)
at require (internal/modules/cjs/helpers.js:20:18)
em transpileDerivedExchangeFiles (/Users/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt/transpile.js:717:17)
em Objeto.(/Users/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt/transpile.js:958:17)
em Module._compile (internal/modules/cjs/loader.js:734:30)
em Object.Module._extensions..js (internal/modules/cjs/loader.js:745:10)
em Module.load (internal/modules/cjs/loader.js:626:32)
em tryModuleLoad (internal/modules/cjs/loader.js:566:12)
npm ERR! código ELIFECYCLE
npm ERR! erro 1
npm ERR! [email protected] transpilar: node transpile
npm ERR! Sair do estado 1
npm ERR!
npm ERR! Falha no script de transpilação [email protected].
npm ERR! Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.

npm ERR! Um log completo desta execução pode ser encontrado em:
npm ERR! .npm/_logs/2019-01-31T23_08_18_442Z-debug.log

Desculpe de novo! executar
npm run export-exchanges
Se não funcionar, execute a compilação completa:
npmrun build

hm... Desculpe cutucá-lo, mas não ajuda. construção falha em

v:ccxt fcl$ npm executar compilação
.....
Transpilando de ./js/test/base/functions/test.datetime.js (transpileDateTimeTests @ transpile.js:859)

→ ./python/test/test_exchange_datetime_functions.py (transpileDateTimeTests @ transpile.js:883)
→ ./php/test/test_exchange_datetime_functions.php (transpileDateTimeTests @ transpile.js:884)
Transpilando ./python/test/test_async.py → ./python/test/test.py (transpilePythonAsyncToSync @ transpile.js:778)
Transpilado com sucesso. (@transpile.js:975)

[email protected] qa /Users/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt
npm execute check-python-syntax && npm execute check-php-syntax

[email protected] check-python-syntax /Users/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt
cd python && tox -e qa && cd ..

sh: tox: comando não encontrado
npm ERR! arquivo sh
npm ERR! código ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! spawn de syscall
npm ERR! [email protected] check-python-sintax: cd python && tox -e qa && cd ..
npm ERR! gerar ENOENT
npm ERR!
npm ERR! Falha no script [email protected] check-python-syntax.
npm ERR! Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.

npm ERR! Um log completo desta execução pode ser encontrado em:
npm ERR! /Users/.npm/_logs/2019-02-01T02_38_44_448Z-debug.log
npm ERR! código ELIFECYCLE
npm ERR! erro 1
npm ERR! [email protected] qa: npm run check-python-syntax && npm run check-php-syntax
npm ERR! Sair do estado 1
npm ERR!
npm ERR! Falha no script [email protected] qa.
npm ERR! Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.

npm ERR! Um log completo desta execução pode ser encontrado em:
npm ERR! /Users/.npm/_logs/2019-02-01T02_38_44_481Z-debug.log
npm ERR! código ELIFECYCLE
npm ERR! erro 1
npm ERR! [email protected] build-without-docs: npm run export-exchanges && npm run vss && npm run check-js-syntax && npm run browserify && npm run transpile && npm run qa
npm ERR! Sair do estado 1
npm ERR!
npm ERR! Falha no script [email protected] build-without-docs.
npm ERR! Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.

npm ERR! Um log completo desta execução pode ser encontrado em:
npm ERR! /Users/.npm/_logs/2019-02-01T02_38_44_510Z-debug.log
npm ERR! código ELIFECYCLE
npm ERR! erro 1
npm ERR! [email protected] compilação: npm run build-without-docs && npm run pandoc-all && npm run update-badges
npm ERR! Sair do estado 1
npm ERR!
npm ERR! Falha no script de compilação [email protected] .
npm ERR! Isso provavelmente não é um problema com o npm. Provavelmente há saída de log adicional acima.

npm ERR! Um log completo desta execução pode ser encontrado em:
npm ERR!

e isso me leva à situação que você mencionou:

v:ccxt fcl$ python3 exemplos/py/websocket-playground.py kraken ob ETH/XTC limit:1
A exceção de tarefa nunca foi recuperada
futuro:exception=AttributeError("O objeto 'kraken' não tem atributo 'on'",)>
Traceback (última chamada mais recente):
Arquivo "examples/py/websocket-playground.py", linha 43, em main
@exchange.on('err')
AttributeError: objeto 'kraken' não tem atributo 'on'
kraken requer liberar todos os recursos com uma chamada explícita para a corrotina .close(). Se você estiver criando a instância de troca de dentro de sua corrotina assíncrona, adicione exchange.close() ao seu código em um local quando terminar a troca e não precisar mais da instância de troca (no final da sua corrotina assíncrona ).
Sessão de cliente não fechada
client_session:

@Fcl69 verifique se o arquivo exchanges.json foi gerado na pasta ccxt. Se sim, tente novamente

npm run transpile

Estas são as trocas atuais que suportam a conexão websocket do livro de pedidos:

  • binance
  • bitfinex2
  • bitmex
  • carimbo de bits
  • bittrex
  • cex
  • cobinhood
  • cheque de moedas
  • coinbaseprime
  • coinbasepro
  • portão
  • Gêmeos
  • hadax
  • hitbtc2
  • huobipro
  • kraken
  • banco
  • líquido
  • okex
  • poloniex
  • o oceano
  • a rocha
  • upbit
  • zb

Por favor, alguém sabe de quem serão as próximas trocas?

É totalmente incrível ver o que vocês conseguiram aqui - obrigado por isso.

Como vocês todos (especialmente @lfern e @kroitor) pensam em ir maior com esse projeto? É um pouco cansativo ver tudo isso tratado em um tópico de problema. Talvez uma página wiki com o que já está funcionando e o que não está e talvez um tutorial aproximado ou algo assim possa ser útil.

Mais uma vez obrigado por seu trabalho duro!

@lfern

exchanges.json está lá:

v:ccxt fcl$ ls exchanges.json
exchanges.json

"npm run transpile" vai bem:

v:ccxt fcl$ npm executar transpile

[email protected] transpile /Users/Documents/_personal/_work/ccwd/bin/ccwd/ccxt_lfern/ccxt
nó transpilar

Transpilando de _1btcxe.js (transpileDerivedExchangeFile @ transpile.js:696)
Transpilando de acx.js (transpileDerivedExchangeFile @ transpile.js:696)
Transpilando de allcoin.js (transpileDerivedExchangeFile @ transpile.js:696)
....

Transpilando de zaif.js (transpileDerivedExchangeFile @ transpile.js:696)
Transpilando de zb.js (transpileDerivedExchangeFile @ transpile.js:696)
Transpilando de ./js/test/base/functions/test.number.js (transpilePrecisionTests @ transpile.js:896)
→ ./python/test/test_decimal_to_precision.py (transpilePrecisionTests @ transpile.js:945)
→ ./php/test/decimal_to_precision.php (transpilePrecisionTests @ transpile.js:946)
Transpilando de ./js/test/base/functions/test.datetime.js (transpileDateTimeTests @ transpile.js:859)
→ ./python/test/test_exchange_datetime_functions.py (transpileDateTimeTests @ transpile.js:883)
→ ./php/test/test_exchange_datetime_functions.php (transpileDateTimeTests @ transpile.js:884)
Transpilando ./python/test/test_async.py → ./python/test/test.py (transpilePythonAsyncToSync @ transpile.js:778)
Transpilado com sucesso. (@transpile.js:975)

mas então não funciona de qualquer maneira:

v:ccxt fcl$ python3 exemplos/py/websocket-playground.py kraken ob ETH/XTC limit:1
A exceção de tarefa nunca foi recuperada
futuro:exception=AttributeError("O objeto 'kraken' não tem atributo 'on'",)>
Traceback (última chamada mais recente):
Arquivo "examples/py/websocket-playground.py", linha 43, em main
@exchange.on('err')
AttributeError: objeto 'kraken' não tem atributo 'on'
kraken requer liberar todos os recursos com uma chamada explícita para a corrotina .close(). Se você estiver criando a instância de troca de dentro de sua corrotina assíncrona, adicione exchange.close() ao seu código em um local quando terminar a troca e não precisar mais da instância de troca (no final da sua corrotina assíncrona ).
Sessão de cliente não fechada
client_session:
^CCFechando Loop
depois de concluído
v:ccxt fcl$

OK, @Fcl69 Acho que agora você precisa instalar as dependências do python:

pip3 install -e python

Eu fiz, além de transpilar novamente, mas as mesmas coisas:

v:ccxt fcl$ python3 exemplos/py/websocket-playground.py kraken ob ETH/XTC limit:1
A exceção de tarefa nunca foi recuperada
futuro:exception=AttributeError("O objeto 'kraken' não tem atributo 'on'",)>
Traceback (última chamada mais recente):
Arquivo "examples/py/websocket-playground.py", linha 43, em main
@exchange.on('err')
AttributeError: objeto 'kraken' não tem atributo 'on'
kraken requer liberar todos os recursos com uma chamada explícita para a corrotina .close(). Se você estiver criando a instância de troca de dentro de sua corrotina assíncrona, adicione exchange.close() ao seu código em um local quando terminar a troca e não precisar mais da instância de troca (no final da sua corrotina assíncrona ).
Sessão de cliente não fechada
client_session:

=(

Desculpe @Fcl69 . Eu baixei este branch em uma distribuição linux limpa e com estas etapas configurei meu ambiente de desenvolvimento:

git clone https://github.com/lfern/ccxt.git
cd ccxt/
git checkout -t origin/feature/websockets-multiple
npm install
pip3 install -e python/
npm run transpile
npm run export-exchanges
npm run transpile
python3 examples/py/websocket-playground.py kraken ob ETH/XBT 

Eu tive que atualizar do python3.5 para o python3.6 e instalar o pip3 para esta versão do python, mas se o python3.6 ou superior estiver instalado no seu sistema, ele deve funcionar

@ Fcl69 Acabei de verificar meu projeto (você vinculou meu outro projeto em java btw, o link correto é https://github.com/firepol/ccxt-websockets-db-updater ), corrigi alguns problemas que afetam ob_tester.py e fez um vídeo de demonstração que mostra em ação https://www.youtube.com/watch?v=0UIvIBUiqQQ

Talvez no readme não tenha ficado claro, mas se você não especificar --verbose e nenhuma opção --debug , não haverá saída. Desculpe se não ficou claro. Então, apenas tente configurá-lo como no vídeo, do zero. Se você usa linux como eu, basta copiar/colar o bloco de código de instalação.

Observe também que ob_tester.py não preenche o banco de dados: ele apenas se conecta aos websockets e não faz nada.
ob_updater.py preenche o banco de dados.

Aliás, caso você tenha problemas para usar meu projeto ccxt-websockets-db-updater , sinta-se à vontade para escrever um problema no meu repositório https://github.com/firepol/ccxt-websockets-db-updater e tentarei ajudar você para colocar as coisas em funcionamento.

Além disso, continuo vendo os mesmos problemas, que as pessoas esquecem de ccxt-websockets-db-updater etc.

@lfern Eu tentei huobipro usando a versão mais recente do seu branch, no meu projeto (sinta-se à vontade para experimentá-lo, talvez você possa usá-lo para testar suas alterações em python em um cenário mais avançado), mas não parece funcionar. Não recebo saída.

Veja as instruções em https://github.com/firepol/ccxt-websockets-db-updater (veja também meu vídeo)

Conexão de trabalho (com saída):

./ob_tester.py -e binance -s eth/btc --verbose --debug

Huobipro (não precisa de chaves de API ou precisa?), não está funcionando, talvez você possa dar uma olhada nele?

./ob_tester.py -e huobipro -s eth/btc --verbose --debug

Kraken, mesmo, sem erro, mas sem saída:

./ob_tester.py -e kraken -s btc/usd --verbose --debug

Esperado: veja a saída de websockets, como em binance. Resultado: nada...

Ideias?

@lfern @firepol Consegui iniciar o script usando uma configuração diferente.

Muito obrigado por sua ajuda. Vou continuar cavando.

@firepol Huobipro tem alguns erros de transpilação e o método exchange.py gunzip estava errado. Parece que agora está funcionando bem.

Ei @lfern , dois problemas com o Poloniex:

  1. Em poloniex.js:1191, há um erro que passa para python onde channelId não é convertido em string e contextId não é passado para emit(). Assim, deve ser:
    1191 this.emit ('err', new ExchangeError (this.id + '._websocketOnMessage() failed to get symbol for channelId: ' + channelId.toString ()), contextId);

  2. Encontrei o acima como parte de outro problema em que não consigo assinar BTC/USD ou BTC/USDT. Eu recebo, por exemplo:
    ExchangeError: poloniex._websocketOnMessage() failed to get symbol for channelId: 121

Deixe-me saber se há mais alguma coisa que eu possa verificar.
Saúde

Muito obrigado pelo esforço que foi feito neste ramo! Existe um readme para o ramo origin/feature/websockets-multiple ?

Eu tenho que funcionar, mas queria saber o que era a API? Especificamente,

  • quais são os valores válidos para o parâmetro event para websocketSubscribe ? _(parece 'ob', mais alguma coisa é suportada?_
  • como usar o método websocketFetchOrderBook ?
  • os dados no callback do livro de pedidos para bitfinex têm todo o livro de pedidos. Este é um formato comum para todas as trocas?

Além disso, notei que o método updateBidAsk parece problemático, pois os lances/pedidos são armazenados em uma matriz. Para livros de pedidos ocupados, será necessário pesquisar bastante para garantir que os itens sejam armazenados na ordem correta. Acho que substituir o array por uma árvore binária seria uma solução muito mais eficiente.

Oi @npomfret todos os créditos vão do @lfern e demais colaboradores, sou apenas um "consumidor" desse ramo também. Mas deixe-me ajudá-lo, pois tenho alguns minutos para usar;)

Sim, existe um leia-me e acredito que você pode encontrar algumas respostas lendo-o:

https://github.com/lfern/ccxt/blob/feature/websockets-multiple/WEBSOCKETS.md

Recursos Ws:

  • obs: livro de pedidos
  • ti: tickers
  • tr: comércios
  • oh: ohlcv

Outras perguntas não posso ajudar, mas até lá você tem algo para ler. Espero ter ajudado, abraços

Obrigado @maayank , deixe-me verificar

Ei @lfern , dois problemas com o Poloniex:

  1. Em poloniex.js:1191, há um erro que passa para python onde channelId não é convertido em string e contextId não é passado para emit(). Assim, deve ser:
    1191 this.emit ('err', new ExchangeError (this.id + '._websocketOnMessage() failed to get symbol for channelId: ' + channelId.toString ()), contextId);
  2. Encontrei o acima como parte de outro problema em que não consigo assinar BTC/USD ou BTC/USDT. Eu recebo, por exemplo:
    ExchangeError: poloniex._websocketOnMessage() failed to get symbol for channelId: 121

Deixe-me saber se há mais alguma coisa que eu possa verificar.
Saúde

@npomfret , a função websocketFetchOrderBook retorna uma cópia do livro de pedidos interno atual gerenciado pela exchange. Eu acho que esta função não é a melhor maneira de obter informações da carteira de pedidos, é melhor ouvir os eventos 'ob' emitidos à medida que recebe atualizações da conexão websocket. Você pode encontrar alguns exemplos na pasta de exemplos em linguagem python, js e php (arquivos com prefixo "websocket-").

Sobre o formato do livro de encomendas, acho que todos têm um formato semelhante. Alguns deles permitem que você escolha a profundidade para receber atualizações até essa profundidade. Em alguns casos você tem que obter um snapshot usando a API REST e receber atualização das conexões websocket... De qualquer forma, cada implementação de exchange tenta gerenciar uma cópia interna do exchange orderbook e emitir eventos 'ob' para o assinante quando alguma atualização é recebida.

E sim, você está certo sobre como atualizar askd/bids na matriz ordenada. Desde o início esta era uma tarefa que tínhamos que melhorar, mas queríamos verificar se a forma como estávamos implementando websockets funcionaria bem.

Muito obrigado pelo esforço que foi feito neste ramo! Existe um readme para o ramo origin/feature/websockets-multiple ?

Eu tenho que funcionar, mas queria saber o que era a API? Especificamente,

  • quais são os valores válidos para o parâmetro event para websocketSubscribe ? _(parece 'ob', mais alguma coisa é suportada?_
  • como usar o método websocketFetchOrderBook ?
  • os dados no callback do livro de pedidos para bitfinex têm todo o livro de pedidos. Este é um formato comum para todas as trocas?

Além disso, notei que o método updateBidAsk parece problemático, pois os lances/pedidos são armazenados em uma matriz. Para livros de pedidos ocupados, será necessário pesquisar bastante para garantir que os itens sejam armazenados na ordem correta. Acho que substituir o array por uma árvore binária seria uma solução muito mais eficiente.

@maayank Acho que o poloniex está corrigido. Por favor, confira

Ei @lfern , dois problemas com o Poloniex:

  1. Em poloniex.js:1191, há um erro que passa para python onde channelId não é convertido em string e contextId não é passado para emit(). Assim, deve ser:
    1191 this.emit ('err', new ExchangeError (this.id + '._websocketOnMessage() failed to get symbol for channelId: ' + channelId.toString ()), contextId);
  2. Encontrei o acima como parte de outro problema em que não consigo assinar BTC/USD ou BTC/USDT. Eu recebo, por exemplo:
    ExchangeError: poloniex._websocketOnMessage() failed to get symbol for channelId: 121

Deixe-me saber se há mais alguma coisa que eu possa verificar.
Saúde

Obrigado @lfern e @firepol

Eu usei árvores binárias para implementar livros de pedidos antes, é muito simples. Acho que o pacote que mencionei é o que o coinbasepro usa em seu site.

Funciona bem. Como sempre, muito obrigado @lfern :)

oi, estou tentando encontrar alguns exemplos de como se conectar ao websocket para bitmex em python. Fico feliz em ajudar a adicionar funcionalidades para trocas, se necessário. de qual branch devo começar para obter os exemplos de python mais atualizados?

Oi @furryboffin confira isso: https://github.com/lfern/ccxt/tree/feature/websockets-multiple

Exemplos etc. leia aqui: https://github.com/lfern/ccxt/blob/feature/websockets-multiple/WEBSOCKETS.md

Leia "Antes de testar em python ou PHP" (você precisa transpilar para gerar os arquivos python).

Para sua conveniência, criei um repositório git contendo (já transpilado) o código mais recente do branch do lfern: https://github.com/firepol/ccxt-websockets

Aproveitar

Oi,

Encontrando o erro 'CloudFlare', ao deixar o código rodar por várias horas. Isso foi reproduzido várias vezes. Estou executando o código de exemplo do python:

example/py/websocket-playground.py kraken ob ETH/XBT

  1. Por favor, pergunte se existe um mecanismo implementado (ou planejado) destinado a evitar isso? (Eu geralmente li sobre um requisito para algum keepalive, por exemplo, ping?)
  2. Quando ocorre - Qual deve ser a abordagem recomendada para lidar com essa exceção? Um cancelamento de assinatura e uma nova assinatura deve ser bom o suficiente?

Net workError: CloudFlare WebSocket proxy reiniciando
Arquivo "examples/py/websocket-playground.py", linha 64, emloop.run_forever()
Arquivo "/usr/lib/python3.6/asyncio/base_events.py", linha 427, em run_forever self._run_once()
Arquivo "/usr/lib/python3.6/asyncio/base_events.py", linha 1440, em _run_once handle._run()
Arquivo "/usr/lib/python3.6/asyncio/events.py", linha 145, em _run self._callback( self._args)Arquivo "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/autobahn/asyncio/websocket.py", linha 100, em connection_lost self._connectionLost(exc)Arquivo "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/autobahn/websocket/protocol.py", linha 3365, em _connectionLost WebSocketProtocol._connectionLost(self, reason)Arquivo "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/autobahn/websocket/protocol.py", linha 1105, em _connectionLost self._onClose(self.wasClean, self.remoteCloseCode, self .remoteCloseReason)Arquivo "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/autobahn/asyncio/websocket.py", linha 181, em _onClose res = self.onClose(wasClean, code, reason)Arquivo "/home/user/Projects/ccxt/python/ccxt/async_support/websocket/websocket_connection.py", linha 43, em onClose self.event_emitter.emit('err', Exception(reason))Arquivo "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/pyee/__init__.py", linha 151, em emitresultado = f( args, *kwargs)Arquivo "/home/user/Projects/ccxt/python/ccxt/async_support/base/exchange.py", linha 782, em websocket_connection_error self.emit('err', NetworkError(error), conxid)Arquivo "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/pyee/__init__.py", linha 151, em emit result = f( args, **kwargs)
Arquivo "examples/py/websocket-playground.py", linha 47, em websocket_error traceback.print_stack()
Ciclo de fechamento
depois de concluído

Eu gostaria de contribuir, seja através da depuração ou se você puder me indicar a direção geral de investigar isso ...

Saúde!

Olá @aviad21 . Em teoria, o Kraken envia uma mensagem a cada segundo (https://www.kraken.com/features/websocket-api#message-heartbeat) e parece que o CloudFlare pode fechar soquetes após 100 ou 1000 segundos de inatividade, portanto, esse erro não deve tomar lugar. Talvez possamos incluir uma solicitação de ping se não recebermos nenhum pacote em um curto período de tempo.

De qualquer forma, você pode capturar as exceções emitidas pela exchange e decidir o que fazer:

  • sempre tente reconectar imediatamente
  • aguarde algum período de tempo se o erro anterior foi gerado há pouco tempo.

Dê uma olhada em example/py/websocket-recover-connection.py e websocket-recover-connection2.py. Esses scripts simulam um NetworkError e aguardam 5 segundos antes de recuperar a conexão do websocket. Basicamente:

 @exchange.on('err')
    async def websocket_error(err, conxid):
        # log error
...
        # close websocket if necesary
        exchange.websocketClose(conxid)
       # analyze what to do now
        if isinstance(err, ccxt.NetworkError):
            # wait 5 seconds
            await asyncio.sleep(5)
            try:
                # clean current context data
                exchange.websocketCleanContext(conxid)
                # subscribe all symbols again
                await doSubscribe(exchange, symbols, {
                    'limit': limit,
                })
            except Exception as ex:
                print(ex)
                sys.stdout.flush()
        else:
...

Ou você pode tentar um novo método de troca que tenta se reconectar ao websocket e se inscrever novamente no símbolo inscrito (ainda não foi totalmente testado)

async def websocket_error(err, conxid):
        #log error
        if isinstance(err, ccxt.NetworkError):
            # close if necesary
            exchange.websocketClose(conxid)
            #wait 5 seconds
            await asyncio.sleep(5)
            try:
                await exchange.websocketRecoverConxid(conxid)
            except Exception as ex:
                print(ex)
                sys.stdout.flush()
        else:

@lfern , agradeço a resposta, obrigado.
Após várias horas tentando chegar às raízes do problema mencionado acima, posso resumir as seguintes observações:

  • Depois de algum tempo em que tudo está funcionando bem, os eventos websocket_ob() param de ocorrer todos juntos
  • websocket_error() também não é recebido (exceto pelo 'CloudFlare' acima, que aparece como um sintoma do problema real...)
  • Estou inscrito em vários símbolos de uma bolsa específica - quando o problema ocorre, todos os símbolos param de receber atualizações websocket_ob()
  • Isso se reproduz repetidamente em: poloniex (maior taxa de reprodução), huobipro, kraken.
  • Isso ainda não foi reproduzido nas últimas 24 horas em: binance, bitstamp, coinbasepro.
  • (ou seja, cada troca está sendo executada separadamente, em um processo python dedicado. Os processos são executados simultaneamente no mesmo computador. Sem problemas de RAM ou CPU alta...)
  • Isso reproduz tanto no meu pc quanto na instância do GCP, python 3.6.7
  • Estou executando asyincio logando no modo debug, mas não vejo nada de alarmante

Outra dica de que as coisas estão dando errado é observada quando tento me recuperar dessa situação.
Como não há websocket_error() - Após o tempo limite de 60 segundos em que nada é recebido, tento executar: websocketClose() , depois websocketCleanContext() , asyncio.sleep(5) e finalmente doSubscribe() , como você mencionou acima.

Uma primeira exceção é gerada ao emitir websocketClose() :

2019-03-15 13:09:54,345 - INFO: handle_log: websocketClose conxid: default
2019-03-15 13:09:54,345 - ERROR: handle_log: GENERIC (non ccxt.BaseError) exception while websocketClose: 'NoneType' object has no attribute 'close'
Traceback (most recent call last):
  File "examples/py/websocket-generic-orderbook-poloniex.py", line 107, in handle_log
    exchange_ctx.websocketClose(conxid)
  File "/home/user/Projects/ccxt/python/ccxt/async_support/base/exchange.py", line 728, in websocketClose
    websocket_conx_info['conx'].close()
  File "/home/user/Projects/ccxt/python/ccxt/async_support/websocket/websocket_connection.py", line 107, in close
    self.client._closeConnection(True)
  File "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/autobahn/asyncio/websocket.py", line 128, in _closeConnection
    self.transport.close()
AttributeError: 'NoneType' object has no attribute 'close'

E então, ao atingir a execução doSubscribe() , ocorre outra exceção. É devido à chamada _websocket_ensure_conx_active() do exchange.py, tentando novamente fechar a conexão:

2019-03-15 13:09:59,388 - ERROR: exception close location 002: 'NoneType' object has no attribute 'close'
Traceback (most recent call last):
  File "/home/user/Projects/ccxt/python/ccxt/async_support/base/exchange.py", line 652, in _websocket_ensure_conx_active
    conx.close()
  File "/home/user/Projects/ccxt/python/ccxt/async_support/websocket/websocket_connection.py", line 107, in close
    self.client._closeConnection(True)
  File "/home/user/Projects/ccxt/venv/lib/python3.6/site-packages/autobahn/asyncio/websocket.py", line 128, in _closeConnection
    self.transport.close()
AttributeError: 'NoneType' object has no attribute 'close'

Quando adiciono um try-except nas tentativas close() em _websocket_ensure_conx_active() , consigo recuperar do estado e assinar novamente.
Infelizmente ... o problema continua ocorrendo de vez em quando (por exemplo, no Poloniex pode ser uma vez em 30 minutos ou mais, no huobi e kraken observado uma vez em várias horas ...) - então eu preciso entender a causa real e resolver isto.
Alguma dica de como posso depurar ainda mais isso?

Oi @aviad21 quando você diz que executa os processos simultaneamente, posso perguntar se você faz isso da mesma forma que eu faço no meu programa (baseado em lfern branch) https://github.com/firepol/ccxt-websockets-db-updater (veja ob_updater.py Eu uso um arquivo .py e assíncrono para fazer o loop de todas as trocas e todos os pares)? Seria interessante saber se você pode reproduzir o problema também usando meu ob_updater.py...

Olá @firepol

quando você diz que executa os processos simultaneamente, posso perguntar se você faz isso da mesma forma que eu faço no meu
programa...

Eu quis dizer que estou executando vários scripts python simultaneamente, cada um lançado de forma independente:

python examples/py/websocket-generic-orderbook-krken.py &
python examples/py/websocket-generic-orderbook-poloniex.py &
python examples/py/websocket-generic-orderbook-huobipro.py &

(cada um deles é baseado no exemplo ccxt\examples\py\websocket-playground.py )

Ei @lfern , acredito que há um bug com o póloniex ou a classe base/exchange do python. Atualmente não atualiza a carteira de pedidos ao excluir atualizações, ou seja, quando há uma atualização (Preço = p, Quantidade = 0).

Isso pode ser evidenciado de 3 maneiras:

  1. Uma pequena modificação do exemplo original do livro de pedidos poloniex: https://github.com/maayank/ccxt_polo_bug/blob/master/websocket-poloniex-orderbook.py
    Em essência, ele se inscreve no BTC/USDT com um limite de 100 e sai com uma mensagem se um dos 10 principais preços de compra/venda for excluído (em vez de ter seu valor definido).
    Ele nunca para (por exemplo, eu testei por ~ 3 horas)
  2. Colocar uma mensagem de impressão na ramificação de execução que exclui a linha na estrutura de dados do livro de pedidos interno e grepping por ela (ou similarmente, colocar um ponto de interrupção) mostra que o código dessa ramificação nunca é chamado. Veja esta cópia de async_support/base/exchange.py em https://github.com/maayank/ccxt_polo_bug/blob/fe43543f88cd4079d167700119f910ddfb359d6d/exchange.py#L344
  3. Até onde eu sei, o problema é que:
    uma. _websocket_handle_ob chama (não assíncrona)exchange.parse_order_book
    b. Que chama self.parse_bids_asks que filtra itens com valor == 0
    c. Mais tarde, na classe poloniex _websocket_handle_ob_delta_cache chama (async-)exchange.mergeOrderBookDelta que chama updateBidAsk, que por sua vez espera que quantidade==0 itens existam para sinalizar a exclusão
    d. git culpando as classes de troca não assíncronas 'js' e 'python' mostra o primeiro se tornando um mapa simples (sem o efeito colateral de filtragem) em março de 2018.

Não tenho certeza de como corrigi-lo sozinho, pois é potencialmente fundamental.
FYI, deixe-me saber se eu puder ajudar mais.

Oi @furryboffin confira isso: https://github.com/lfern/ccxt/tree/feature/websockets-multiple

Exemplos etc. leia aqui: https://github.com/lfern/ccxt/blob/feature/websockets-multiple/WEBSOCKETS.md

Leia "Antes de testar em python ou PHP" (você precisa transpilar para gerar os arquivos python).

Para sua conveniência, criei um repositório git contendo (já transpilado) o código mais recente do branch do lfern: https://github.com/firepol/ccxt-websockets

Aproveitar

OBRIGADO!

Olá @kroitor ,
Seguindo o comentário de @maayank , parece que os pedidos de valor zero não estão atualizando o livro de pedidos em cache e, portanto, os preços relacionados não são removidos do livro de pedidos.

Possivelmente, a origem python disso foi introduzida na seguinte condição adicionada:
https://github.com/ccxt/ccxt/blob/45febed9b792ab33c9454626e468e8e9672dad37/python/ccxt/base/exchange.py#L1233 ...onde a intenção estava filtrando os valores 'none'?

Nesse caso, para evitar filtrar entradas válidas de 'amount==0', considere usar:

if bidask[price_key] is not None and bidask[amount_key] is not None:
...
if (price_key in bidask) and (amount_key in bidask) and (bidask[price_key] is not None and bidask[amount_key] is not None):

De onde vem o carimbo de data/hora no feed do livro de pedidos gdax/coinbase pro? Eu pergunto porque estou recebendo atualizações com timestamps muito antigos (mais de 10 segundos) de tempos em tempos.

como posso usar websocket em huobipro e zb para 'ob' e comércio?
u pode tomar uma etapa detalhada?
THX

como posso usar websocket em huobipro e zb para 'ob' e comércio?
u pode tomar uma etapa detalhada?
THX

Oi @317459062 , como respondi no outro problema que você abriu no repositório errado (que é apenas o branch do lfern, transpilado em python por conveniência), aqui um link para o meu pequeno projeto, onde tentei criar um exemplo prático de como use o trabalho de lfern para salvar os livros de pedidos mais recentes em um banco de dados: https://github.com/firepol/ccxt-websockets-db-updater

Você pode vê-lo facilmente em ação. Siga as instruções no leia-me para começar e execute este comando:

python ob_tester.py -e huobipro -s BTC/USDT --debug --verbose

Acabei de testar e o testador funciona. Para salvar os dados em um banco de dados, consulte o uso ob_updater.py . O tratamento de erros está ausente, então ainda está em andamento, mas espero que possa ajudá-lo a começar. Saúde.

Oi @lfern , parece haver um bug no código python _transpiled_ do Kraken: as atualizações de 'lances' do Orderbook nem sempre são tratadas.

De tempos em tempos, a Kraken enviará uma atualização da carteira de pedidos que contém 'asks' e 'bids', em uma única mensagem, por exemplo:

[0,{"a":[["5035.90000","7.19104284","1554559551.265576"]]},{"b":[["5029.00000","0.00000000","1554559551.278368"],["3601.00000","0.03400000","1554235030.583914"]]}]

O código _transpiled_ relevante em ccxt\async_support\kraken.py parece manipular dados apenas do primeiro item de msg :

    def _websocket_on_message(self, contextId, data):
        msg = json.loads(data)
        event = self.safe_string(msg, 'event')
        status = self.safe_string(msg, 'status')
        if event is None:
            # channel data
            chanId = msg[0]
            data = msg[1]       ### <-- need to take into account a possible msg[2] as well

Por favor, deixe-me saber se eu devo fornecer mais informações sobre isso. Obrigado

Edit: A questão principal é que 'a' e 'b' podem chegar como dois dicionários separados , dentro de uma única lista. Como se opõe a 'as' e 'bs' que chegam como duas chaves de um único dicionário. Visto nas cargas úteis de exemplo do Kraken . Este código python de exemplo irá corrigi-lo:

if len(msg) is 3:
    data.update(msg[2])

(Provavelmente deve ser colocado sob a linha if event == 'ob': )

Olá @lfern , gostaria de informar que adicionei alguns eventos à troca Coinbase/GDAX (ticker, trades e heartbeat). Disposto a fazer um PR assim que o limpar. Porém, estou com um pequeno problema e não consigo descobrir o wait4readyEvent .

Para wait4ready :

(node:1558) UnhandledPromiseRejectionWarning: Error: WebSocket is not open: readyState 0 (CONNECTING)
    at WebSocket.send (.../node_modules/ws/lib/websocket.js:314:19)
    at WebsocketConnection.send (.../node_modules/ccxt/js/base/websocket/websocket_connection.js:81:28)
    at WebsocketConnection.sendJson (.../node_modules/ccxt/js/base/websocket/websocket_base_connection.js:37:14)
    at coinbasepro.websocketSendJson (.../node_modules/ccxt/js/base/Exchange.js:2106:35)
    at coinbasepro._websocketSubscribe (.../node_modules/ccxt/js/gdax.js:1032:16)
    at Promise (.../node_modules/ccxt/js/base/Exchange.js:2323:26)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)

Embora a troca pareça funcionar bem de outra forma, gostaria muito de resolver o enigma da conexão.

@lfern pelo que entendi dos comentários aqui, a API do websocket é bastante estável.

Existem planos para mesclar isso com a versão principal do ccxt em breve?

@lfern pelo que entendi dos comentários aqui, a API do websocket é bastante estável.

Existem planos para mesclar isso com a versão principal do ccxt em breve?

Não sei se é estável o suficiente, veja ccxt/ccxt#4335

Oi @bugs181 , Alguém relatou alguns problemas em conexões lentas, e acho que há um bug que lança essa exceção quando você tenta fazer uma segunda chamada ao método de assinatura antes que uma primeira chamada tenha retornado. Se você tiver um branch de teste público para esse recurso, eu poderia dar uma olhada.

Olá @lfern , gostaria de informar que adicionei alguns eventos à troca Coinbase/GDAX (ticker, trades e heartbeat). Disposto a fazer um PR assim que o limpar. Porém, estou com um pequeno problema e não consigo descobrir o wait4readyEvent .

Para wait4ready :

(node:1558) UnhandledPromiseRejectionWarning: Error: WebSocket is not open: readyState 0 (CONNECTING)
    at WebSocket.send (.../node_modules/ws/lib/websocket.js:314:19)
    at WebsocketConnection.send (.../node_modules/ccxt/js/base/websocket/websocket_connection.js:81:28)
    at WebsocketConnection.sendJson (.../node_modules/ccxt/js/base/websocket/websocket_base_connection.js:37:14)
    at coinbasepro.websocketSendJson (.../node_modules/ccxt/js/base/Exchange.js:2106:35)
    at coinbasepro._websocketSubscribe (.../node_modules/ccxt/js/gdax.js:1032:16)
    at Promise (.../node_modules/ccxt/js/base/Exchange.js:2323:26)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)

Embora a troca pareça funcionar bem de outra forma, gostaria muito de resolver o enigma da conexão.

Tentei usar o branch websocket, mas não consegui entender a documentação e por algum motivo o código não é autoexplicativo para mim. Alguém se importaria de me cutucar na direção certa, mostrando um exemplo de como eu poderia obter, por exemplo, o ticker ws para BitMEX funcionando em PHP? O código Pusesdo provavelmente funcionaria, desde que usasse os métodos corretos. Espero que alguém possa me empurrar na direção certa. Obrigado!

@btc-zz , apenas um empurrãozinho (especialmente quando eu nunca usei o código php), mas uma vez que você git clone o branch websockets, você precisa transpilar (ou seja, compilar) o código js para php usando npm. Assim:

git clone https://github.com/lfern/ccxt.git
cd ccxt
git checkout remotes/origin/feature/websockets-multiple
npm install opencollective
npm install ws
npm run postinstall
npm run export-exchanges
npm run transpile

Ele pode solicitar módulos node.js adicionais - YMMV.

@lfern

Eu acho que há um bug que lança essa exceção quando você tenta fazer uma segunda chamada para o método de assinatura antes que uma primeira chamada tenha retornado.

Isso soa como o que estou fazendo. Eu notei que await exchange.websocketSubscribe apenas trava no entanto. A promessa nunca vai resolver. Eu tinha assumido que a implementação ws enfileiraria as assinaturas. Na maioria das vezes, após o erro de conexão, ele tentará novamente a assinatura e funcionará bem. Houve algumas vezes em que a assinatura do canal de pulsação falhou e o nó foi fechado após algum tempo.

@bugs181 Se o websocketSubscribe travar para sempre, há algo errado na implementação do js, ​​você deve receber uma exceção de tempo limite. Talvez você tenha uma conexão lenta ou tenha que esperar alguma mensagem enviada pelo servidor antes de enviar qualquer assinatura ao servidor. Talvez o servidor websocket gdax altere o protocolo. Eu tentaria fazer alguns testes, você está usando a versão js?

@ bugs181 Acabei de testar a versão atual do gdax js e parece que está se conectando corretamente. Talvez possamos nos comprometer com o branch websocket e fazer alguns testes.

@lfern Acabei de testar o código que eu tinha e está funcionando bem hoje. Estranho mesmo. É possível que tenha sido de uma conexão lenta (tivemos tempestades por cerca de 2 semanas seguidas aqui).

Editar:
Existe um conjunto de regras de linting que você gostaria que eu seguisse para relações públicas? Percebi algumas coisas sobre seu estilo de codificação e quero garantir que possamos concordar.

@ bugs181 Não realmente, siga as regras gerais do ccxt e tome cuidado para que o código js transpile diretamente para python e PHP.

Editar:
Existe um conjunto de regras de linting que você gostaria que eu seguisse para relações públicas? Percebi algumas coisas sobre seu estilo de codificação e quero garantir que possamos concordar.

@lfern Parece que o cobinhood mudou sua API WS ou algo assim. Dá tempo esgotado metade do tempo

feature/websocket-multiple mesclado com a versão ccxt/master atual.

@xCuri0 quanto tempo para obter o erro de tempo limite? Testando o evento ob sem erro por 1 hora.

@lfern cerca de 75% das vezes não consegue se inscrever com erro de tempo limite. Não acontece quando eu uso manualmente wscat para conectar

como usar a API do websocket agora? e há alguns documentos?

@guotie WEBSOCKET.md no ramo feature/websocket-multiple . Além disso, você pode olhar para os exemplos. Afaik reconectando em um erro de rede no WS não funciona, exceto para desconectar após algumas horas, a menos que você tenha uma internet perfeita

Não sei por que, mas se eu simular um erro de rede desligando o WiFi por um tempo, ele poderá se reconectar. Um erro de rede real dá AttributeError: 'NoneType' object has no attribute 'close' ao tentar reconectar

@kroitor quais são os requisitos para que o branch websocket seja mesclado no master?

Não encontrei a filial feature/websocket-multiple . @xCuri0

@guotie no CCXT de lfern existe

Ok, obrigado

Parece que o único problema com a ramificação ws é a compilação do php agora. Espero que seja corrigido para que possa ser mesclado no mestre

Alguma atualização disso ?

@kroitor O que falta para poder integrar? Muitas pessoas ansiosas pelos websockets

@kroitor Você poderia dizer quando os websockets estarão disponíveis no ccxt?

@qwasko1212 Vou postar uma atualização aqui dentro de uma semana ou mais. Por favor, espere. Thx por sua paciência!

Olá a todos, e um grande obrigado a todos os usuários e contribuidores do CCXT! Agradecemos muito o seu envolvimento!

Em primeiro lugar, queremos agradecer à comunidade por nos permitir chegar até aqui. Todos vocês são pessoas incríveis, e sem vocês este projeto não estaria na posição que está hoje. Mesmo que o CCXT tenha se concentrado em APIs RESTful, sempre apreciamos e entendemos seu entusiasmo pelos WebSockets. O fluxo constante de comentários expressando interesse no status do WebSockets não passou despercebido, apesar do fato de termos permanecido em silêncio sobre o assunto.

É claro que o CCXT não pode mais permanecer apenas REST. A comunidade esperou por muito tempo e nosso silêncio gerou frustração e até dúvidas de que estávamos trabalhando para adicionar esse recurso. Peço desculpas por não responder a todos, mas queria fornecer uma resposta significativa e não apenas uma promessa vazia. Estamos muito focados no trabalho real de manter e melhorar o CCXT, por isso esperamos sua compreensão.

O suporte a streaming no CCXT está em desenvolvimento há algum tempo e estamos muito perto de ter uma arquitetura que satisfaça nossos critérios de facilidade de uso, troca a quente, unificação e portabilidade. Tudo foi codificado internamente do zero com os mesmos altos padrões que o CCXT é conhecido por ter, sendo a extensibilidade um objetivo adicional.

Nos últimos dois anos, o CCXT cresceu exponencialmente, e a quantidade de trabalho de manutenção e suporte necessários cresceu proporcionalmente. Como um projeto de código aberto licenciado pelo MIT, nós autofinanciamos tudo, mas nessa escala não podemos continuar fazendo isso. Sem os recursos necessários para manter a biblioteca diante de um universo criptográfico em rápida mudança, ela logo perderia funcionalidade e diminuiria em utilidade. Sem desenvolvimento contínuo, novas integrações ficariam estagnadas. Nada disso é bom para a biblioteca, a comunidade ou o desenvolvimento da infraestrutura de criptomoedas para competir com as finanças tradicionais.

O que nos leva ao CCXT Pro. CCXT Pro é um complemento profissional para CCXT que suporta WebSockets e muito, muito mais. O CCXT continuará como um projeto de código aberto sob a licença do MIT e será apoiado por você, a comunidade, em conjunto com uma equipe de desenvolvimento do CCXT mais bem financiada. O CCXT Pro será hospedado em um repositório privado de forma paga, mas com a oportunidade de os principais contribuidores do CCXT obterem acesso gratuito.

Isso equilibra nossa forte crença no valor e no poder de projetos de código aberto orientados para a comunidade, ao mesmo tempo em que aborda a realidade de recursos limitados e uma demanda crescente por um nível mais alto de serviço e capacidade de resposta de traders profissionais, empresas maiores e instituições financeiras que use CCXT para trabalho de missão crítica. Esses usuários comerciais desejam acesso instantâneo ao suporte, linguagens compiladas, baixas latências, protocolos de negociação adicionais e, é claro, capacidade WebSocket.

Criar uma licença comercial e cobrar desses usuários do CCXT Pro nos permite continuar o importante trabalho no CCXT e, acreditamos, é uma forma ética de apoiar a comunidade e seus colaboradores. Esperamos que algumas pessoas se oponham a fazer do CCXT Pro um projeto comercial, e estamos interessados ​​em suas opiniões, principalmente se você for um colaborador ativo. Queremos recompensar nossos colaboradores com licenças CCXT Pro e, em breve, abriremos um canal onde poderão ser feitas consultas para fazer isso.

O lançamento do CCXT Pro está planejado para o terceiro trimestre deste ano. Publicaremos mais detalhes sobre o roteiro para o CCXT Pro em breve.

Com sinceros agradecimentos e reconhecimento!

Bom ouvir @kroitor ! Esta é a decisão certa. Certifique-se de que aqueles com licença profissional ainda possam construir a partir de fontes. Pessoalmente, não estou preocupado em pagar por software, mas não posso arcar com os riscos de segurança de negociar com software proprietário.

Certifique-se de que aqueles com licença profissional ainda possam construir a partir de fontes.

Os licenciados terão acesso ao repositório de código-fonte do CCXT Pro no GitHub e poderão construir a partir de fontes. Os contribuidores terão a chance de obter uma licença gratuita.

Obrigado @kroitor. Alguma ideia de quanto custará o CCXT Pro?

@zanoo ofereceremos uma grade simples de preços para diferentes tipos ou níveis de clientes. Considerando o propósito da lib que é ganhar dinheiro, o plano inicial para desenvolvedores individuais será acessível – comparável à sua assinatura mensal de TV a cabo/satélite.

Com o CCXT Pro o usuário se comunicará diretamente com as exchanges sem intermediários. Mesmo que sua licença expire, o CCXT Pro continuará funcionando. No entanto, é do seu interesse ter uma licença que lhe dê acesso ao repositório protegido – incluindo as atualizações mais recentes, correções de bugs, suporte dedicado, novas trocas, métodos e aprimoramentos.

@kroitor do CCXT Pro, certamente as empresas que precisam de recursos e ajustes rápidos na biblioteca serão beneficiadas, então acho que você deve cobrá-los adequadamente. Empresas de médio porte que quase nunca vão incomodar/pedir algo, mas ganham dinheiro graças ao CCXT devem pagar, mas muito menos.

Se você quiser fazer com que peixes pequenos (pessoas privadas) paguem, acho que seria injusto (as pessoas podem potencialmente usar o CCXT para negociar, então sim "para ganhar dinheiro", mas no final das contas eles investem seus fundos e é com o risco deles que eles ganham dinheiro, não diretamente com CCXT). Considerar que existem bots como 3commas, cryptohopper, gekko, gunbot etc. que custam muito barato e na verdade possuem alguma IA/algo que faz as pessoas ganharem dinheiro.

Além disso, se você quiser deixar isso de graça apenas para os "principais contribuidores do CCXT", surgirá a pergunta: quem são os principais contribuidores do ccxt, com certeza os que fazem o trabalho sujo. E as pessoas testando isso e enviando muitos relatórios de bugs (como eu) e ideias úteis?

Na verdade, os principais contribuidores (por exemplo, como lfern) não apenas devem obter uma licença gratuita, mas também merecem ser pagos. Quero dizer, senão como você planeja incentivar as contribuições ativas? Se você não me pagar um centavo, eu mantenho meu código para mim, por que liberar de graça e você ganha dinheiro com isso e talvez até me peça para pagar uma licença por isso, porque eu não seria um "top" colaborador, mas apenas um colaborador "ocasional"?

Eu acho que seria justo manter um nível pessoal para pessoas que não têm um negócio e usam isso como "hobby" abaixo de 10 USD/mês. Ou melhor, de graça. Quero dizer: para países ocidentais 10 USD ainda está ok, mas posso imaginar que alguns desenvolvedores em países em desenvolvimento gostariam de economizar 10 USD/mês...

...em última análise, acho que você deveria permitir uma licença gratuita para pessoas que não a usam comercialmente. Por exemplo, se um desenvolvedor codifica seu próprio bot com base no CCXT, isso não é comercial. Deve ser uma licença "não comercial" gratuita.

Eu codifiquei algumas coisas com base no CCXT e é de código aberto, você gostaria de fazer pessoas como eu pagar por isso? Sério, isso me lembraria que a Apple exige que os desenvolvedores paguem 99 USD/ano, mesmo que planejem publicar aplicativos gratuitos. Ridículo!

Se um desenvolvedor criou um bot ou um software baseado em CCXT e quer vender seu software, então concordo que ele precisa pagar uma licença comercial. Felizmente, deve haver um nível para isso também. Imagine novamente um pequeno desenvolvedor, tentando codificar uma ferramenta baseada em CCXT e tentando vendê-la, mas ninguém vai comprar no começo, talvez algumas cópias por ano. Existem muitos desenvolvedores que tentam ganhar algum dinheiro depois de investir muitas horas em algo e não investir muito em marketing para torná-lo um produto super comercial... licença comercial" (por exemplo, coinmarketcap cobra 70 dólares/mês, preço ridiculamente alto para um pequeno desenvolvedor capaz de vender talvez 2-3 cópias de um aplicativo a 3 dólares cada) e, em vez disso, remova a dependência CCXT e use APIs nativas. Seria um passo para trás e muito decepcionante.

Espero que você considere tais aspectos e faça licenças gratuitas para pessoas não comerciais ou pessoas tentando usá-lo comercialmente, mas também não obtendo grandes ganhos com isso... e confiando na honestidade das pessoas para isso. Por exemplo, olhe para jetbrains, syntevo. Até que você não tenha fins lucrativos usando suas ferramentas, você não paga nada, no dia em que começar a ganhar dinheiro, você paga as licenças. É bastante justo.

Eu realmente espero que o CCXT permaneça gratuito para usuários ocasionais. Deixe as empresas e usuários comerciais pagarem! THX

@kroitor do CCXT Pro, certamente as empresas que precisam de recursos e ajustes rápidos na biblioteca serão beneficiadas, então acho que você deve cobrá-los adequadamente. Empresas de médio porte que quase nunca vão incomodar/pedir algo, mas ganham dinheiro graças ao CCXT devem pagar, mas muito menos.

Sim!

Se você quiser fazer com que peixes pequenos (pessoas privadas) paguem, acho que seria injusto (as pessoas podem potencialmente usar o CCXT para negociar, então sim "para ganhar dinheiro", mas no final das contas eles investem seus fundos e é com o risco deles que eles ganham dinheiro, não diretamente com CCXT). Considerar que existem bots como 3commas, cryptohopper, gekko, gunbot etc. que custam muito barato e na verdade possuem alguma IA/algo que faz as pessoas ganharem dinheiro.

Não se esqueça que o CCXT original com todas as suas funcionalidades permanecerá sob MIT e ainda permanecerá gratuito, portanto, as pessoas que o usarem não serão afetadas.

A parte paga do CCXT Pro será a parte profissional, que inclui streaming, o que significa velocidades mais altas para ser mais competitivo. Essa parte (que ainda não foi lançada) será paga e será um add-on opcional. Você poderá desenvolver o CCXT gratuito ou alternar facilmente para a versão comercial e usar o CCXT Pro para ser um pouco mais rápido e competitivo.

Essa parte paga não é baseada no trabalho feito por @lfern , mas é codificada internamente pelo CCXT Dev Team do zero. Mas @lfern, sem dúvida, merece uma licença gratuita. E os licenciados terão acesso ao código-fonte.

Além disso, se você quiser deixar isso de graça apenas para os "principais contribuidores do CCXT", surgirá a pergunta: quem são os principais contribuidores do ccxt, com certeza os que fazem o trabalho sujo. E as pessoas testando isso e enviando muitos relatórios de bugs (como eu) e ideias úteis?

Os principais contribuidores são pessoas que contribuíram significativamente para o projeto desta ou daquela forma. Seja com código, seja com testes e relatórios (nós adoraríamos incentivar os testadores também, a propósito ;)), ou por outros meios. Plz, não se preocupe, não vamos perder acidentalmente as pessoas que se esforçaram neste projeto. Sabendo que você realmente ajudou muito com isso ao longo do ano, é claro que prestaremos contas disso.

Na verdade, os principais contribuidores (por exemplo, como lfern) não apenas devem obter uma licença gratuita, mas também merecem ser pagos. Quero dizer, senão como você planeja incentivar as contribuições ativas?

Na verdade, é exatamente isso que gostaríamos de fazer junto com as outras coisas – vamos recompensar os contribuidores e talvez até convidar os contribuidores para participar do projeto. Em outras palavras, todo o propósito de fazer do CCXT Pro um projeto comercial é sustentar a vida do CCXT e do CCXT Pro. Porque... veja a resposta para a próxima pergunta...

Se você não me pagar um centavo, eu guardo meu código para mim, por que liberar de graça e você ganhar dinheiro com isso e talvez até me pedir para pagar uma licença por isso,

... por que eu continuaria mantendo o CCXT? Por que o CCXT Dev Team se esforçaria para liberar e manter o código? ) Por que ajudaríamos outras pessoas a construir seus projetos? Eu liberei um monte de código feito por mim para que você pudesse usá-lo gratuitamente e eu não exigi um pagamento de você) Por que eu faria isso você acha? ))

Para mim, uma atitude melhor é o contrário – torná-lo comercial nos ajudará a incentivar adequadamente os contribuidores. E, novamente, o CCXT original permanecerá gratuito. O CCXT Pro será pago. E, idealmente, eles serão interoperáveis, o que significa que você pode alternar sem alterar seu código de usuário existente.

Eu acho que seria justo manter um nível pessoal para pessoas que não têm um negócio e usam isso como "hobby" abaixo de 10 USD/mês. Ou melhor, de graça. Quero dizer: para países ocidentais 10 USD ainda está ok, mas posso imaginar que alguns desenvolvedores em países em desenvolvimento gostariam de economizar 10 USD/mês...

Faremos o nosso melhor para torná-lo acessível para os indivíduos. Nosso nível inicial será próximo à sua estimativa. No entanto, observe que, para fornecer acesso às fontes e permanecer acessível aos usuários do GitHub (para ser fácil de usar com a infraestrutura existente), talvez precisemos gastar US $ 9 por estação por mês (https:// github.com/pricing), sem incluir outros custos e sem incluir o esforço dos desenvolvedores.

...em última análise, acho que você deveria permitir uma licença gratuita para pessoas que não a usam comercialmente. Por exemplo, se um desenvolvedor codifica seu próprio bot com base no CCXT, isso não é comercial. Deve ser uma licença "não comercial" gratuita.

Se for um uso não comercial, então (se você pensar nisso, logicamente) ele deve se encaixar perfeitamente na categoria de propósitos do CCXT que permanece livre e será desenvolvido sob a licença do MIT. Assim, aqueles que constroem software não comercial e ferramentas gratuitas, e até bots comerciais baseados em CCXT – esses ainda podem aproveitar tudo de graça e não são afetados. Mas também há usuários que querem aproveitar um pouco mais do que outros – é ético cobrar deles por velocidade extra.

Se você pensar em algum propósito de streaming – isso é puramente comercial. Você pode citar pelo menos um propósito não comercial de usar uma ferramenta um pouco mais rápida quando uma versão gratuita da mesma ferramenta sai, todo o resto sendo igual? Levando isso adiante, se for um bot, esse é um uso comercial com certeza, em todos os sentidos. Porque o propósito puro de um bot é ser comercial, "ganhar dinheiro", obviamente. Por que você precisaria de velocidades mais rápidas além de construir um bot mais rápido? Todos os outros propósitos, incluindo rastreamento histórico - não precisam ser instantâneos, em outras palavras, você só precisa do CCXT Pro se quiser "ganhar um pouco mais de dinheiro do que a média". Se você não precisa de um bot mais rápido, pode continuar usando o CCXT no MIT. Absolutamente de graça) E isso é honesto, aberto e justo.

Eu codifiquei algumas coisas com base no CCXT e é de código aberto, você gostaria de fazer pessoas como eu pagar por isso?

Claro que não. Porque CCXT permanece gratuito.

Sério, isso me lembraria que a Apple exige que os desenvolvedores paguem 99 USD/ano, mesmo que planejem publicar aplicativos gratuitos. Ridículo!

Totalmente de acordo com você neste exemplo. Por isso:

  • Teremos uma licença "CCXT bRO" que será gratuita para uso não comercial e uso acadêmico, e será gratuita para nossos colaboradores, que poderão obter uma licença gratuita contribuindo com código para o repositório CCXT Pro.
  • Os principais contribuidores do repositório CCXT também receberão suas licenças bRO gratuitas para o CCXT Pro. Forneceremos mais detalhes sobre isso.
  • O CCXT permanecerá totalmente gratuito no MIT e será mantido ainda melhor se os contribuidores forem mais incentivados.
  • O CCXT será subsidiado pelo CCXT Pro (caso contrário, não é sustentável).
  • O CCXT Pro cobrará apenas pela vantagem, basicamente, que inclui a manutenção, a adição rápida de novas integrações, o desenvolvimento, o suporte e os custos subjacentes.

Se um desenvolvedor criou um bot ou um software baseado em CCXT e quer vender seu software, então concordo que ele precisa pagar uma licença comercial. Felizmente, deve haver um nível para isso também. Imagine novamente um pequeno desenvolvedor, tentando codificar uma ferramenta baseada em CCXT e tentando vendê-la, mas ninguém vai comprar no começo, talvez algumas cópias por ano. Existem muitos desenvolvedores que tentam ganhar algum dinheiro depois de investir muitas horas em algo e não investir muito em marketing para torná-lo um produto super comercial ...

A licença abordará principalmente peixes maiores. Assim, um desenvolvedor ruim terá a oportunidade de lutar o quanto quiser e nosso plano para iniciantes será acessível. A licença CCXT Pro terá como alvo as empresas em desenvolvimento que não lutam com marketing e que usarão o CCXT Pro para criar produtos e serviços de sucesso. O que é justo, novamente.

Eu com certeza não quero gastar 50-70 usd/mês para uma "licença comercial" (por exemplo, coinmarketcap cobra 70 usd/mês,

Nosso plano para iniciantes está longe disso. Sem problemas.

preço ridiculamente alto para um pequeno desenvolvedor capaz de vender talvez 2-3 cópias de um aplicativo a 3 dólares cada) e, em vez disso, remover a dependência CCXT e usar APIs nativas. Seria um passo para trás e muito decepcionante.

Entendemos isso, portanto, não temos a intenção de dar um tiro no projeto aumentando o limite de entrada muito alto.

Espero que você considere tais aspectos e faça licenças gratuitas para pessoas não comerciais ou pessoas tentando usá-lo comercialmente, mas também não obtendo grandes ganhos com isso... e confiando na honestidade das pessoas para isso.

Nós pensamos o mesmo.

Por exemplo, olhe para jetbrains, syntevo. Até que você não tenha fins lucrativos usando suas ferramentas, você não paga nada, no dia em que começar a ganhar dinheiro, você paga as licenças. É bastante justo.

Totalmente com você sobre isso.

Eu realmente espero que o CCXT permaneça gratuito para usuários ocasionais. Deixe as empresas e usuários comerciais pagarem! THX

CCXT permanecerá gratuito para usuários ocasionais, além disso, permanecerá gratuito mesmo para usuários comerciais e para empresas.

O CCXT Pro terá uma licença comercial, mas será acessível para iniciantes, comerciantes profissionais, empresas e baleias.

Postaremos mais detalhes em uma ou duas semanas. Fique ligado!

Uau, isso é uma grande notícia, eu não continuei no meu projeto nos últimos meses, então eu realmente não participei de discussões ou desenvolvimento de ccxt... ainda não tenho certeza se eu gosto dessas mudanças ou não ;-) Deve haver um preço inicial para pequenos negócios em crescimento (sem se tornar um grande bloco de custos um dia), caso contrário eu pensaria duas vezes usando CCXT. Pelo menos para a versão gratuita eu precisava escrever testes (usando uma conta de troca ativa e quantidades muito pequenas de fiat para testar todos os objetos e respostas), melhorias etc. por mim mesmo, pois estava longe de objetos estáveis ​​e unificados. Espero que você tenha usado o TypeScript para reescrever ;-) E assim que o dinheiro estiver envolvido, um bom QM é muito importante. Melhores trocas menos suportadas, mas API lib mais estável. Não há nada pior do que perder grandes quantias de dinheiro por causa de uma biblioteca cheia de bugs.

@kroitor muito obrigado pela resposta. Na verdade eu acho que você deveria colocar todos esses pontos em um FAQ e publicá-los no site/blog/twitter da ccxt o mais rápido possível, e atualizá-los ao longo do tempo, para ter um lugar central e não um tópico como este para rolar para encontrar informações espalhadas aqui e ali.

Este tópico sim é sobre streaming e agora eu entendo que haverá 2 versões diferentes do projeto, API de descanso normal e Pro = versão websocket/streaming... entendi agora.

Para mim, cobrar mais de 9 USD/mês para usuários ocasionais é uma impossibilidade. Especialmente se você acha que precisa gastar 9 USD/mês por sit, para pagar a licença do github. Quero dizer, vamos lá (esta licença da equipe do github é mais cara do que a licença "malvada" do desenvolvedor da Apple!). Eu entendo que é mais conveniente ficar no github, mas como mencionado (e você pareceu concordar com isso), se você confiar na honestidade das pessoas, você pode simplesmente criar um novo repositório, deixar o código-fonte publicamente acessível (apenas a licença tem que seja claro), não há necessidade de pagar 9 USD por nenhum membro e permitir que todos baixem. Então você ainda fica no github, mas não precisa pagar 9 USD/mês para pessoas que usarão isso ocasionalmente.

Se você tem medo de que as pessoas, assim, baixem a fonte e a usem sem pagar pela licença, então significa que você não confia no público pagante... (a premissa era que você confia na honestidade das pessoas).

Você pode criar/usar um sistema separado para as licenças. Tenho certeza de que há muitas maneiras de conseguir isso. Provavelmente até aceita criptomoedas como pagamento, já que este é um projeto de criptomoedas, por que não?

Eventualmente, você pode criar outro repositório, ccxt-enterprise, onde as pessoas VIP (empresas) pagarão o cheque grande e obterão sua conta especial no github para relatar bugs/problemas onde você dará maior prioridade (se precisar). Poderia ser uma solução, não? Assim, todos os peixes pequenos não precisarão ser levados em consideração e você pode pular esses 9 USD / mês para eles ... na verdade, esse recurso "Equipe" do github não parece realmente necessário para mim, e só aumenta os custos para um projeto que deve ficar o mais barato possível para usuários ocasionais/não comerciais.

Para citar um único caso em que os websockets são necessários para fins não comerciais: notificações.
Como trader, gosto de monitorar os preços usando meu próprio bot e quero ser notificado quando um determinado preço for atingido. Sim, em última análise, eu gostaria de automatizar algo quando um preço é acionado ;) É "comercial"... e basicamente tem 0 ganhos para eu cobrir os custos de eletricidade usados ​​pelo meu pequeno bot de teste? Acho que até uma pequena quantidade de ganhos, podemos considerar o uso ainda "não comercial". Até 100 USD/mês de ganhos líquidos (após taxas, impostos...) Eu diria que ainda não é comercial, é apenas dinheiro de bolso... depois de 100 USD/mês comercial. Justo?

Além disso, outro uso não comercial seria criar um bot para fins educacionais, de código aberto, para mostrar minhas habilidades de codificação. Na verdade, eu gostaria de encontrar um emprego em python, estou cansado de receber ofertas de trabalho em C#, então quero mostrar que sou ativo no desenvolvimento de python ;) Acho que muitos alunos podem se relacionar com isso (eles podem criar projetos baseados nisso e colocá-los em seu currículo ou usá-los em sua tese de bacharelado/mestrado etc.), eles podem criar um projeto baseado no CCXT pro, mas devem ser cobrados 0 por isso (eu insisto nisso, 0, não mesmo os 9 USD para pagar o github - não precisamos disso), a única condição seria abrir o código do projeto. Pense nisso: todo projeto de código aberto baseado em CCXT é publicidade para CCXT. O mesmo para CCXT Pro. Você pode fazer uma lista de projetos notáveis ​​usando CCXT e CCX Pro, novos codificadores ou empresas podem dar uma olhada nesses projetos e até usar esse código para suas próprias implementações.

Estes meus 2 centavos de preocupações e idéias. Senão... Estou muito animado com isso. Vou tentar ressuscitar meu(s) pequeno(s) projeto(s) baseado(s) no CCXT e abrir o código deles algum dia no futuro ;)

Algum cronograma para quando o CCXT Pro estará disponível para uso/download?

Para mim, cobrar mais de 9 USD/mês para usuários ocasionais é uma impossibilidade. Especialmente se você acha que precisa gastar 9 USD/mês por sit, para pagar a licença do github. Quero dizer, vamos lá (esta licença da equipe do github é mais cara do que a licença "malvada" do desenvolvedor da Apple!). Eu entendo que é mais conveniente ficar no github, mas como mencionado (e você pareceu concordar com isso), se você confiar na honestidade das pessoas, você pode simplesmente criar um novo repositório, deixar o código-fonte publicamente acessível (apenas a licença tem que seja claro), não há necessidade de pagar 9 USD por nenhum membro e permitir que todos baixem. Então você ainda fica no github, mas não precisa pagar 9 USD/mês para pessoas que usarão isso ocasionalmente

Apostar o sustento dos desenvolvedores do ccxt na honestidade das pessoas não é algo que estamos dispostos a fazer. Seu argumento de que algumas pessoas deveriam ser isentas de pagar porque usam nosso código apenas ocasionalmente não faz sentido. Digamos que eu queira pegar o trem, mas só pego o trem uma vez por mês, isso significa que não devo pagar a passagem? Como o @kroitor disse, o nível inicial será muito acessível (provavelmente mais de US $ 9 por mês), no entanto, qualquer pessoa que tenha escrito um bot antes sabe que negociar até a menor quantidade de criptografia nesses mercados voláteis e você perderá / ganhará 10x isso quantidade em questão de dias.

Se você tem medo de que as pessoas, assim, baixem a fonte e a usem sem pagar pela licença, então significa que você não confia no público pagante... (a premissa era que você confia na honestidade das pessoas).

Não é que não confiemos nas pessoas, confiamos muito que a maioria das pessoas será desonesta em uma configuração dessas (mesmo eu não pagaria tbh)

Para citar um único caso em que os websockets são necessários para fins não comerciais: notificações.
Como trader, gosto de monitorar os preços usando meu próprio bot e quero ser notificado quando um determinado preço for atingido.

Em seguida, use ccxt regular e pesquise o ticker. Não é difícil. E 100ms não importa para as notificações no seu telefone, porque levará 100x mais tempo para você negociar manualmente qualquer coisa.

É "comercial"... mas se eu apenas jogar com dinheiro de bolso e ganhar 20 USD de ganhos por mês, devo pagar uma licença de 10-20 USD e basicamente ter 0 ganhos para cobrir os custos de eletricidade usados ​​pelo meu pequeno teste robô?

Realisticamente esta é a escolha do usuário, o fato de você ter obtido pequenos ganhos usando código ws extremamente rápido não é culpa nossa, apenas significa que você deveria ter projetado um bot melhor (sabemos que é difícil...)

bot para fins educacionais, de código aberto, para mostrar minhas habilidades de codificação. Na verdade, eu gostaria de encontrar um emprego em python, estou cansado de receber ofertas de trabalho em C#, então quero mostrar que sou ativo no desenvolvimento de python ;) Acho que muitos alunos podem se identificar com isso

Eu também sou um estudante, e definitivamente consideraremos dar licenças educacionais gratuitas para qualquer pessoa que possa provar que está na educação possuindo um endereço de e-mail educacional, no entanto, não queremos que esse sistema seja abusado (por exemplo, manter meu e-mail da universidade para sempre).

@frosty00 você ainda está desperdiçando 9 USD/mês por um github sit por pessoa. Você pode dar isso como desconto para seus usuários.

A passagem de trem na verdade é um bom exemplo: se eu usar o trem 3 vezes por mês acho justo comprar 3 passagens e não uma assinatura mensal ;) nota: em alguns países os idosos não pagam transporte público. Em algumas cidades, como Tallinn (Estônia), os transportes públicos são gratuitos. Então, sim, em um mundo ganancioso onde devemos pagar por tudo, ainda é possível oferecer coisas grátis se quisermos.

Para todos os seus outros pontos. Eu não discutiria sobre isso.

No final, talvez eu tenha sido um pouco dramático demais, mas se você puder entregar um bom produto como disse que faria, provavelmente pagar mais de 9 USD/mês seria bom para a maioria dos usuários.

Para os poucos que não ficarão felizes, acho que haverá alternativas gratuitas a serem usadas, como https://github.com/bitrich-info/xchange-stream ou o fork de código aberto de @lfern .

Ansioso para ver o CCXT Pro.

@firepol se o sistema puramente baseado em honestidade funcionasse, @kroitor e os desenvolvedores deveriam estar ganhando dinheiro suficiente para não ter que dar esse passo. A página de índice lista várias opções para patrocinar, mesmo pequenas quantias, então qualquer pessoa que ganhe algum dinheiro com CCXT provavelmente já deve estar doando. Eu entendo esse passo e acho justo e viável, como diz kroitor, com uma condição. Na minha opinião, isso só pode funcionar se o CCXT Pro permanecer estritamente um complemento do CCXT. Com isso quero dizer que, por exemplo, a implementação do websocket deve usar todas as mesmas classes de troca do CCXT "base", de modo que todas as atualizações e melhorias para o Pro serão necessariamente feitas também no CCXT. Assim que isso se tornar dois projetos separados, mal posso imaginar que funcione. Confio plenamente que a equipe de desenvolvimento tem todas as intenções de continuar apoiando o CCXT mesmo assim, afinal, por que eles deveriam apoiá-lo agora? No entanto, assim que você tiver clientes pagantes por um produto separado, obviamente todas as prioridades serão definidas com esse produto primeiro. Talvez o CCXT viva como um projeto comunitário, mas nem isso é certo. De qualquer forma, pelo que entendi, o recurso complementar é exatamente o plano, então acho que essa é uma boa decisão e só melhorará o CCXT como um todo.

O fato de o CCXT Pro poder interagir diretamente com as exchanges, sem intermediários, é tudo o que importa na minha opinião. acesso ao código-fonte me convenceu disso.

Eu gostaria que a equipe CCXT gerasse uma renda maior apenas com a biblioteca base CCXT, suspeito que o CCXT seja usado por mais e maiores usuários do que poderíamos imaginar, e só posso vê-lo crescendo ao longo dos anos com o mercado de criptomoedas.

Faz sentido para mim cobrar de acordo com as empresas comerciais que esperam algum nível de consistência, em oposição aos desenvolvedores individuais usando a ferramenta de forma mais modesta, assumindo o risco de encontrar bugs e provavelmente contribuindo, seja por meio de commits, sugestões ou relatórios de bugs.

O streaming pode justificar uma licença paga opcional; é difícil dizer quanta diferença isso faria para os pequenos investidores. Mas certamente foi um trabalho sério para a equipe, e todo trabalho merece algo em troca.

Tenho algumas perguntas.
Teremos acesso ao manual do CCXT Pro antes de adquirir o produto, para entender todas as sutilezas do CCXT Pro? ou talvez seja incluído no manual básico?

Além disso, qual tecnologia CCXT escolheu para a biblioteca de streaming php? há muitas soluções, reactphp, amphp, ratchet ... podemos ter algumas ideias sobre qual solução foi/é preferida para uso com fluxos CCXT? você conseguiu executar alguns benchmarks para determinar qual solução se encaixaria mais nesse tipo de ferramenta? e quanto ao lado do servidor, precisaríamos construir um processo/daemon específico em outra linguagem para lidar com o fluxo à medida que eles são enviados para o servidor WS?

@AadaEa

Teremos acesso ao manual do CCXT Pro antes de adquirir o produto, para entender todas as sutilezas do CCXT Pro?

sim. Estamos tornando-os perfeitamente compatíveis o máximo que podemos, então, pode acontecer que a maior parte do Manual já esteja lá ))

ou talvez seja incluído no manual básico?

Isso também é possível, sim.

Além disso, qual tecnologia CCXT escolheu para a biblioteca de streaming php? há muitas soluções, reactphp, amphp, catraca...

Para PHP estamos usando alguns componentes do ratchet e algumas partes do reactphp.

podemos ter algumas ideias sobre qual solução foi/é preferida para uso com fluxos CCXT?

Idealmente, você desejaria um link para o CCXT Pro Manual em vez deste comentário - isso responderia a todas as suas perguntas, é claro) No entanto, não posso dizer muito agora, postaremos mais atualizações ao longo do caminho (em prazos Mencionado acima).

você conseguiu executar alguns benchmarks para determinar qual solução se encaixaria mais nesse tipo de ferramenta?

Sim, fizemos nossa pesquisa) Se alguma parte disso se tornar um gargalo, vamos otimizá-lo.

e quanto ao lado do servidor, precisaríamos construir um processo/daemon específico em outra linguagem para lidar com o fluxo à medida que eles são enviados para o servidor WS?

Tanto o CCXT quanto o CCXT Pro são ferramentas do lado do cliente, o que significa que o cliente usa o CCXT e/ou o CCXT Pro para se conectar às APIs REST das exchanges ou aos seus servidores WS. O CCXT pode ser iniciado a partir de um navegador, da linha de comando, do nó, python ou php, pode ser agendado como um script, pode ser executado dentro de um servidor web e seu servidor também pode ser um cliente para trocas. Então, depende de como você configura suas coisas e como elas se relacionam umas com as outras. O CCXT Pro não terá um servidor WS dentro dele.

Se você deseja receber um fluxo de dados de uma exchange para seu servidor e deseja encaminhá-lo para seus clientes, isso é basicamente um proxy de multiplexação. Para isso, você usaria o CCXT em seu servidor para obter os dados e, em seguida, transmitiria para seus clientes com código de userland, dependendo das necessidades de seu aplicativo, projeto ou sistema. Servir websockets está fora do nosso escopo por enquanto. CCXT Pro foi projetado para ser um cliente eficiente ( ccxt-connects-to-exchanges ), para receber dados das exchanges e enviar dados para as exchanges por meio de canais de streaming, mas não foi projetado para funcionar como um servidor de streaming autônomo para atender a um multidão de outros clientes (sem clients-connecting-to-ccxt ). Seus clientes podem se conectar ao seu servidor, mas lidar com eles está além dos propósitos do CCXT Pro. Portanto, se você quer dizer esse uso específico, sim, talvez seja necessário adicionar alguma funcionalidade com os módulos npm existentes ou com seu próprio código, para ser um servidor WS-multiplexing-intermediary-proxy para seus clientes.

Se, no entanto, você quer dizer iniciar o código geral que usa o CCXT Pro em qualquer servidor ou computador em que seja iniciado - então, sim, ele foi projetado para funcionar de qualquer lugar, assim como o CCXT. De acordo com nossos princípios fundamentais de portabilidade , você não precisará codificar em outras linguagens para usar o CCXT Pro streaming em PHP no lado do servidor. Você vai usar apenas PHP. Ou nó. Ou Python. É melhor para você saber mais de uma linguagem de programação, mas não é necessário saber mais de uma linguagem para usar o CCXT Pro em toda a sua extensão.

Tínhamos uma definição diferente ou eu não estava claro, o que eu chamo de "lado do servidor" era na verdade um servidor hospedado executando uma cópia da biblioteca CCXT através do php que coleta dados e executa um conjunto de instruções com cron jobs, que também podem ser chamado de cliente de um ponto de vista diferente :P Não vendo o uso de um proxy de multiplexação.

O que eu tive dificuldade em imaginar foi como o CCXT teria um script permanentemente aberto, que permitiria ao php interpretar dados em tempo real e executar instruções com base na entrada e que não gerasse vazamentos ou travamentos; talvez através do uso do Supervisor. Que alcançaria o comportamento correto através de catraca. Lidar com esse tipo de processo em tempo real de forma eficiente pode rapidamente se tornar bastante complexo e exigir conhecimento no nível do sistema operacional.

Mal posso esperar para saber mais sobre isso!

Eu sou um desenvolvedor e administro uma startup de uma pessoa que faz bots de negociação comercial, que obviamente usam CCXT (em NodeJS). Até agora tive que usar outras bibliotecas para streaming, e há uma diferente para cada troca. Eu gostaria de poder usar o streaming CCXT, mas isso depende do preço. Eu tenho soluções alternativas (as outras bibliotecas ou escrevendo eu mesmo), mas elas também têm um custo. Não me oponho a pagar pelo suporte, mas não tenho certeza se o modelo de complemento Pro funcionará para minha empresa muito pequena, mas em crescimento. Será importante que seja rentável para o meu negócio, para obter toda a fonte para depuração e ter liberdade para executá-lo em qualquer número de máquinas sem que o uso seja medido ou limitado. Sinta-se à vontade para entrar em contato comigo para discutir os planos iniciais e ficarei feliz em fornecer feedback e até mesmo testes beta.

Ei @kroitor , eu e meu colega @Alescontrela estamos dispostos a ajudar no lado do desenvolvimento das coisas. No momento, estamos executando uma pequena estrutura com a intenção de resolver o problema exato para o qual o CCXT Pro está sendo feito; CryptoBook (API universal para trocas de criptografia, bem como suporte WebSocket). Podemos divergir alguns de nossos esforços para o CCXT Pro como desenvolvedores e testadores, pois achamos que pode valer mais a pena combinar esforços do que trabalhar em projetos separados. 👍🏼

Seria possível implementar o gate.io ws api v3 (https://gateio.io/docs/websocket/index.html#depth-subscription)?

@npomfret espero que sim, vamos tentar adicioná-lo.

Olá croitor,
Obrigado por todos os seus esforços.
Você pode me informar quando a API do Websocket, o Orderbookfetcher em tempo real, os detalhes de compra e venda em tempo real serão adicionados?
Eu preciso da versão websocket, ela está implementada?
Cumprimentos,

Oi. O feed kraken ws está explodindo com Cannot read property 'data' of undefined para alguns mercados. Tente XTZ/BTC por exemplo.

O erro está em:

_contextGetSymbolData(conxid, event, symbol) {
    return this.websocketContexts[conxid]['events'][event][symbol]['data'];
}

Espera-se que o evento ob seja algo como:

{ 'XTZ/BTC':
   { subscribed: true,
     subscribing: false,
     data: { depth: '50', limit: 200, ob: [Object], rawData: [Object] },
     params: {} } }

Mas, depois de alguns segundos (ou às vezes imediatamente) ele recebe algo assim:

{ 'XTZ/BTC':
   { subscribed: false,
     subscribing: true,
     data: { 'sub-nonces': [Object], limit: undefined, depth: 1000 } } }

Não consigo imprimir o JSON exato porque há uma estrutura circular em algum lugar aqui.

Meu código funciona com outros mercados (XTZ/ETH por exemplo). Não estou me inscrevendo duas vezes, ou re-subscrevendo, me inscrevendo em vários mercados ou qualquer coisa assim.

@npomfret você está usando o garfo de ifern? tem muitos bugs que provavelmente não serão corrigidos porque outro fork do websocket está sendo desenvolvido

você está usando o garfo de ifern

Eu sou sim.

outro fork do websocket está sendo desenvolvido

OK! Obrigado

qual é o status no ccxt pro? quando será esperado o lançamento?

@xCuri0 está em desenvolvimento muito ativo e vamos postar um anúncio independente dentro de uma semana ou duas. O lançamento está planejado para o terceiro trimestre, em setembro.

@kroitor quais exchanges serão suportadas no lançamento? seremos capazes de contribuir e adicionar mais trocas?

@xCuri0

@kroitor quais exchanges serão suportadas no lançamento?

Publicaremos mais detalhes nos próximos anúncios. Muitos deles estarão disponíveis, priorizaremos as principais exchanges por volume e reputação.

seremos capazes de contribuir e adicionar mais trocas?

Sim, veja este comentário: https://github.com/ccxt/ccxt/issues/56#issuecomment -508280756

Também estou aguardando o anúncio sobre a versão "pro" (paga). 15 dias se passaram, dê-nos mais informações por favor ;-D Se o preço estiver certo, comprarei a versão pro assim que for lançada.

@kroitor atualização no status do ccxt pro?

@teneon

Também estou aguardando o anúncio sobre a versão "pro" (paga). 15 dias se passaram, dê-nos mais informações por favor ;-D Se o preço estiver certo, comprarei a versão pro assim que for lançada.

Não posso revelar a grade de preços completa agora. No entanto, como mencionado acima, o plano mais simples será comparável a uma assinatura mensal de TV a cabo, em torno de US$ 20-25. Para os madrugadores, também ofereceremos um desconto de aproximadamente um quarto do preço, reduzindo-o para US$ 15-20 por mês. Os principais contribuidores receberão uma licença gratuita do CCXT bRO.

O que você recebe:

  • transmissão
  • acesso ao código fonte
  • correções, atualizações e suporte
  • novas trocas (integrações mais rápidas)
  • nova funcionalidade

@xCuri0

@kroitor atualização no status do ccxt pro?

Neste ponto, terminamos o trabalho no subsistema de licenciamento que opera sobre os repositórios do GitHub. Esse componente foi de missão crítica, pois o código-fonte do CCXT Pro estará disponível para os licenciados e buscamos a proteção dos direitos intelectuais até certo ponto. O plano era lançar o CCXT Pro este mês. Ainda estamos ocupados em algumas partes do código principal, mas a maior parte do trabalho duro está feito. Você deve ter notado que a frequência de atualizações deste repositório do MIT CCXT diminuiu recentemente, isso está diretamente relacionado, pois agora passamos a maior parte do nosso tempo trabalhando para lançar o CCXT Pro, é nossa principal prioridade. Esperamos anunciar o lançamento em cerca de 4 semanas, e postarei mais detalhes sobre nosso progresso quanto mais nos aproximarmos da meta.

Obrigado!

@kroitor , a nova estrutura do WS fornecerá eventos 'trade'?

@maayank , não haverá eventos, apenas promessas resolvidas. Então em js e python você chamará um binance.fetchWsTicker e ele retornará uma promessa/futuro, que se completa assim que a mensagem chegar. Portanto, da perspectiva dos usuários, ele funcionará perfeitamente com o restante do ccxt. simplesmente await binance.fetchWsTicker(symbol, etc) . Em php, usaremos retornos de chamada, mas o código de troca derivado permanece transpilável graças a alguma codificação inteligente da equipe de desenvolvimento do ccxt;)

maayank em suma, sim.

@kroitor E os preços para estudantes? Na msg acima, você disse que fornecerá acesso gratuito à sua biblioteca. Como validar os alunos?

@frosty00 e se você quiser usar eventos? eu acho que o ccxt pro deve adicionar suporte para eles

@xCuri0 é feito em princípios semelhantes aos geradores e, simplificando, funcionalmente é um superconjunto que cobre o modelo de eventos, ou seja, é flexível o suficiente em seu núcleo. Assim, se você quiser eventos - você pode facilmente criar um wrapper semelhante a um evento e provavelmente incluiremos alguns exemplos de uso como uma interface no estilo de retorno de chamada.

A versão CCXT pro terá dados de preços em tempo real? ou apenas livros de encomendas e saldos. Preciso dele para um aplicativo no qual estou trabalhando e preferiria websockets em vez de pesquisa.
Algo como ccxws , apenas mais trocas suportadas.

@amitkukadia

A versão CCXT pro terá dados de preços em tempo real? ou apenas livros de encomendas e saldos.

Quando você diz _"dados de preços"_, você pode listar quais informações específicas você quer dizer?
Em geral, o CCXT Pro suportará o maior número possível de tipos de streams, incluindo:

  • tickers
  • livros de pedidos
  • comércios públicos (preenchimentos)
  • outros fluxos públicos, se houver
  • atualizações de conta
  • atualizações de saldo
  • comércios privados
  • atualizações de pedidos
  • outros fluxos privados, se houver
  • ...

OHLCV e preenchimentos de comércio. Parece que será coberto. Obrigado @kroitor .

Olá @kroitor ,
há alguma notícia sobre CCXT pro? Setembro está chegando ao fim. Tudo bem, mesmo que seja beta, gostaríamos de ver a API e alguns documentos, para que possamos começar a experimentar e implementar. Não precisa ser perfeito desde o início? Pelo menos nos atualize com informações a cada poucos dias, é muito melhor do que o silêncio.

Atenciosamente!

não haverá eventos, apenas promessas resolvidas. Então em js e python você chamará um binance.fetchWsTicker e ele retornará uma promessa/futuro, que se completa assim que a mensagem chegar.

@frosty00 Será possível assinar um ticker ou negociar um par de ativos ou todos os pares?
algo como

binance.on('trade', data =>{
    console.log(data)      
})

Alguma atualização no CCXT Pro em outubro? @kroitor

@amitkukadia , este exemplo de websocket não faz parte da implementação futura do ccxt pro. Mas seria bom que o ccxt pro implementasse esse recurso.

@lfern , definitivamente implementaremos esse recurso e hospedaremos uma demonstração de vários livros de pedidos de troca no site ccxt pro. Por alguma razão, o websocket ignora a política de mesma origem na maioria dos navegadores que deveria parar ataques xss, tanto para a segurança do navegador...

@xCuri0 está chegando em breve; Estamos trabalhando nisso. Eu estimaria que no próximo mês poderia ser lançado, mas isso depende de muitos fatores, então não podemos dar uma data exata de lançamento.

@amitkukadia sim, será possível assinar tickers e trades (que é um dos principais pontos de venda)

@frosty00 Isso parece ótimo!
Você já tem um site dedicado para CCXT pro?

Eu usei https://developers.shrimpy.io , o WS deles era gratuito por 16 trocas, mas agora eles estão cobrando 350+/mês por isso, se você assinar 100 moedas (6 por troca), isso é demais NA MINHA HUMILDE OPINIÃO.

Com o camarão, eu tinha que acompanhar as atualizações do livro e cancelar e re-assinar se eu perdesse uma sequência, isso era meio inconveniente. Você vai lidar com isso de forma semelhante ou automatizá-lo, para que o software gere/solicite um instantâneo de livro como a cada minuto?

Você vai lidar com isso de forma semelhante ou automatizá-lo, para que o software gere/solicite um instantâneo de livro como a cada minuto?

Todo o processo será automatizado, então você não terá que lidar com deltas ou atualizações do livro de pedidos, em vez disso, você só terá que lidar com o objeto inteiro do livro de pedidos mais recente. Também garantiremos que nenhuma sequência ou nonces seja ignorado ao lidar com dados incrementais.

O lfern fork suporta os parâmetros do livro de pedidos da binance (https://www.binance.com/en/support/articles/360032916632) permitindo que a profundidade e a frequência sejam especificadas?

@npomfret Acabei de adicionar. Parece que funciona, mas precisaria de algum teste.
Este exemplo para testar a carteira de pedidos parcial;

node examples/js/websocket-playground.js binance partob ETH/BTC obdepth:20 obinterval:100ms

E este para intervalo orderboo de 100ms

node examples/js/websocket-playground.js binance ob ETH/BTC obinterval:100ms limit:5

O lfern fork suporta os parâmetros do livro de pedidos da binance (https://www.binance.com/en/support/articles/360032916632) permitindo que a profundidade e a frequência sejam especificadas?

Esperamos que algumas pessoas se oponham a fazer do CCXT Pro um projeto comercial e estamos interessados ​​em suas opiniões

Eu sou dessas pessoas 😄
Vou postar minha opinião, desde que você esteja interessado em ouvir
Eu pago se gerar lucro com a integração da biblioteca - e se meu projeto ainda for apenas uma ideia ou beta
Não vou gerar dinheiro agora - então por que pagar?
que tal dar um teste gratuito com muito tempo, 6 meses ou ano
para garantir que a pessoa que comprar o código levará tempo suficiente para desenvolver e publicar seu projeto antes de gerar dinheiro e pagar.

que tal dar um teste gratuito com muito tempo, 6 meses ou ano
para garantir que a pessoa que comprar o código levará tempo suficiente para desenvolver e publicar seu projeto antes de gerar dinheiro e pagar.

Você está perdendo um ponto "um tanto importante". Há pessoas que trabalham duro para desenvolver e compartilhar esta grande biblioteca e devem ser pagas por seu trabalho. CCXT é uma ótima biblioteca, está ativa, é mantida e é gratuita para todos nós usarmos. Acho que você pode ver o CCXT Pro como o próximo passo, e provavelmente haverá um manual do usuário que você pode acessar gratuitamente para desenvolver seu projeto. Se você usa, confia e gosta do CCXT, sabe o que esperar do CCXT Pro. A taxa/custo que você será solicitado a pagar é uma questão diferente, e cabe a você avaliar se pode ter um ROI e lucros.

Eu pago se eu gerar lucro com a integração da biblioteca

Uma abordagem ainda melhor seria apenas pedir os lucros que você gostaria de ter...

Uma abordagem ainda melhor seria apenas pedir os lucros que você gostaria de ter...

Eu entendo que você e eu não posso pagar antes de gerar dinheiro,
no entanto, não há problema - encontrei outra biblioteca para usar com o CCXT.

Acho que vai ser uma boa mistura

Eu realmente aprecio e gostaria de apoiar esses projetos de código aberto, seja com contribuição financeira ou com outra forma de contribuição.

Simplesmente, meu projeto não estará ativo e utilizável sem esses projetos de código aberto.
Posso ter falta de orçamento :blush:

@frodoe7 Qual biblioteca você usa? O camarãoy.com está oferecendo planos de 19/mês agora para 17 trocas de websocket transmitindo todos os canais. Então eu acho que o ccxt pro pode ter um preço semelhante. Shrimpy não é tão conveniente para integrar, você precisa rastrear atualizações perdidas da carteira de pedidos e também há um limite de assinatura por cliente, então você precisa escrever uma lógica extensa para lidar com isso e distribuir assinaturas em diferentes IPs.

@KlausGlueckert , Não Camarão
este: https://www.npmjs.com/package/ccxws
ele suporta menos trocas, mas inicialmente está tudo bem para mim

Eu entendo que você e eu não posso pagar antes de gerar dinheiro,
no entanto, não há problema - encontrei outra biblioteca para usar com o CCXT.

@frodoe7 Eu tenho ideia de qual é o seu projeto, e o que eu escrevo abaixo pode ser uma perda de tempo para ler, ou mesmo fora do tópico, mas eu escrevo com toda a bondade no coração, e é o que eu tenho aprendeu ao longo de vários anos.

Cada bolsa é um 'animal' diferente, com sua própria tabela de taxas, precisão diferente para cada moeda e par, valores mínimos e máximos diferentes, bem como traders diferentes, com mentalidade própria (às vezes coletiva), volumes diários diferentes para cada par , etc. etc. E mesmo que você tenha uma noção de como uma bolsa "funciona" e possa realmente ganhar dinheiro com ela, espere que tudo isso mude. Eu já vi isso muitas vezes. Ter uma carteira de pedidos atualizada o tempo todo não é realmente importante, pois não garante que seus pedidos sejam concluídos quando você espera. Não somos os únicos a "consumir" os pedidos certos... Além disso, ter uma lógica de aplicação sólida não garante que seja a lógica certa para a troca em que você está trabalhando. Negociar é negociar; não é 1+1=2. É uma corrida contra outros traders, que têm mais dinheiro, código melhor, máquinas mais rápidas e estão em redes mais rápidas. E então você tem bombas e despejos, você tem preços subindo, subindo, subindo e depois descendo, descendo e descendo, e tudo mais que você não pode imaginar que realmente acontecerá. A menos é claro que você tenha a lógica perfeita para todas as condições e situações, além de máquinas super rápidas sentadas no data center de cada exchange, ao lado de seus servidores de API. Se sim, invejo-te :)

Se você não é um trader experiente e um desenvolvedor experiente para negociação, você deve esperar perder dinheiro antes de ganhar dinheiro. E mesmo que você comece a ganhar dinheiro com sua primeira troca imediatamente, é provável que você perca com a segunda. Se a taxa que teremos de pagar pela versão Pro for semelhante ao que foi mencionado nos posts anteriores, é apenas uma fração das perdas iniciais. Confie em mim.

Com tudo o que foi dito acima, sugiro que você comece a usar o CCXT como está (sem suporte a websocket), e quando a versão Pro for lançada, você terá que substituir algumas chamadas. Se você achar que está atingindo os limites de certas trocas, não é de websockets que você precisa.

Apenas meu 2c

Com tudo o que foi dito acima, sugiro que você comece a usar o CCXT como está (sem suporte a websocket), e quando a versão Pro for lançada, você terá que substituir algumas chamadas. Se você achar que está atingindo os limites de certas trocas, não é de websockets que você precisa.

já tem problema no meu projeto , e é obrigatório usar websocket agora , nem vejo a hora do CCXT Pro ser lançado

@lfern obrigado pelas melhorias da Binance, testando-as agora - parece ótimo.

@lfern você já considerou usar um RBTree em vez de um array para armazenar os dados? Estou testando no meu projeto e deu certo. É bem simples de implementar e _assumo_ mais eficiente do que usar um array (mas não testei a teoria). Feliz em compartilhar meu código em uma essência pública se você estiver interessado.

@npomfret enquanto aguarda a implementação oficial do websocket, se for realmente fácil, é claro que tentarei alterá-lo no branch websocket-multiple.

@lfern dê uma olhada nisso: https://gist.github.com/npomfret/a52fab1144090204425f984ea132e45e

Não posso prometer que o RBTree seja mais rápido, mas suspeito que seja.

@npomfret que parece bem interessante. Usamos TreeMap para cada lado do livro com um classificador personalizado. Eu não estou tão familiarizado com o RBTree, mas estou curioso por que você o usaria no TreeMap? Posso dizer por experiência que usar o TreeMap foi uma opção muito melhor do que matrizes para um livro de pedidos ao vivo durante uma ação de preço pesada

Ah desculpe, eu pensei que você ainda estava usando arrays, não lia o código há algum tempo. Eu não sei o quão eficiente é o TreeMap, receio. Uma árvore vermelha/preta tem um perfil de desempenho bem entendido ( O log(n) para pesquisa e exclusões), talvez TreeMap seja o mesmo.

Um RBTree é muito simples, eu usei uma classe NPM, mas você pode escrevê-lo em 10 minutos, tenho certeza.

[editar] ha, é o mesmo - o desempenho é mencionado logo na parte inferior dos documentos. Então não adianta trocar.

@lfern você já considerou usar um RBTree em vez de um array para armazenar os dados?

Por que você usaria isso usando um hashmap regular indexado por preços que é O(1)? Armazenar e buscar dados de uma árvore binária é pelo menos log(N) assintoticamente, então não faz muito sentido - https://docs.google.com/presentation/d/1FVENq6nVfWEHohE8j3oQC6uutxWOghacBfJixFV3KQU/edit#slide =id. g5240c8ba42_0_1460

@frosty00 Não sou especialista em estruturas de dados (não tenho educação formal e devo reconhecer com vergonha que nunca pesquisei adequadamente sobre isso), então corrija-me se estiver errado.

Pelo que vi on-line, os hashmaps geralmente são melhores para inserir/atualizar/excluir de elemento único, enquanto as árvores de autobalanceamento têm melhor desempenho para iterar em intervalos. Com base nisso, eu diria que optar por um ou outro dependeria do seu caso de uso de leitura (no nosso sempre buscamos o X superior após qualquer inserção/atualização/exclusão, portanto um RBTree faz mais sentido).

Por outro lado, os hashmaps normalmente funcionariam com base no agrupamento pelo hash, mas isso é propenso a perda de velocidade se houver altas concentrações em um único balde enquanto outros baldes tiverem poucos elementos.

@lfern (ou @frosty00 ?) muito tempo sem atualização do meu lado, tentei transpilar o estado real do branch websockets-multiple de lfern. Recebo muitos erros em python quando executo ob_updater.py no meu projeto https ://github.com/firepol/ccxt-websockets-db-updater... Tentei corrigir alguns deles manualmente (veja os últimos commits no ramo dev do meu outro repo, onde costumo confirmar os arquivos transpilados: https://github.com/firepol/ccxt-websockets/tree/dev), para ver se meu programa funciona, mas no final não é sempre mais um erro de sintaxe que aparece. Aqui os erros de sintaxe que recebi e como os corrigi:

Arquivo "\venv\lib\site-packagesccxt\kucoin.py", linha 1623
lastSeqId++
^
SyntaxError: sintaxe inválida

Solução : pesquise todos os "++" e substitua por " += 1"

Arquivo "..,\venv\lib\site-packagesccxt\poloniex.py", linha 1301
outro:
^
IndentationError: esperava um bloco recuado

Solução : um comentário não é suficiente para python, em python eu adiciono, por exemplo, "pass", idealmente não use um bloco elif ou else vazio, mas coloque um comentário antes ou depois ... se você realmente precisar de um bloco vazio, declare uma variável fictícia como foo = 'foo' ou algo assim ...

Arquivo "...\venv\lib\site-packagesccxtasync_support\baseexchange.py", linha 1059
resposta = await getattr(this_param, method)(*params)
^
SyntaxError: 'await' fora da função assíncrona

Solução : não faço ideia ... você tem que encontrar uma correção para isso ...

obrigada

Pessoal, por favor, definam uma data de lançamento para o CCXT pro e, em seguida, liberem em uma data específica, qualquer que seja, sempre haverá alguns bugs com certeza desde o início, mas vamos cuidar disso mais tarde, precisamos começar a implementar e experimentar, mesmo que não seja perfeito desde o início! Caso o lançamento do "ccxt pro" vá para 2020, por favor, diga! Devemos então implementar o pacote "ccxws" nesse meio tempo em nosso projeto. Mas se "ccxt pro" estiver chegando, eu não quero implementar "ccxws" apenas por uma semana ou duas e depois reimplementar "ccxt pro". Então, por favor, é importante para nós e provavelmente para todos os outros, para que possamos planejar com antecedência.

Pessoal, por favor, definam uma data de lançamento para o CCXT pro e, em seguida, liberem em uma data específica, qualquer que seja, sempre haverá alguns bugs com certeza desde o início, mas vamos cuidar disso mais tarde, precisamos começar a implementar e experimentar, mesmo que não seja perfeito desde o início!

Estamos totalmente de acordo com você e tem sido nossa maior prioridade desde que anunciamos.

Caso o lançamento do "ccxt pro" vá para 2020, por favor, diga!

Estamos determinados a não deixá-lo avançar para 2020 e agora temos certeza de que não o fará. A partir daqui, pode levar de 2 a 4 semanas para lançar a versão inicial se nada mais aparecer. Mas, de qualquer forma, será lançado antes do final deste ano.

Mas se "ccxt pro" estiver chegando, eu não quero implementar "ccxws" apenas por uma semana ou duas e depois reimplementar "ccxt pro".

Está chegando e estamos trabalhando muito para entregá-lo o mais rápido possível, sério. Não podemos dizer a data exata, pois podemos entregar antes disso. No entanto, será lançado imediatamente quando estiver pronto. Se você ainda quiser a data exata, assuma "antes do final de 2019".

@firepol Acho que corrigi todos os erros de python que você relatou em websockets-multiple branch., Por favor, confira

@kroitor Você tem alguma informação sobre licenciamento e cronograma de taxas que possa compartilhar antes do lançamento do Pro?

@WoK-E postamos sobre este assunto aqui:

Atualizaremos você sobre a grade de preços antes do lançamento assim que a tivermos (nosso objetivo é lançar um design de tecnologia bom e flexível para os usuários, em primeiro lugar).

@kroitor o CCXT pro terá o tratamento adequado das mensagens do livro de pedidos diff que chegam fora de sequência?

EDIT: ignore esta pergunta. Acabei de ver seu post acima. Obrigada.

@frodoe7 você sempre pode implementar soquetes da web para uma ou duas trocas enquanto espera para ver se vale a pena pagar pelo CCXT pro. Eu tenho feito exatamente isso enquanto espero o lançamento e realmente não é tão difícil. Eu tenho ws-feeds públicos (livros de pedidos) e privados (minhas negociações e pedidos) funcionando para 6 trocas e não posso dizer que algum foi particularmente difícil de fazer.

Alguma palavra sobre quando o CCXT Pro será lançado? 1 de janeiro de 2020 está se aproximando rapidamente!

@n01ukn0w estamos mais perto do que nunca de lançá-lo finalmente e anunciaremos o teste beta em breve.

@n01ukn0w estamos mais perto do que nunca de lançá-lo finalmente e anunciaremos o teste beta em breve.

Tão empolgante, estou prestando muita atenção a esse problema por um mês, ansioso para experimentar o Pro pela primeira vez.

Seria bom ter trechos de usos para vários frameworks JS, especialmente para Angular/Typescript.
Se ele pode lidar com coisas como Nativescript, seria incrível! Embora de meus testes recentes a biblioteca ws npm não funcione bem com o NS. Quer saber o que é usado para streaming sob o capô?

@kroitor : muito animado também e muito obrigado por todo o trabalho!!! algumas perguntas antes:

  • haverá um wrapper Python desde o início?
  • o ccxt pro lidará com as sequências do livro de pedidos automaticamente? (sem conexão manual, lógica de reconexão etc)
  • o ccxt pro lidará automaticamente com os livros de pedidos atuais na memória? algumas trocas fornecem apenas instantâneos do livro de pedidos da API REST, então você precisa criar sua própria lógica para obter os instantâneos REST e atualizá-los com as atualizações do livro de pedidos do websocket :(
  • se você precisar de alguma entrada ou feedback, deixe-me saber, eu integrei recentemente o camarãoy.io, e ele simplesmente não resolve todos os problemas que um desenvolvedor tem, o ccxt pro pode ser muito melhor do que tudo disponível atm

@Klaus Glueckert

haverá um wrapper Python desde o início?

Sim.

o ccxt pro lidará com as sequências do livro de pedidos automaticamente? (sem conexão manual, lógica de reconexão etc)

Sim, e os outros tipos de feeds de dados também.

o ccxt pro lidará automaticamente com os livros de pedidos atuais na memória? algumas trocas fornecem apenas instantâneos do livro de pedidos da API REST, então você precisa criar sua própria lógica para obter os instantâneos REST e atualizá-los com as atualizações do livro de pedidos do websocket :(

Sim, isso também é tratado.

se você precisar de alguma entrada ou feedback, deixe-me saber, eu integrei recentemente o camarãoy.io, e ele simplesmente não resolve todos os problemas que um desenvolvedor tem, o ccxt pro pode ser muito melhor do que tudo disponível atm

Thx muito para o seu apoio, vou deixar você saber se alguma coisa!

Caso o lançamento do "ccxt pro" vá para 2020, por favor, diga!

Estamos determinados a não deixá-lo avançar para 2020 e agora temos certeza de que não o fará. A partir daqui, pode levar de 2 a 4 semanas para lançar a versão inicial se nada mais aparecer. Mas, de qualquer forma, será lançado antes do final deste ano.

Mas se "ccxt pro" estiver chegando, eu não quero implementar "ccxws" apenas por uma semana ou duas e depois reimplementar "ccxt pro".

Está chegando e estamos trabalhando muito para entregá-lo o mais rápido possível, sério. Não podemos dizer a data exata, pois podemos entregar antes disso. No entanto, será lançado imediatamente quando estiver pronto. Se você ainda quiser a data exata, assuma "antes do final de 2019".

@kroitor - como está o lançamento agora? Suponho que isso não acontecerá antes de 2020, então qual é o próximo alvo? É melhor manter o ppl atualizado mesmo com o alvo em movimento do que não ter atualizações - neste caso, parece que nada vai acontecer, pois suas prioridades podem ter mudado para outra coisa

@juso , o trabalho está se movendo muito ativamente para o lançamento (é uma questão de dias agora). Já temos um repositório transpilável em funcionamento e vamos convidar testadores beta no início de janeiro. A falta de atualizações não significa que nossas prioridades mudaram, é o contrário – ainda é nossa prioridade máxima e estamos tão ocupados com isso que não podemos postar atualizações com muita frequência, exceto “quase lá”. Outro aspecto disso é que queremos lançar um produto de trabalho estável. Nosso progresso atual é de 85-90%. Publicaremos mais novidades e divulgaremos a grade de preços nos próximos dias.

@kroitor onde/como você publicará notícias no CCXT Pro e/ou convites para testadores beta? Será neste tópico?

@WoK-E, abriremos um tópico de anúncio independente e postaremos links aqui também para notificar todos sobre este problema.

Feliz Ano Novo a todos! Acabei de publicar um pequeno roteiro de atualização/intermediário para o primeiro trimestre aqui: https://github.com/ccxt/ccxt/issues/6332. Estamos fazendo todo o possível para lançá-lo este mês.

Nós unificamos a API de balanceamento, conforme escrito aqui, na edição #36 . Agora sua solicitação de recurso pode ser implementada facilmente ) Primeiro, adicionaremos um método de saldo sujo que salvaria o saldo em uma instância de mercado. E quando estivermos prontos para liberar as implementações do Websocket, faremos a atualização automática, é claro. Mantenha contato! )

Estava rolando depois de ver a atualização sobre os planos do ccxt pro e não pude deixar de notar isso / sua resposta a alguém perguntando sobre a pesquisa da API em intervalos? E gostaria apenas de salientar que a Binance tem um endpoint de websocket para dados comerciais e de contas. Só precisa se inscrever no stream "userData": https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md

Além disso, caso alguém esteja interessado, tenho usado isso para minhas necessidades de websocket binance, espero que vocês achem tão útil quanto eu: https://github.com/oliver-zehentleitner/unicorn-binance-websocket-api /

@HoDaDor é exatamente disso que trata o CCXT Pro, usando os WebSockets para streaming: https://github.com/ccxt/ccxt/issues/6332#issuecomment -586626802 (hoje)

Olá, queridos usuários do CCXT!

Hoje trazemos-lhe a boa notícia.

Lançamos o CCXT Pro com suporte para WebSockets!
Por favor, veja o anúncio aqui: #6543

Obrigado a todos que esperaram tão pacientemente por isso.
Como sempre, seu feedback é muito apreciado!

Finalmente, estamos fechando esta edição)

Atenciosamente, Equipe de desenvolvimento do CCXT

Esta página foi útil?
0 / 5 - 0 avaliações