Tuesday 20 March 2018

Akka trading system


sistema comercial Akka
Obter através da App Store Leia esta publicação em nosso aplicativo!
Negociação de alta freqüência na JVM com Scala / Akka.
Imagine um sistema HFT hipotético em Java, exigindo (muito) baixa latência, com muitos objetos pequenos de curta duração um pouco devido à imutabilidade (Scala?), Milhares de conexões por segundo e um número obsceno de mensagens que circulam em um Arquitetura baseada em eventos (akka e amqp?).
Para os especialistas lá fora, o que seria (hipoteticamente) o melhor ajuste para JVM 7? Que tipo de código faria feliz? Scala e Akka estarão prontos para este tipo de sistemas?
Nota: houve algumas perguntas semelhantes, como esta, mas ainda tenho encontrado uma cobertura Scala (que tem sua própria pegada idiossincrática na JVM).
No meu laptop, a latência média das mensagens de ping entre os atores Akka 2.3.7 é.
300ns e é muito menor do que a latência esperada devido a pausas GC em JVMs.
Código (incluindo opções JVM) e amp; resultados de teste para Akka e outros atores no Intel Core i7-2640M aqui.
P. S. Você pode encontrar muitos princípios e dicas para computação de baixa latência no site de Dmitry Vyukov e no blog de Martin Thompson.
É possível alcançar um desempenho muito bom em Java. No entanto, a questão precisa ser mais específica para fornecer uma resposta credível. Suas principais fontes de latência virão de seguir a lista não exaustiva:
Quanto lixo você cria e o trabalho do GC para coletá-lo e promovê-lo. Projetos imutáveis ​​na minha experiência não se encaixam bem com baixa latência. O ajuste do GC precisa ser um grande foco.
Aqueça a JVM para que as classes sejam carregadas e o JIT tenha tido tempo para fazer seu trabalho.
Desenhe seus algoritmos para ser O (1) ou pelo menos O (log2 n), e ter testes de desempenho que afirmam isso.
Seu design precisa ser livre de bloqueio e seguir o "Princípio do Único Escritor".
Um esforço significativo deve ser levado a entender a pilha inteira e demonstrar simpatia mecânica em seu uso.
Desenhe seus algoritmos e estruturas de dados para serem amigáveis ​​com o cache. As falhas de cache agora são o maior custo. Isso está intimamente relacionado com a afinidade do processo que, se não configurado corretamente, pode resultar e poluição significativa do cache. Isso envolverá simpatia pelo sistema operacional e até mesmo algum código JNI em alguns casos.
Certifique-se de ter núcleos suficientes para que qualquer thread que precisa ser executado tenha um núcleo disponível sem ter que esperar.
Recentemente bloguei sobre um estudo de caso de tal exercício.
Você pode achar que o uso de um buffer de toque para a passagem de mensagens superará o que pode ser feito com o Akka. A principal implementação do buffer de anel que as pessoas usam na JVM para aplicações financeiras é chamada de Disruptor, que é cuidadosamente sintonizado para eficiência (potência de dois tamanhos), para a JVM (sem GC, sem bloqueios) e para CPUs modernas (sem compartilhamento falso de linhas de cache).

Ainda outro Akka Benchmark.
Posso dizer imediatamente que o desempenho de Akka Actors é excelente em comparação com os atores de Scala.
Antes de olhar para o benchmark, descreverei brevemente o aplicativo de amostra.
Um sistema de negociação é essencialmente sobre como combinar pedidos de compra e venda. Um pedido de limite é uma ordem para comprar uma garantia em não mais, ou vender a não menos, do que um preço específico. Por exemplo, se um investidor quiser comprar um estoque, mas não quer pagar mais de US $ 20 por isso, o investidor pode fazer uma ordem de limite para comprar o estoque em US $ 20 e # 8220 ou melhor # 8221 ;. Existem muitos outros tipos de pedidos e restrições especiais. A amostra apenas está gerenciando ordens de limite simples.
As encomendas que estão longe do melhor preço atual no mercado são coletadas em um livro de pedidos para a segurança, para posterior execução.
Um motor correspondente administra um ou mais cadernos de encomendas, ou seja, o mercado é destruído por um livro de pedidos. Os mecanismos de correspondência mantêm o estado atual dos livros de encomendas. Os clientes se conectam a um serviço de recebedor de pedidos, que é responsável por rotear a ordem para o mecanismo de correspondência correto. O destinatário da ordem é sem estado e os clientes podem usar qualquer receptor de pedidos independente do livro de pedidos.
Para redundância, os motores correspondentes funcionam em pares. Cada ordem é processada por ambos os motores correspondentes. O pedido também é armazenado em um registro de transações persistente, por ambos os mecanismos correspondentes. Em uma configuração real, os mecanismos de correspondência primária e de espera geralmente são implantados em centros de dados separados.
Agora, até o ponto de referência. O cenário de teste colocou ordens de compra e venda em 15 livros de pedidos, divididos em 3 motores correspondentes. As ordens estão em níveis de preços diferentes, de modo que uma profundidade de catálogo de pedidos é construída, mas no final todas as encomendas são negociadas e que são verificadas pelo teste JUnit executando o benchmark.
O cenário foi executado em carga diferente, variando o número de clientes simulados de 1 a 40.
Os resultados de referência aqui ilustrados foram realizados em uma caixa real de 8 núcleos (máquina dupla de Xeon 5500, 2.26 Ghz por núcleo).
Aqui estão o resultado do processamento de pedidos 750000 em cada nível de carga.
A solução básica usa invocações de métodos síncronos comuns. É extremamente rápido, mas não é uma opção para uma solução escalável verdadeira. A passagem de mensagens assíncronas é uma alternativa melhor para dimensionamento em nós múltiplos ou múltiplos.
Nas soluções Scala e Akka Actors, os clientes enviam cada mensagem de ordem a um destinatário e aguardam a resposta Future (!? Operator in Scala and !! in Akka). O receptor de pedidos encaminha a solicitação para o motor correspondente responsável pelo caderno de pedidos, ou seja, o segmento / despachante do receptor de pedidos pode ser usado imediatamente para o próximo pedido. O mecanismo correspondente envia a mensagem da ordem para o modo de espera e ambos os mecanismos correspondentes processam a lógica correspondente e o log de transações em paralelo. Confirmação é respondida ao cliente quando ambos estão concluídos.
Os resultados de referência mostram que os Akka Actors são capazes de processar três vezes mais pedidos em comparação com os Atores Scala na mesma carga. Resultado semelhante com latência. A latência de Akka Actors é um terço dos atores Scala. Isso também é válido para baixa carga. A latência média nem sempre é a melhor medida, então deixe-nos olhar alguns percentis.
As operações que estão à espera de um futuro para completar foram usadas no envio de mensagens. Isso tem uma etiqueta de preço de escalabilidade, uma vez que o segmento está bloqueado enquanto espera que o Futuro seja concluído. Uma melhor escalabilidade pode ser alcançada com a passagem de mensagens unidirecional, que é ilustrada pelas soluções unidirecionais Scala / Akka Actor. Ele usa operação bang (!) Para enviar todas as mensagens.
Os mecanismos de correspondência escrevem cada ordem para um arquivo de log de transações. Este é um bloqueio de bloqueio de IO. Para empurrar o teste de mensagem passando um passo adiante, o benchmark também foi executado sem o log de transações. A solução Akka brilha ainda mais. Mais de três vezes maior taxa de transação em comparação com Scala Atores na mesma carga, ao usar a solução com o envio de mensagens e aguardando resposta. Para as soluções de passagem de mensagens unidireccionais, os atores Akka são duas vezes mais rápidos do que os atores Scala.
A Akka tem uma grande flexibilidade quando se trata de especificações de diferentes mecanismos de despacho. O Akka Actor hawt está incluído no benchmark como uma comparação com a solução unidirecional Akka Actor. Ele usa a biblioteca Threading HawtDispatch, que é um clone Java de libdispatch. O último teste sem registro de transações mostra que o HawtDispatcher possui um desempenho ligeiramente melhor do que o despachante baseado em eventos que foi usado para Akka Actor de um jeito.
O código-fonte completo para o aplicativo de exemplo está localizado em: github / patriknw / akka-sample-trading.
Para executar o benchmark você mesmo, você pode baixar e descompactar a distribuição, contendo todos os arquivos jar necessários. O README incluído descreve como executar os testes.
Nota de atualização 15 de agosto: Adicionado a solução One-Way de Scala Actor e uma nova descrição de como executar o benchmark.
Nota de atualização 22 de agosto: Novo benchmark executado na caixa real de 8 núcleos.
5 Comentários.
Boa coisa & # 8230; Acabei de acelerar rapidamente o código para o & # 8220; regular & # 8221; Os atores de Scala e algumas coisas saltaram para mim. O primeiro é que, em vez de usar o ForkJoinPool padrão, você personalizou os seus agendadores uma quantidade razoável. Há muitas boas razões para fazer isso, mas eu me pergunto por que você fez? Os atores Scala (com reações) baseados em eventos sofrem uma penalidade de desempenho quando não são executados no ForkJoinPool. O segundo é que você está usando o loop / reagir. I & # 8217; d sugere que em vez de usar o loop, você faz uma chamada recursiva para a função que contém reagir. Na minha experiência, isso é substancialmente mais rápido.
Mas é bom ver alguém fazendo benchmarks reais e postar o código. Mantem!
Agradeço os comentários. Inicialmente, tive problemas para executar tudo no meu laptop com pool de threads padrão (inanição), mas agora acho que entendo o porquê, por isso pode ser bom voltar para o pool de threads padrão para alguns atores.
Meus testes iniciais do pool de threads padrão e também recebem mostram que é apenas uma pequena melhoria. Vou testar mais e, provavelmente, usar suas sugestões como padrão. Obrigado novamente.
Obrigado por este benchmark, mas # 8230; quem se interessa por cerca de 40 clientes concorrentes? 40 clientes concorrentes podem ser facilmente implementados com um segmento por modelo de cliente.
Por que não executar este benchmark com 40.000 clientes? Isso mostraria um problema de escalabilidade real (atores famintos?) E destacar a sobrecarga da akka em mudar os atores.

sistema comercial Akka
Puxe pedidos 0.
Participe do GitHub hoje.
O GitHub é o lar de mais de 20 milhões de desenvolvedores que trabalham juntos para hospedar e rever o código, gerenciar projetos e criar software juntos.
Clone com HTTPS.
Use o Git ou o check-out com o SVN usando o URL da web.
A Ergodicity é uma plataforma de negociação automatizada baseada em atores de código aberto, fornecendo ferramentas para negociação orientada para a estratégia com o uso de dados de mercado de Nível 1 e Nível 2. A Ergodicity suporta a conectividade direta de dados de mercado com a Bolsa de Valores do "Russian Trading System" usando seu protocolo proprietário Plaza2 para execução em tempo real de baixa latência. Além disso, fornece mecanismo tick-by-tick backtest para executar as mesmas estratégias em dados históricos armazenados no MarketDb para análise de desempenho e otimização.
A Platfrom usa Scala como idioma primário e depende da arquitetura baseada em eventos usando Akka Actors para concorrência e escalabilidade.
O projeto MarketDb também é parte da plataforma de Ergodicity e usado para captura e captura de dados de mercado.
backtest - estratégias de captura de quadros de backtesting - captura de dados de mercado usando conectividade de mercado direto com RTS CGate API cgate - abstração baseada em ator em CGate núcleo - componentes principais da plataforma: pedido, OrderBook, Trade, Session etc. engine - esquema de mecanismo de execução de estratégia - projeto compartilhado para backtest e `capture 'com esquema de banco de dados.
A ergodicidade é construída usando a arquitetura conduzida por eventos. Todos os dados de mercado recebidos da Bolsa de Valores (comércio, adicionar ordem, cancelar pedido, atualizações de sessão, etc.) considerados como um evento. Componentes principais de uma plataforma apresentada como Atores: sessão de negociação, cada estoque atribuído para sessão, cada ordem, etc. A Akka como espinha dorsal para a plataforma permite aproveitar esta abordagem e construir plataforma com tolerância a falhas e alta escalabilidade em sua natureza .
Para compilar projetos de Ergodicity, é necessário instalar a biblioteca CGate. Windows e Linux estão disponíveis no servidor RTS. Após a instalação, você deve adicionar o diretório $ CGATE_HOME / p2bin na variável $ Path para fornecer acesso à ferramenta de geração de código.
Consulte o projeto / SchemeTools. scala para obter detalhes.
&cópia de; 2017 GitHub, Inc. Termos Privacidade Segurança Status Ajuda.
Você não pode executar essa ação neste momento.
Você fez login com outra guia ou janela. Recarregue para atualizar sua sessão. Você se separou em outra guia ou janela. Recarregue para atualizar sua sessão.

sistema comercial Akka
Puxe pedidos 0.
Participe do GitHub hoje.
O GitHub é o lar de mais de 20 milhões de desenvolvedores que trabalham juntos para hospedar e rever o código, gerenciar projetos e criar software juntos.
Clone com HTTPS.
Use o Git ou o check-out com o SVN usando o URL da web.
Scala Backtesting + Live Trading Framework, construído no topo da Akka / Spray.
Esta estrutura pode ser útil para pessoas que vêm do Scala background, que estão fazendo seus primeiros passos nas estratégias de negociação automáticas de back / live testando a API REST da Oanda, que é, na minha opinião, uma das melhores API de varejo disponíveis. Uma vez que este é um trabalho em progresso, se você é um entusiasta da Scala e está interessado em negociação automatizada, tenha uma olhada e sinta-se livre para receber recompensa e contribuir!
Basta clonar o repo e deixar sua lógica comercial em StrategyFSM. scala. Não se esqueça de modificar AuthInfo. scala para incluir sua própria ID da conta e token de acesso para a API REST da Oanda.
Nota: Se você está simplesmente procurando uma maneira de se conectar à Oanda REST API usando Scala / Akka, confira meu projeto Scalanda.
&cópia de; 2017 GitHub, Inc. Termos Privacidade Segurança Status Ajuda.
Você não pode executar essa ação neste momento.
Você fez login com outra guia ou janela. Recarregue para atualizar sua sessão. Você se separou em outra guia ou janela. Recarregue para atualizar sua sessão.

No comments:

Post a Comment