Sistemas de negociação: design do sistema - Parte 1 13 A seção anterior deste tutorial analisou os elementos que compõem um sistema de negociação e discutiu as vantagens e desvantagens de usar esse sistema em um ambiente comercial real. Nesta seção, construímos esse conhecimento examinando quais mercados são especialmente adequados para o comércio de sistemas. Em seguida, analisaremos mais detalhadamente os diferentes gêneros dos sistemas de negociação. Negociação em Mercados de Mercados de Mercados Diferentes O mercado de ações é provavelmente o mercado mais comum para o comércio, especialmente entre os novatos. Nesta arena, grandes jogadores como Warren Buffett e Merrill Lynch dominam, e as estratégias tradicionais de investimento em crescimento e valor são, de longe, as mais comuns. No entanto, muitas instituições investiram significativamente na concepção, desenvolvimento e implementação de sistemas de negociação. Investidores individuais estão se juntando a essa tendência, embora lentamente. Aqui estão alguns fatores importantes a ter em mente ao usar sistemas de negociação em mercados de ações: 13 A grande quantidade de ações disponíveis permite que os comerciantes testem sistemas em vários tipos diferentes de ações - tudo, desde ações de venda livre (OTC) extremamente voláteis Chips azuis não voláteis. A eficácia dos sistemas de negociação pode ser limitada pela baixa liquidez de algumas ações, especialmente os problemas de OTC e rosa. As comissões podem comer em lucros gerados por negócios bem-sucedidos e podem aumentar as perdas. As ações da folha OTC e rosa geralmente incorrem em taxas de comissão adicionais. Os principais sistemas de negociação utilizados são aqueles que procuram valor - ou seja, sistemas que usam parâmetros diferentes para determinar se uma segurança é subvalorizada em comparação com o desempenho passado, seus pares ou o mercado em geral. Mercado de câmbio O mercado cambial, ou forex. É o maior e mais líquido mercado do mundo. Os governos mundiais, bancos e outras grandes instituições trocam trilhões de dólares no mercado cambial todos os dias. A maioria dos comerciantes institucionais no forex conta com sistemas de negociação. O mesmo vale para os indivíduos no forex, mas alguns comerciais com base em relatórios econômicos ou pagamentos de juros. Aqui estão alguns fatores importantes a ter em mente ao usar sistemas de negociação no mercado cambial: a liquidez neste mercado - devido ao enorme volume - Torna os sistemas de negociação mais precisos e eficazes. Não há comissões neste mercado, apenas se espalha. Portanto, é muito mais fácil fazer muitas transações sem aumentar os custos. Comparado com o valor das ações ou commodities disponíveis, o número de moedas para o comércio é limitado. Mas, devido à disponibilidade de pares de moeda exóticos - ou seja, moedas de países mais pequenos - o alcance em termos de volatilidade não é necessariamente limitado. Os principais sistemas de negociação utilizados no forex são aqueles que seguem as tendências (um ditado popular no mercado é a tendência é seu amigo), ou sistemas que compram ou vendem em breakouts. Isso ocorre porque os indicadores econômicos muitas vezes causam grandes movimentos de preços ao mesmo tempo. Futures Equity, forex e mercados de commodities oferecem negociação de futuros. Este é um veículo popular para o comércio de sistemas devido ao maior valor de alavancagem disponível e ao aumento da liquidez e da volatilidade. No entanto, esses fatores podem cortar as duas formas: podem amplificar seus ganhos ou amplificar suas perdas. Por esta razão, o uso de futuros é geralmente reservado para comerciantes avançados de sistemas individuais e institucionais. Isso ocorre porque os sistemas de negociação capazes de capitalizar o mercado de futuros exigem uma personalização muito maior, usam indicadores mais avançados e levam muito mais tempo para desenvolver. Então, o que é melhor é o investidor individual para decidir qual mercado é mais adequado ao comércio de sistemas - cada um tem suas próprias vantagens e desvantagens. A maioria das pessoas está mais familiarizada com os mercados de ações e essa familiaridade facilita o desenvolvimento de um sistema de negociação. No entanto, forex é comummente pensado para ser a plataforma superior para operar sistemas de negociação - especialmente entre os comerciantes mais experientes. Além disso, se um comerciante decide capitalizar o aumento de alavancagem e volatilidade, a alternativa futura está sempre aberta. Em última análise, a escolha está nas mãos do desenvolvedor do sistema. Tipos de Sistemas de Negociação Trend-Following Systems O método mais comum de negociação de sistema é o sistema de tendência contínua. Na sua forma mais fundamental, este sistema simplesmente espera um movimento de preço significativo, então compra ou vende nessa direção. Este tipo de bancos de sistemas na esperança de que esses movimentos de preços manterão a tendência. Sistemas médios móveis Freqüentemente utilizados na análise técnica. Uma média móvel é um indicador que mostra simplesmente o preço médio de uma ação ao longo de um período de tempo. A essência das tendências é derivada dessa medida. A maneira mais comum de determinar a entrada e a saída é um cruzamento. A lógica por trás disso é simples: uma nova tendência é estabelecida quando o preço cai acima ou abaixo da média do preço histórico (tendência). Aqui está um gráfico que traça tanto o preço (linha azul) quanto o Mestre de 20 dias (linha vermelha) da IBM: Breakout Systems O conceito fundamental por trás desse tipo de sistema é semelhante ao de um sistema de média móvel. A idéia é que quando um novo alto ou baixo é estabelecido, o movimento do preço provavelmente continuará na direção do breakout. Um indicador que pode ser usado na determinação de fugas é uma simples sobreposição da Bollinger Band. As Bandas de Bollinger mostram médias de preços altos e baixos, e os breakouts ocorrem quando o preço atende as bordas das bandas. Aqui está um gráfico que traça o preço (linha azul) e Bollinger Bands (linhas cinza) da Microsoft: Desvantagens dos sistemas de tendências: Requisição de decisão empírica necessária - Ao determinar as tendências, há sempre um elemento empírico a considerar: a duração de A tendência histórica. Por exemplo, a média móvel pode ser nos últimos 20 dias ou nos últimos cinco anos, então o desenvolvedor deve determinar qual é o melhor para o sistema. Outros fatores a serem determinados são os altos e baixos médios em sistemas de breakout. Lagging Nature - As médias móveis e os sistemas de breakout estarão sempre atrasados. Em outras palavras, eles nunca podem atingir o topo ou a parte inferior de uma tendência. Isso inevitavelmente resulta em uma perda de lucros potenciais, o que às vezes pode ser significativo. Efeito Whipsaw - Entre as forças do mercado que prejudicam o sucesso dos sistemas de tendência, este é um dos mais comuns. O efeito whipsaw ocorre quando a média móvel gera um sinal falso - isto é, quando a média cai apenas para o alcance, de repente, inverte a direção. Isso pode levar a perdas maciças, a menos que sejam utilizadas efetivas perdas de parada e técnicas de gerenciamento de risco. Sideways Markets - Trend-following sistemas são, por natureza, capaz de ganhar dinheiro apenas em mercados que realmente fazem tendências. No entanto, os mercados também se movem para os lados. Permanecendo dentro de um certo intervalo por um longo período de tempo. Pode ocorrer volatilidade extrema - Ocasionalmente, os sistemas que seguem a tendência podem experimentar alguma volatilidade extrema, mas o comerciante deve manter seu sistema. A incapacidade de fazê-lo resultará em falhas garantidas. Countertrend Systems Basicamente, o objetivo com o sistema contra-tendência é comprar no menor baixo e vender ao mais alto. A principal diferença entre este e o sistema de tendência seguinte é que o sistema contra-tendência não é auto-corretivo. Em outras palavras, não há tempo definido para sair de posições, e isso resulta em um potencial de queda ilimitado. Tipos de sistemas contratrarrescentes Muitos tipos diferentes de sistemas são considerados sistemas contra-tendência. A idéia aqui é comprar quando o impulso em uma direção começa a desaparecer. Isso geralmente é calculado usando osciladores. Por exemplo, um sinal pode ser gerado quando os estocásticos ou outros indicadores de força relativa caem abaixo de certos pontos. Existem outros tipos de sistemas de negociação contra tendência, mas todos compartilham o mesmo objetivo fundamental: comprar baixo e vender alto. Desvantagens dos Sistemas de Contra-Tendência: Requisição de Decisão Míbrica - Por exemplo, um dos fatores que o desenvolvedor do sistema deve decidir é os pontos nos quais os indicadores de força relativa se desvanecem. Pode ocorrer volatilidade extrema - esses sistemas também podem experimentar alguma volatilidade extrema e uma incapacidade de manter o sistema apesar dessa volatilidade resultará em falhas garantidas. Desvantagem ilimitada - Como mencionado anteriormente, existe um potencial de downside ilimitado porque o sistema não é auto-corretivo (não há tempo definido para sair de posições). Conclusão Os principais mercados para os quais os sistemas de negociação são adequados são os mercados de ações, divisas e futuros. Cada um desses mercados tem suas vantagens e desvantagens. Os dois principais gêneros dos sistemas de negociação são os sistemas de tendência e de contra-tendência. Apesar de suas diferenças, ambos os tipos de sistemas, em seus estágios de desenvolvimento, requerem uma tomada de decisão empírica por parte do desenvolvedor. Além disso, esses sistemas estão sujeitos a extrema volatilidade e isso pode exigir algum vigor - é essencial que o comerciante do sistema fique com seu sistema durante esses tempos. Na próxima parcela, observe melhor como projetar um sistema comercial e discutir alguns dos softwares que os comerciantes do sistema usam para facilitar sua vida. Sistemas de negociação: design do seu sistema - Parte 2 Padrões de integração 187 Padrões de integração na prática 187 Estudo de caso: sistema de comércio de títulos (por Jonathan Simon) É fácil distanciar-se de uma grande coleção de padrões ou de uma linguagem padrão. Os padrões são a abstração de uma idéia em uma forma reutilizável. Muitas vezes, a natureza muito genérica dos padrões que os torna tão úteis também os torna difíceis de entender. Às vezes, a melhor coisa para ajudar a entender os padrões é um exemplo do mundo real. Não é um cenário inventado do que poderia acontecer, mas o que realmente acontece eo que acontecerá. Este capítulo aplica padrões para resolver problemas usando um processo de descoberta. O sistema que discutiremos é um sistema de negociação de títulos com o qual trabalhei durante dois anos desde o projeto inicial até a produção. Exploraremos cenários e problemas que foram encontrados e como resolvê-los com padrões. Isso envolve o processo de decisão de escolher um padrão, bem como como combinar e ajustar padrões de acordo com as necessidades do sistema. E tudo isso é feito levando em consideração as forças encontradas em sistemas reais, incluindo requisitos de negócios, decisões de clientes, requisitos arquitetônicos e técnicos, bem como integração de sistemas legados. A intenção desta abordagem é proporcionar uma compreensão mais clara dos próprios padrões através da aplicação prática. Construindo um sistema Um grande banco de investimento de Wall Street pretende construir um sistema de preços de títulos em um esforço para agilizar o fluxo de trabalho de sua mesa de negociação de títulos. Atualmente, os comerciantes de títulos têm que enviar preços para um grande número de títulos para vários locais de negociação diferentes, cada um com sua própria interface de usuário. O objetivo do sistema é minimizar as minúcias de avaliar todos os seus títulos combinados com funcionalidades analíticas avançadas específicas para o mercado de títulos em uma única interface de usuário encapsulada. Isso significa integração e comunicação com vários componentes em vários protocolos de comunicação. O fluxo de alto nível do sistema parece assim: primeiro, os dados do mercado entram no sistema. Os dados do mercado são dados relativos ao preço e outras propriedades do vínculo que representam o que as pessoas estão dispostas a comprar e vender o vínculo no mercado livre. Os dados de mercado são imediatamente enviados para o mecanismo de análise que altera os dados. O analítico refere-se a funções matemáticas para aplicações financeiras que alteram os preços e outros atributos de títulos. Estas são funções genéricas que usam variáveis de entrada para adaptar os resultados da função a uma ligação particular. O aplicativo cliente que será executado em cada desktop do trader irá configurar o mecanismo de análise por base de comerciante, controlando as especificidades da análise para cada vínculo, o comerciante está classificando os preços. Uma vez que a análise é aplicada aos dados do mercado, os dados modificados são enviados para vários locais de negociação em que os comerciantes de outras empresas podem comprar ou vender os títulos. Arquitetura com padrões Com esta visão geral do fluxo de trabalho do sistema, podemos abordar alguns dos problemas arquitetônicos que encontramos durante o processo de design. Vamos ver o que sabemos até agora. Os comerciantes precisam de um aplicativo muito receptivo nas estações de trabalho Windows NT e Solaris. Portanto, decidimos implementar o aplicativo cliente como um cliente de Java grosso devido à independência da plataforma e sua capacidade de responder rapidamente aos dados de entrada e de mercado dos usuários. Do lado do servidor, estamos herdando componentes C legados que nosso sistema utilizará. Os componentes de dados do mercado se comunicam com a infra-estrutura de mensagens TIBCO Information Bus (TIB). Estamos herdando os seguintes componentes: Market Data Price Feed Server. Publica dados de mercado recebidos para o TIB. Mecanismo de análise. Executa análises sobre dados de mercado recebidos e transmite os dados de mercado modificados para o TIB. Servidor de Contribuição. Realiza toda a comunicação com os locais de negociação. Os locais de negociação são componentes de terceiros não controlados pelo banco. Subsistema de dados de mercado legado Subsistema de contribuição legado Precisamos decidir como os subsistemas separados (Java thick client, data de mercado e contribuição) se comunicarão. Poderíamos ter o cliente grosso se comunicar diretamente com os servidores legados, mas isso exigiria muita lógica de negócios no cliente. Em vez disso, bem, crie um par de gateways Java para se comunicar com os servidores herdados. O gateway de preços para dados de mercado um Contribution Gateway para enviar preços para os locais de negociação. Isso alcançará um bom encapsulamento da lógica de negócios relacionada a essas áreas. Os componentes atuais do sistema são mostrados abaixo. As conexões marcadas como. Indicam que ainda não temos certeza de como alguns dos componentes se comunicarão. O sistema e seus componentes A primeira questão de comunicação é como integrar o cliente de Java grosso e os dois componentes do servidor Java para trocar dados. Vamos ver os quatro estilos de integração sugeridos neste livro: Transferência de arquivos. Banco de dados compartilhado. Invocação do procedimento remoto. E mensagens. Nós podemos descartar Database compartilhado imediatamente porque queríamos criar uma camada de abstração entre o cliente e o banco de dados e não queremos ter o código de acesso ao banco de dados no cliente. A transferência de arquivos pode ser descartada de forma similar, uma vez que é necessária uma latência mínima para garantir que os preços atuais sejam enviados para os locais de negociação. Isso nos deixa com uma escolha entre Invocação de Procedimento Remoto ou Mensagens. A plataforma Java fornece suporte incorporado para Invocação de Procedimentos Remotos e Mensagens. A integração com o estilo RPC pode ser alcançada usando o Remote Method Invocation (RMI), CORBA ou Enterprise Java Beans (EJB). O Java Messaging Service (JMS) é a API comum para integração com o estilo de mensagens. Portanto, ambos os estilos de integração são fáceis de implementar em Java. Então, o que funcionará melhor para este projeto, Invocação de Procedimento Remoto ou Mensagens. Há apenas uma instância do Pricing Gateway e uma instância do Contribution Gateway no sistema, mas, geralmente, muitos Clientes Thicks se conectam simultaneamente a esses serviços (um para cada comerciante de títulos que esteja logado em um horário específico). Além disso, o banco gostaria que este fosse um sistema genérico de preços que possa ser utilizado em outras aplicações. Portanto, além de um número desconhecido de Think Clients, pode haver um número desconhecido de outras aplicações usando os dados de preços que saem dos Gateways. Um Thick Client (ou outro aplicativo usando os dados de preços) pode facilmente usar o RPC para fazer chamadas para os Gateways para obter dados de preços e invocar o processamento. No entanto, os dados de preços serão constantemente publicados, e certos clientes só estão interessados em determinados dados, portanto, obter os dados relevantes para os clientes adequados em tempo hábil pode ser difícil. Os clientes poderiam pesquisar os Gateways, mas isso criará muitas despesas gerais. Seria melhor para os Gateways disponibilizar os dados aos clientes assim que estejam disponíveis. Isso, no entanto, exigirá que cada Gateway faça o controle de quais clientes estão atualmente ativos e que desejam quais dados particulares, então, quando um novo dado se torna disponível (o que ocorrerá várias vezes por segundo), o Gateway terá que fazer Um RPC para cada cliente interessado para passar os dados para o cliente. Idealmente, todos os clientes devem ser notificados simultaneamente, então cada RPC precisa ser feito em seu próprio tópico concorrente. Isso pode funcionar, mas está ficando muito complicado muito rápido. O Messaging simplifica muito esse problema. Com o Messaging. Podemos definir canais separados para os diferentes tipos de dados de preços. Então, quando um Gateway obtém um novo pedaço de dados, ele irá adicionar uma mensagem contendo esses dados ao Canal de Publicação-Inscrição para esse tipo de dados. Enquanto isso, todos os clientes interessados em um certo tipo de dados irão ouvir no canal para esse tipo. Desta forma, os Gateways podem facilmente enviar novos dados para quem está interessado, sem precisar saber quantos aplicativos de ouvintes existem ou o que são. Os clientes ainda precisam ser capazes de invocar comportamentos nos Gateways também. Uma vez que existem apenas dois gateways, e o cliente provavelmente pode bloquear enquanto o método é invocado de forma síncrona, essas invocações de cliente para gateway podem ser facilmente implementadas usando o RPC. No entanto, uma vez que já estamos usando mensagens para comunicações de gateway para cliente, as mensagens provavelmente são uma maneira tão boa de implementar a comunicação do cliente para o gateway também. Portanto, todas as comunicações entre os Gateways e os clientes serão realizadas através de mensagens. Como todos os componentes estão escritos em Java, o JMS apresenta uma escolha fácil para o sistema de mensagens. Isso efetivamente está criando um barramento de mensagens ou uma arquitetura que tornará possível que futuros sistemas se integrem com o sistema atual com poucas ou nenhuma alteração na infra-estrutura de mensagens. Desta forma, a funcionalidade de negócios da aplicação pode ser facilmente usada por outra aplicação que o banco desenvolve. Componentes Java A comunicação com o JMS JMS é simplesmente uma especificação e precisamos decidir sobre um sistema de mensagens compatível com JMS. Nós decidimos usar o IBM MQSeries JMS porque o banco é uma loja da IBM, usando servidores de aplicativos WebSphere e muitos outros produtos da IBM. Como resultado, usaremos o MQSeries uma vez que já possuímos uma infraestrutura de suporte e uma licença de site do produto. A próxima pergunta é como conectar o sistema de mensagens MQSeries com o servidor de C Contribuição autônomo e os servidores do Mercado Data e Analytics Engine baseados em TIBCO. Precisamos de um modo para os consumidores do MQSeries terem acesso às mensagens TIB. Mas como talvez possamos usar o padrão do Message Translator para traduzir mensagens TIB para mensagens MQSeries. Embora o cliente C do MQSeries sirva como um Message Translator. Usando isso, sacrificaria a independência do servidor JMS. E embora a TIBCO tenha uma API Java, o arquiteto e o gerente do cliente a rejeitaram. Como resultado, a abordagem do Message Translator deve ser abandonada. A ponte do servidor TIB para o servidor MQSeries requer comunicação entre C e Java. Podemos usar o CORBA, mas então, o que diz respeito à mensagem. Um olhar mais atento sobre o padrão do Message Translator mostra que ele está relacionado ao Adaptador de Canal em seu uso de protocolos de comunicação. O coração de um Adaptador de Canal é conectar sistemas não-mensagens a sistemas de mensagens. Um par de adaptadores de canal que conecta dois sistemas de mensagens é uma ponte de mensagens. A finalidade de um Messaging Bridge é transferir mensagens de um sistema de mensagens para outro. Isso é exatamente o que estamos fazendo com a complexidade adicional da comunicação intra-linguagem Java para C. Podemos implementar a ponte de mensagens em linguagem cruzada usando uma combinação de Channel Adapter s e CORBA. Construiremos dois servidores ligeiros de Adaptadores de Canal, um em C gerenciando comunicação com o TIB e um em Java gerenciando comunicação com o JMS. Estes dois canais de adaptador. Que são os próprios pontos de mensagem, se comunicarão entre si através do CORBA. Como a nossa escolha para o MQSeries, usaremos CORBA em vez de JNI, pois é um padrão de empresa. A ponte de mensagens implementa a tradução efetivamente simulada de mensagens entre sistemas de mensagens aparentemente incompatíveis e diferentes idiomas. Conversor de mensagens usando adaptadores de canais O próximo diagrama mostra o design do sistema atual, incluindo os Gateways e outros componentes. Este é um bom exemplo de aplicação de padrões. Combinamos dois Adaptadores de Canal s com um protocolo sem mensagens para implementar o padrão do Message Translator, usando efetivamente um padrão para implementar outro padrão. Além disso, mudamos o contexto do Adaptador de Canal para vincular dois sistemas de mensagens com um protocolo de conversão de língua cruzada que não seja de mensagens em vez de conectar um sistema de mensagens a um sistema que não seja de mensagens. O sistema atual com os Canais de Estruturação dos Adaptadores de Canal Uma chave para trabalhar com padrões não é apenas saber quando usar qual padrão, mas também como usá-lo com maior eficiência. Cada implementação de padrão deve ter em conta especificidades da plataforma tecnológica, bem como outros critérios de design. Esta seção aplica o mesmo processo de descoberta para encontrar o uso mais eficiente do canal Publish-Subscribe no contexto do servidor de dados de mercado que se comunica com o mecanismo de análise. Os dados de mercado em tempo real originam-se com o feed de dados do mercado, um servidor C que transmite dados de mercado no TIB. O feed de dados do mercado usa um canal de publicação-inscrição separado para cada vínculo para o qual ele está publicando preços. Isso pode parecer um pouco extremo, uma vez que cada novo vínculo precisa do seu próprio novo canal. Mas isso não é tão grave, pois você realmente não precisa criar canais no TIBCO. Em vez disso, os canais são referenciados por um conjunto hierárquico de nomes de tópicos chamados de assuntos. O servidor TIBCO filtra um único fluxo de mensagens por assunto, enviando cada assunto exclusivo para um único canal virtual. O resultado é um canal de mensagem muito leve. Poderíamos criar um sistema que publica em alguns canais e os assinantes poderiam ouvir apenas os preços que lhes interessam. Isso exigiria que os assinantes usassem um Filtro de Mensagens ou um Consumidor Seletivo para filtrar todo o fluxo de dados para preços de títulos interessantes, decidindo se cada mensagem Deve ser processado conforme recebido. Dado que os dados de mercado são publicados em canais dedicados, os assinantes podem se inscrever para atualizações sobre uma série de títulos. Isso efetivamente permite que os assinantes filtrarem secionando seletivamente aos canais e apenas recebendo atualizações de interesse ao invés de decidir depois que a mensagem for recebida. É importante notar que o uso de múltiplos canais para evitar a filtragem é um uso não padrão de canais de mensagens. No contexto da tecnologia TIBCO, no entanto, estamos realmente decidindo se implementamos ou possuímos filtros ou utilizamos a filtragem de canais incorporada no TIBCO - e não seja a utilização de tantos canais. O próximo componente que precisamos projetar é o mecanismo analítico, outro servidor C TIB que modificará os dados do mercado e o retransmitirá para o TIB. Embora esteja fora do alcance do nosso desenvolvimento JMS Java, estamos trabalhando em estreita colaboração com a equipe C para projetá-lo, já que somos o principal cliente dos motores de análise. O problema em questão é encontrar a estrutura de canais que retransmitide os dados de mercado recentemente modificados. Uma vez que já possuímos um canal de mensagens dedicado por vínculo herdado do preço de preço do mercado, seria lógico modificar os dados do mercado e retransmitir os dados de mercado modificados no canal de mensagens dedicado. Mas isso não funcionará uma vez que os analíticos que modificam os preços dos títulos são específicos do comerciante. Se nós retransmitimos os dados modificados no canal de mensagens de vínculo. Destruiremos a integridade dos dados, substituindo os dados genéricos do mercado por dados específicos do comerciante. Por outro lado, podemos ter um tipo de mensagem diferente para os dados de mercado específicos do comerciante que publicamos no mesmo canal, permitindo que os assinantes decidam qual mensagem eles estão interessados para evitar destruir a integridade dos dados. Mas os clientes terão que implementar seus próprios filtros para separar mensagens para outros comerciantes. Além disso, haverá um aumento substancial nas mensagens recebidas pelos assinantes, colocando um fardo desnecessário sobre eles. Existem duas opções: One Channel per Trader: cada comerciante possui um canal designado para os dados de mercado modificados. Desta forma, os dados de mercado originais permanecem intactos e cada aplicação de comerciante pode ouvir seus comerciantes específicos Message Channel para as atualizações de preços modificadas. Um Canal por comerciante por Obrigatório: Crie um Canal de Mensagens por comerciante por ação unicamente para os dados de mercado modificados dessa ligação. Por exemplo, os dados de mercado para a ligação ABC seriam publicados no canal Bond ABC enquanto os dados de mercado modificados para o comerciante A seriam publicados no Message Channel Trader A, Bond ABC, dados de mercado modificados para o comerciante B no Trader B, Bond ABC e em breve. Um canal por comerciante Um canal por ligação por comerciante Existem vantagens e desvantagens para cada abordagem. A abordagem por vínculo, por exemplo, usa muito mais Message Channel. No pior caso, o número de Canal de Mensagens será o número de títulos total multiplicado pelo número de comerciantes. Podemos colocar limites superiores no número de canais que serão criados, já que sabemos que existem apenas cerca de 20 comerciantes e nunca mais do que um par de cem títulos. Isso coloca o limite superior abaixo da faixa de 10.000, o que não é tão estranho em comparação com o canal de mensagens de quase 100.000 que o preço do preço de mercado está usando. Além disso, uma vez que estamos usando o TIB eo canal de mensagens são bastante baratos, o número de canais de mensagens não é um problema grave. Por outro lado, o grande número de canais de mensagens pode ser um problema de uma perspectiva de gerenciamento. Toda vez que um vínculo é adicionado, um canal para cada comerciante deve ser mantido. Isso pode ser grave em um sistema muito dinâmico. Nosso sistema, no entanto, é essencialmente estático. Ele também possui uma infraestrutura para gerenciar automaticamente o Channel de mensagens s. Isso combinado com a arquitetura herdada de um componente legado usando uma abordagem similar minimiza a desvantagem. Isso não quer dizer que devemos fazer um número desnecessariamente excessivo de canais de mensagens s. Em vez disso, podemos implementar uma abordagem arquitetônica que usa um grande número de canais de mensagens quando há um motivo. E há um motivo neste caso que se resume à localização da lógica. Se implementarmos a abordagem por trader, o Analytics Engine necessita de lógica para agrupar canais de entrada e saída. Isso ocorre porque os canais de entrada do Google Analytics Engine são por ligação e o Canal de Mensagens de saída seria por comerciante, exigindo que o Engine Analytics encaminhe toda a entrada de análise de múltiplas ligações para um comerciante específico para um canal de mensagens de saída específico do comerciante. Isso efetivamente transforma o mecanismo de análise em um roteador baseado em conteúdo para implementar lógica de roteamento personalizada para nossa aplicação. Seguindo a estrutura do Bus de mensagens, o Analytics Engine é um servidor genérico que pode ser usado por vários outros sistemas no. Então, não queremos cloud-lo com funcionalidades específicas do sistema. Por outro lado, a abordagem por vínculo funciona uma vez que a idéia de um comerciante que possui a saída analítica dos preços dos títulos é uma prática aceita pela empresa. A abordagem por vínculo mantém intacta a separação do canal de mensagens do feed de dados do mercado, ao mesmo tempo em que adiciona vários canais de mensagens mais. Antes de chegar ao cliente, queremos que um roteador baseado em conteúdo combine esses vários canais em um número gerenciável de canais. Nós não queremos que o aplicativo cliente executado na área de trabalho dos comerciantes esteja ouvindo milhares ou dezenas de milhares de canais de mensagens s. Agora, a questão se torna onde colocar o Roteador baseado em conteúdo. Poderíamos simplesmente ter o Adaptador de canal C TIB encaminhar todas as mensagens para o gateway de preços em um único canal de mensagens. Isso é ruim por duas razões pelas quais estaria dividindo a lógica de negócios entre C e Java, e perderíamos o benefício do Canal de Mensagens separado no lado TIB, permitindo-nos evitar a filtragem mais tarde no fluxo de dados. Olhando para os nossos componentes Java, podemos colocá-lo no Pricing Gateway ou criar um componente intermediário entre o Pricing Gateway e o cliente. Em teoria, se continuássemos com a separação baseada em vínculo do Message Channel s até o cliente, o gateway de preços retransmitiria informações de preços com a mesma estrutura de canais que o Gateway de preços e o Google Analytics Engine. Isso significa uma duplicação de todos os canais dedicados TIB dedicados no JMS. Mesmo que criemos um componente intermediário entre o gateway de preços e o cliente, o Gateway de preços ainda precisará duplicar todos os canais no JMS. Por outro lado, implementar a lógica diretamente no Pricing Gateway nos permite evitar a duplicação do grande número de canais no JMS, o que nos permite criar um número muito menor de canais na ordem de um por comerciante. O gateway de preços se registra através do adaptador de canal C TIB como consumidor para cada vínculo de todos os comerciantes do sistema. Em seguida, o Gateway de preços encaminhará cada cliente específico apenas as mensagens relacionadas a esse comerciante específico. Desta forma, usamos apenas um pequeno número de canais de mensagens no final do JMS, ao mesmo tempo em que maximizamos o benefício da separação no terminal TIB. O fluxo de dados do mercado completo para o cliente A discussão do layout do canal de mensagens é um bom exemplo de como os padrões de integração são importantes. O objetivo aqui foi descobrir como usar efetivamente o canal de mensagens s. Dizendo que você usa um padrão não é suficiente. Você precisa descobrir como implementá-lo e incorporar no seu sistema para resolver os problemas em questão. Além disso, este exemplo mostra as forças de negócios em ação. Se pudéssemos implementar lógica de negócios em qualquer um dos nossos componentes, poderíamos ter ido com a abordagem por comerciante e implementado uma abordagem global mais simples com muitos canais menos. Selecionando um canal de mensagens Agora que conhecemos a mecânica da comunicação entre os componentes do Java JMS e os componentes do C TIBCO, e vimos alguma estruturação do canal de mensagens, precisamos decidir qual tipo de canal de mensagens JMS os componentes Java devem usar para comunicar. Antes de poder escolher entre os diferentes Canais de Mensagens disponíveis no JMS, podemos ver o fluxo de mensagens de alto nível do sistema. Temos dois gateways (Preços e Contribuição) que se comunicam com o cliente. Os fluxos de dados do mercado para o cliente a partir do gateway de preços que o envia para o Contribution Gateway. O aplicativo cliente envia mensagem para o Gateway de preços para alterar a análise a cada ligação. The Contribution Gateway also sends messages to the Client application relaying the status of the price updates to the different trading venues. The system message flow The JMS specification describes two Message Channel types, Point-to-Point Channel (JMS Queue ) and Publish-Subscribe Channel (JMS Topic ). Recall that the case for using publish-subscribe is to enable all interested consumers to receive a message while the case for using point-to-point is to ensure that only one eligible consumer receives a particular message. Many systems would simply broadcast messages to all client applications, leaving each individual client application to decide for itself whether or not to process a particular message. This will not work for our application since there are a large number of market data messages being sent to each client application. If we broadcast market data updates to uninterested trader, we will be unnecessarily wasting client processor cycles deciding whether or not to process a market data update. Point-to-Point Channel s initially sound like a good choice since the clients are sending messages to unique servers and visa versa. But it was a business requirement that traders may be logged in to multiple machines at the same time. If we have a trader logged in at two workstations simultaneously and a point-to-point price update is sent, only one of the two client applications will get the message. This is because only one consumer on a Point-to-Point Channel can receive a particular message. Notice that only the first of each group of a traders client applications receives the message. Point-to-Point Messaging for Price Updates We could solve this using the Recipient List pattern, which publishes messages to a list of intended recipients, guaranteeing that only clients in the recipient list will receive messages. Using this pattern, the system could create recipient lists with all client application instances related to each trader. Sending a message related to a particular trader would in turn send the message to each application in the recipient list. This guarantees all client application instances related to a particular trader would receive the message. The downside of this approach is that it requires quite a bit of implementation logic to manage the recipients and dispatch messages. Recipient List for Price Updates Even though point-to-point could be made to work, lets see if there is a better way. Using Publish-Subscribe Channel s, the system could broadcast messages on trader specific channels rather than client application specific channels. This way, all client applications processing messages for a single trader would receive and process the message. Publish-Subscribe Messaging for Price Updates The downside of using Publish-Subscribe Channel s is that unique message processing is not guaranteed with the server components. It would be possible for multiple instances of a server component to be instantiated and each instance process the same message, possibly sending out invalid prices. Recalling the system message flow, only a single communication direction is satisfactory with each Message Channel . Server-to-client communication with publish-subscribe is satisfactory while client-to-server communication is not and client-server communication with point-to-point is satisfactory while server-client is not. Since there is no need to use the same Message Channel in both directions, we can use each Message Channel only one direction. Client-to-server communication will be implemented with point-to-point while server-to-client communication will be implemented with publish-subscribe. Using this combination of Message Channel s, the system benefits from direct communication with the server components using point-to-point messaging and the multicast nature of publish-subscribe without either of the drawbacks. Message flow with Channel Types Problem Solving With Patterns Patterns are tools and collections of patterns are toolboxes. They help solve problems. Some think that patterns are only useful during design. Following the toolbox analogy, this is like saying that tools are only useful when you build a house, not when you fix it. The fact is that patterns are a useful tool throughout a project when applied well. In the following sections we will use the same pattern exploration process we used in the previous section to solve problems in our now working system. Flashing Market Data Updates Traders want table cells to flash when new market data is received for a bond, clearly indicating changes. The Java client receives messages with new data which triggers a client data cache update and eventually flashing in the table. The problem is that updates come quite frequently. The GUI thread stack is becoming overloaded and eventually freezing the client since it cant respond to user interaction. We will assume that the flashing is optimized and concentrate on the data flow of messages through the updating process. An examination of performance data shows the client application is receiving several updates a second some updates occurred less than a millisecond apart. Two patterns that seem like they could help slow down the message flow are Aggregator and Message Filter. A first thought is to implement a Message Filter to control the speed of the message flow by throwing out updates received a small amount of time after the reference message. As an example, lets say that we are going to ignore messages within 5 milliseconds of each other. The Message Filter could cache the time of the last acceptable message and throw out anything received within the next 5 milliseconds. While other applications may not be able to withstand data loss to such an extent, this is perfectly acceptable in our system due to the frequency of price updates. Time based Message Filter The problem with this approach is that not all data fields are updated at the same time. Each bond has approximately 50 data fields displayed to the user including price. We realize that not every field is updated in every message. If the system ignores consecutive messages, it may very well be throwing out important data. The other pattern of interest is the Aggregator . The Aggregator is used to manage the reconciliation of multiple, related messages into a single message, potentially reducing the message flow. The Aggregator could keep a copy of the bond data from the first aggregated message, then update only new or changed fields successive messages. Eventually the aggregated bond data will be passed in a message to the client. For now, lets assume that the Aggregator will send a message every 5 milliseconds like the Message Filter . Later, well explore another alternative. Aggregator with partial successive updates The Aggregator . like any other pattern, is not a silver bullet it has its pluses and minuses that need to be explored. One potential minus is that implementing an Aggregator would reduce the message traffic by a great amount in our case only if many messages are coming in within a relatively short time regarding the same bond. On the other hand, we would accomplish nothing if the Java client only receives updates for one field across all of the traders bonds. For example, if we receive 1000 messages in a specified timeframe with 4 bonds of interest, we would reduce the message flow from 1000 to 4 messages over that timeframe. Alternatively, if we receive 1000 messages in the same timeframe with 750 bonds of interest, we will have reduced the message flow from 1000 to 750 messages relatively little gain for the amount of effort. A quick analysis of the message updates proves that the Java client receives many messages updating fields of the same bond, and therefore related messages. So, Aggregator is in fact a good decision. Whats left is to determine how the Aggregator will know when to send a message it has been aggregating. The pattern describes a few algorithms for the Aggregator to know when to send the message. These include algorithms to cause the aggregator to send out its contents after a certain amount of time has elapsed, after all required fields in a data set have been completed, and others. The problem with all of these approaches is that the aggregator is controlling the message flow, not the client. And the client is the major bottleneck in this case, not the message flow. This is because the Aggregator is assuming the consumers of its purged messages (the client application in this case) are Event-Driven Consumer s, or consumers that rely on events from an external source. We need to turn the client into a Polling Consumer . or a consumer that continuously checks for messages, so the client application can control the message flow. We can do this by creating a background thread that continuously cycles through the set of bonds and updates and flashes any changes that have occurred since the last iteration. This way, the client controls when messages are received and as a result, guarantees that it will never become overloaded with messages during high update periods. We can easily implement this by sending a Command Message to the Aggregator initiating an update. The Aggregator will respond with a Document Message containing the set of updated fields that the client will process. The choice of Aggregator over Message Filter is clearly a decision based solely on the business requirements of our system. Each could help us solve our performance problems, but using the Message Filter would solve the problem at cost of the system data integrity. Major Production Crash With the performance of the flashing fixed, we are now in production. One day the entire system goes down. MQSeries crashes, bringing several components down with it. We struggle with the problem for a while and finally trace it back to the MQSeries dead letter queue (an implementation of the Dead Letter Channel ). The queue grows so large that it brings down the entire server. After exploring the messages in the dead letter queue we find they are all expired market data messages. This is caused by slow consumers, or consumers that do not process messages fast enough. While messages are waiting to be processed, they time out (see the Message Expiration pattern) and are sent to the Dead Letter Channel . The excessive number of expired market data messages in the dead letter queue is a clear indication that the message flow is too great messages expire before the target application can consume them. We need to fix the message flow and we turn to patterns for help slowing down the message flow. A reasonable first step is to explore solving this problem with the Aggregator as we recently used this pattern to solve the similar flashing market data control rate problem. The system design relies on the client application to immediately forward market data update messages to the trading venues. This means the system cannot wait to collect messages and aggregate them. So the Aggregator must be abandoned. There are two other patterns that deal with the problem of consuming messages concurrently: Competing Consumers and Message Dispatcher . Starting with Competing Consumers . the benefit of this pattern is the parallel processing of incoming messages. This is accomplished using several consumers on the same channel. Only one consumer processes each incoming message leaving the others to process successive messages. Competing Consumers . however, will not work for us since we are using Publish-Subscribe Channel s in server-to-client communication. Competing Consumers on a Publish-Subscribe Channel channel means that all consumers process the same incoming message. This results in more work without any gain and completely misses the goal of the pattern. This approach also has to be abandoned. On the other hand, the Message Dispatcher describes an approach whereby you add several consumers to a pool. Each consumer can run its own execution thread. One main Message Consumer listens to the Channel and delegates the message on to an unoccupied Message Consumer in the pool and immediately returns to listening on the Message Channel . This achieves the parallel processing benefit of Competing Consumers . but works on Publish-Subscribe Channel s. The Message Dispatcher in context Implementing this in our system is simple. We create a single JMSListener called the Dispatcher, which contains a collection of other JMSListener s called Performers. When the onMessage method of the Dispatcher is called, it in turn picks a Performer out of the collection to actually process the message. The result of which is a Message Listener (the Dispatcher) that always returns immediately. This guarantees a steady flow of message processing regardless of the message flow rate. Additionally, this works equally well on a Publish-Subscribe Channel s as it does on a Point-to-Point Channel s. With this infrastructure, messages can be received by the client application at almost any rate. If the client application is still slow to process the message after receiving them, the client application can deal with the delayed processing and potentially outdated market data rather than the messages expiring in the JMS Message Channel . The crash discussed in this section and the fix using the Message Dispatcher is an excellent example of the limits of applying patterns. We encountered a performance problem based on a design flaw not allowing the client to process messages in parallel. This greatly improved the problem, but did not completely fix it. This is because the real problem was the client becoming a bottleneck. This couldnt be fixed with a thousand patterns. We later addressed this problem by refactoring the message flow architecture to route messages directly from the Pricing Gateway to the Contribution Gateway. So patterns can help design and maintain a system, but dont necessarily make up for poor upfront design. Throughout this chapter, we have applied patterns to several different aspects of a bond trading system including solving initial upfront design problems and fixing a nearly job threatening production crash with patterns. We also saw these patterns as they already exist in third party product, legacy components, and our JMS and TIBCO messaging systems. Most importantly, these are real problems with the same types of architectural, technical and business problems we experience as we design and maintain our own systems. Hopefully reading about applying patterns to this system helps give you a better understanding of the patterns as well as how to apply them to your own systems. Want to track what happened since the book came out Follow My Ramblings . Want to read more in depth Check out My Articles . Want to see me live See where I am speaking next . Find the full description of this pattern in: Enterprise Integration Patterns Gregor Hohpe and Bobby Woolf ISBN 0321200683 650 pages Addison-Wesley Parts of this page are made available under the Creative Commons Attribution license. You can reuse the pattern icon, the pattern name, the problem and solution statements (in bold), and the sketch under this license. Other portions of the text, such as text chapters or the full pattern text, are protected by copyright. Messaging Patterns 187 Integration Patterns in Practice 187 Case Study: Bond Trading System
Comments
Post a Comment