Jon V.
BigData. Iniciantes. Negociação
BigData. Iniciantes. Negociação
Construindo um sistema de backtesting em Python: ou como eu perdi $ 3400 em duas horas.
Construir um sistema de backtest é realmente muito fácil. Fácil de estragar eu quero dizer. Embora existam toneladas de excelentes bibliotecas por aí (e nós as percorremos em algum momento), eu sempre gosto de fazer isso sozinha para ajustá-las.
De todos os sistemas de backtesting que vi, podemos supor que existem duas categorias:
Hoje, falaremos sobre loopers.
Os "loopers" são meus tipos favoritos de backtesters. Eles são triviais para escrever e super divertidos de se expandir, mas eles têm alguns fluxos vitais e, infelizmente, a maioria dos backtesters lá fora é "for-loopers" (ps: eu preciso encontrar um nome melhor para isso!).
Como funcionam os loopers? Usando um loop for (como você deve ter imaginado). É algo assim:
Muito simples né? É assim que funciona um sistema de backtesting, que executa uma estratégia de momentum:
Então qual é o problema?
Muito difícil de escalar (horizontalmente) Precisa de muito trabalho para manter seu apply_strategy () trabalhando em backtesting e produção Você precisa ter tudo na mesma linguagem de programação.
Vamos mergulhar neles, um por um.
Escalabilidade Eu estava experimentando algumas semanas atrás com um algoritmo de escalada para otimizar uma das minhas estratégias. Ainda está em execução. Depois de duas semanas. E eu construo sistemas escaláveis para a vida. Por que ainda está funcionando? Você pode usar multiprocessamento, Disco, produtor / consumidor (usando ZeroMQ) ou apenas threads para acelerar isso, mas alguns problemas não são "constrangedores paralelos" (sim, este é um termo real, não uma das minhas palavras inventadas). A quantidade de trabalho para escalar um backtester como este (especialmente quando você quer fazer o mesmo aprendizado de máquina em cima dele) é enorme. Você pode fazer isso, mas é o caminho errado.
Produção e backtesting em sincronia. As vezes eu fui mordido por isso. Eu me lembro dos negócios perdidos onde eu estava "hm, porque eu entrei neste comércio?" ou o meu favorito dos velhos tempos "PORQUE PARAR DE TRAILING FOI APLICADO AGORA?"
Hora da história: Eu tive uma idéia para otimizar minha estratégia, para executar um backtester para ver o que aconteceria se eu pudesse colocar uma parada depois que o negócio fosse lucrativo, a fim de sempre garantir lucros. O backtesting funcionou como um encanto, com um aumento de 13% nos lucros e a produção perdeu todos os negócios. Eu percebi isso depois que meu algo perdeu $ 3400 em um par de horas (uma lição muito cara).
Manter o apply_strategy em sincronia é muito difícil e se torna quase impossível quando você quer fazê-lo de maneira distribuída. E você não quer ter duas versões da sua estratégia que são "quase" idênticas. A menos que você tenha $ 3400 de sobra.
Usando diferentes linguagens eu amo o Python. E Erlang. E Clojure. E J. E C. E R. E Ruby (não, na verdade, eu odeio Ruby). Eu quero ser capaz de aproveitar a força de outras linguagens no meu sistema. Eu quero experimentar estratégias em R onde existem bibliotecas muito bem testadas e há uma enorme comunidade por trás disso. Eu quero ter Erlang para escalar meu código e C para processar dados. Se você quer ser bem sucedido (não apenas na negociação), você precisa ser capaz de usar todos os recursos disponíveis sem preconceitos. Eu aprendi toneladas de coisas de sair com desenvolvedores de R sobre como você pode delta de títulos de hedge e visualizá-los ou por que razão de Sharpe pode ser uma mentira. Cada idioma tem uma multidão diferente e você quer tantas pessoas despejando ideias em seu sistema. Se você tentar ter apply_strategy em uma linguagem diferente, então boa sorte com (2).
Você está convencido agora? Bem, eu não estou tentando convencê-lo como para loopers é uma ótima maneira de executar seus testes iniciais. Foi assim que comecei e, para muitas estratégias, não as envio para o pipeline. Um "melhor" caminho (assim você pode dormir à noite) é o gerador de eventos.
Chegando em seguida, compartilhando e discutindo meu mais simples (mas mais bem sucedido) backtester!
Se você tiver mais feedback, envie-me um ping no jonromero ou inscreva-se no boletim informativo.
Outro Jurídico Este é um tutorial de engenharia sobre como construir uma plataforma de algotrading para experimentação e DIVERSÃO. Todas as sugestões aqui não são conselhos financeiros. Se você perder algum (ou todo) dinheiro porque seguiu qualquer aviso de negociação ou implantou este sistema em produção, você não pode culpar esse blog aleatório (e / ou eu). Aproveite por sua conta e risco.
Biblioteca de Negociação Algorítmica Python.
O PyAlgoTrade é uma Biblioteca de Negociação Algorítmica Python, com foco em backtesting e suporte para negociação de papéis e negociação ao vivo. Digamos que você tenha uma ideia para uma estratégia de negociação e gostaria de avaliá-la com dados históricos e ver como ela se comporta. O PyAlgoTrade permite que você faça isso com o mínimo de esforço.
Principais características.
Totalmente documentado. Evento dirigido. Suporta ordens Market, Limit, Stop e StopLimit. Suporta o Yahoo! Arquivos Finanças, Google Finance e NinjaTrader CSV. Suporta qualquer tipo de dados de séries temporais no formato CSV, por exemplo, o Quandl. Suporte de negociação Bitcoin através do Bitstamp. Indicadores técnicos e filtros como SMA, WMA, EMA, RSI, Bandas de Bollinger, expoente de Hurst e outros. Métricas de desempenho como a taxa de Sharpe e a análise de rebaixamento. Manipulando eventos do Twitter em tempo real. Criador de perfil de eventos. Integração TA-Lib.
Muito fácil de dimensionar horizontalmente, isto é, usando um ou mais computadores para fazer backtest de uma estratégia.
O PyAlgoTrade é gratuito, de código aberto e está licenciado sob a Licença Apache, Versão 2.0.
bt - Backtesting flexível para Python¶
O que é bt?
O bt é um framework de backtesting flexível para Python usado para testar estratégias de negociação quantitativa. Backtesting é o processo de testar uma estratégia em um dado conjunto de dados. Essa estrutura permite criar facilmente estratégias que combinam e combinam diferentes Algos. O objetivo é promover a criação de blocos de lógica de estratégia facilmente testáveis, reutilizáveis e flexíveis para facilitar o rápido desenvolvimento de estratégias de negociação complexas.
O objetivo: salvar os demais de reinventarem a roda e deixá-los concentrar-se na parte importante do desenvolvimento da estratégia de trabalho.
O bt é codificado em Python e se junta a um ecossistema vibrante e rico para análise de dados. Existem inúmeras bibliotecas para aprendizado de máquina, processamento de sinais e estatísticas, e podem ser aproveitadas para evitar reinventar a roda - algo que acontece com muita freqüência quando se usa outras linguagens que não têm a mesma riqueza de alta qualidade. projetos de origem.
bt é construído sobre o ffn - uma biblioteca de funções financeiras para Python. Confira!
Um exemplo rápido¶
Aqui está um gostinho rápido de bt:
Um backtest de estratégia simples¶
Vamos criar uma estratégia simples. Criaremos uma estratégia mensalmente reequilibrada, de longa duração, em que colocamos pesos iguais em cada ativo em nosso universo de ativos.
Primeiro, vamos baixar alguns dados. Por padrão, o bt. get (apelido para ffn. get) faz o download do Ajusted Close do Yahoo! Finança. Vamos baixar alguns dados a partir de 1º de janeiro de 2010 para os fins desta demonstração.
Assim que tivermos nossos dados, criaremos nossa estratégia. O objeto Strategy contém a lógica da estratégia combinando vários Algos.
Por fim, criaremos um Backtest, que é a combinação lógica de uma estratégia com um conjunto de dados.
Feito isso, podemos executar o backtest e analisar os resultados.
Agora podemos analisar os resultados do nosso backtest. O objeto Result é um wrapper fino em torno de ffn. GroupStats que adiciona alguns métodos auxiliares.
Modificando uma estratégia¶
E se executássemos essa estratégia semanalmente e também usássemos alguma abordagem de estilo de paridade de risco usando pesos que são proporcionais ao inverso da volatilidade de cada ativo? Bem, tudo o que temos a fazer é conectar alguns algos diferentes. Ver abaixo:
Como você pode ver, a lógica da estratégia é fácil de entender e, mais importante, fácil de modificar. A ideia de usar Algos simples e compostos para criar estratégias é um dos principais blocos de construção do bt.
Estrutura da Árvore A estrutura da árvore facilita a construção e a composição de estratégias complexas de negociação algorítmica que são modulares e reutilizáveis. Além disso, cada nó da árvore possui seu próprio índice de preços que pode ser usado pelos Algos para determinar a alocação de um Nó. Algorithm Stacks Algos e AlgoStacks são outro recurso essencial que facilita a criação de lógica de estratégia modular e reutilizável. Devido à sua modularidade, esses blocos lógicos também são mais fáceis de testar - um passo importante na construção de soluções financeiras robustas. Gráficos e relatórios bt também fornece muitas funções úteis de gráficos que ajudam a visualizar os resultados do backtest. Também planejamos adicionar mais gráficos, tabelas e formatos de relatório no futuro, como gerar relatórios em PDF gerados automaticamente. Estatísticas detalhadas Além disso, o bt calcula um monte de estatísticas relacionadas a um backtest e oferece uma maneira rápida de comparar essas várias estatísticas em vários backtests diferentes por meio dos métodos de exibição do Results.
Os futuros esforços de desenvolvimento se concentrarão em:
Velocidade Devido à natureza flexível do BT, um trade-off teve que ser feito entre usabilidade e desempenho. A usabilidade sempre será a prioridade, mas queremos melhorar o desempenho o máximo possível. Algos Também estaremos desenvolvendo mais algoritmos com o passar do tempo. Nós também encorajamos qualquer um a contribuir com seus próprios algos também. Criação de gráficos e relatórios Esta é outra área que desejamos melhorar constantemente, pois os relatórios são um aspecto importante do trabalho. Gráficos e relatórios também facilitam encontrar bugs na lógica da estratégia.
Backtesting de Python forex
Puxe as solicitações 11.
Junte-se ao GitHub hoje.
O GitHub é o lar de mais de 20 milhões de desenvolvedores trabalhando juntos para hospedar e revisar código, gerenciar projetos e construir software juntos.
Clone com HTTPS.
Use Git ou check-out com o SVN usando o URL da web.
O QSForex é um backtesting de código aberto orientado a eventos e uma plataforma de negociação ao vivo para uso nos mercados de câmbio ("forex"), atualmente em um estado "alfa".
Foi criado como parte da série Forex Trading Diary no QuantStart para fornecer à comunidade de negociação sistemática um mecanismo de negociação robusto que permite a implementação e teste diretos da estratégia do Forex.
O software é fornecido sob uma licença "MIT" permissiva (veja abaixo).
Open-Source - O QSForex foi lançado sob uma Licença MIT de código aberto extremamente permissiva, que permite o uso total em aplicações comerciais e de pesquisa, sem restrições, mas sem garantia de qualquer tipo. Livre - QSForex é totalmente gratuito e não custa nada para baixar ou usar. Colaboração - Como o QSForex é de código aberto, muitos desenvolvedores colaboram para melhorar o software. Novos recursos são adicionados com freqüência. Quaisquer erros são rapidamente determinados e corrigidos. Desenvolvimento de Software - O QSForex é escrito na linguagem de programação Python para suporte direto a várias plataformas. O QSForex contém um conjunto de testes de unidade para a maioria do seu código de cálculo e novos testes são constantemente adicionados para novos recursos. Arquitetura orientada a eventos - A QSForex é totalmente orientada a eventos, tanto para backtesting quanto para negociação ao vivo, o que leva à transição direta de estratégias de uma fase de pesquisa / teste para uma implementação de negociação ao vivo. Custos de transação - Os custos de spread são incluídos por padrão para todas as estratégias de backtested. Backtesting - QSForex apresenta backtesting de pares multi-dia com resolução de ticks intraday. Negociação - A QSForex atualmente suporta negociação intraday ao vivo usando a API de Brokerage da OANDA em um portfólio de pares. Métricas de Desempenho - A QSForex atualmente suporta medição de desempenho básica e visualização de equidade através das bibliotecas de visualização Matplotlib e Seaborn.
Visite oanda / e configure uma conta para obter as credenciais de autenticação da API, as quais você precisará para realizar negociações ao vivo. Eu explico como realizar isso neste artigo: quantstart / artigos / Forex-Trading-Diário-1-Automatizado-Forex-Trading-com-o-OANDA-API.
Clone este repositório git em um local adequado em sua máquina usando o seguinte comando em seu terminal: git clone github / mhallsmoore / qsforex. git. Alternativamente, você pode baixar o arquivo zip da ramificação mestre atual em github / mhallsmoore / qsforex / archive / master. zip.
Crie um conjunto de variáveis de ambiente para todas as configurações encontradas no arquivo settings. py no diretório raiz do aplicativo. Como alternativa, você pode "codificar" suas configurações específicas sobrescrevendo as chamadas os. environ. get (.) Para cada configuração:
Isso criará um novo ambiente virtual para instalar os pacotes. Supondo que você baixou o repositório git QSForex em um diretório de exemplo como.
/ projects / qsforex / (mude este diretório abaixo para onde quer que você tenha instalado o QSForex), então para instalar os pacotes você precisará executar os seguintes comandos:
Isso levará algum tempo para que o NumPy, SciPy, Pandas, Scikit-Learn e Matplotlib sejam compilados. Existem muitos pacotes necessários para que isso funcione, então, por favor, dê uma olhada nesses dois artigos para mais informações:
Você também precisará criar um link simbólico do diretório de pacotes do site para o diretório de instalação do QSForex para poder chamar o qsforex de importação dentro do código. Para fazer isso, você precisará de um comando semelhante ao seguinte:
Certifique-se de mudar.
/ projects / qsforex para o seu diretório de instalação e.
/venv/qsforex/lib/python2.7/site-packages/ para o seu diretório de pacotes de sites virtualenv.
Agora você poderá executar os comandos subseqüentes corretamente.
Nesta fase, se você simplesmente deseja realizar prática ou negociação ao vivo, então você pode executar python trading / trading. py, que usará a estratégia de negociação padrão do TestStrategy. Isso simplesmente compra ou vende um par de moedas a cada 5 ticks. É puramente para testes - não use em um ambiente de negociação ao vivo!
Se você deseja criar uma estratégia mais útil, basta criar uma nova turma com um nome descritivo, por exemplo, MeanReversionMultiPairEstratégie e garanta que ele tenha um método calculate_signals. Você precisará passar essa classe à lista de pares, bem como à fila de eventos, como em trading / trading. py.
Por favor, olhe para strategy / strategy. py para detalhes.
Para realizar qualquer backtesting é necessário gerar dados simulados de forex ou baixar dados históricos de ticks. Se você quiser simplesmente testar o software, a maneira mais rápida de gerar um exemplo de backtest é gerar alguns dados simulados. O formato de dados atual usado pelo QSForex é o mesmo fornecido pelo DukasCopy Historical Data Feed em dukascopy / swiss / english / marketwatch / historical /.
Para gerar alguns dados históricos, certifique-se de que a configuração CSV_DATA_DIR em settings. py seja definida como um diretório no qual você deseja que os dados históricos sejam armazenados. Você então precisa rodar generate_simulated_pair. py, que está sob o diretório scripts /. Ele espera um único argumento de linha de comando, que nesse caso é o par de moedas no formato BBBQQQ. Por exemplo:
Nesse estágio, o script é codificado para criar dados de um único mês para janeiro de 2014. Ou seja, você verá arquivos individuais, do formato BBBQQQ_YYYYMMDD. csv (por exemplo, GBPUSD_20140112.csv), exibidos em seu CSV_DATA_DIR em todos os dias úteis daquele mês. Se você deseja alterar o mês / ano da saída de dados, simplesmente modifique o arquivo e execute novamente.
Agora que os dados históricos foram gerados, é possível realizar um backtest. O arquivo de backtest em si é armazenado em backtest / backtest. py, mas isso contém apenas a classe Backtest. Para realmente executar um backtest, você precisa instanciar esta classe e fornecê-la com os módulos necessários.
A melhor maneira de ver como isso é feito é examinar o exemplo da implementação do Moving Average Crossover no arquivo examples / mac. py e usá-lo como um modelo. Isso faz uso do MovingAverageCrossStrategy, que é encontrado em strategy / strategy. py. Isso padroniza a negociação de GBP / USD e EUR / USD para demonstrar o uso de múltiplos par de moedas. Ele usa dados encontrados em CSV_DATA_DIR.
Para executar o exemplo de backtest, simplesmente execute o seguinte:
Isso vai levar algum tempo. No meu sistema de desktop Ubuntu em casa, com os dados históricos gerados via generate_simulated_pair. py, demora cerca de 5 a 10 minutos para ser executado. Uma grande parte desse cálculo ocorre no final do backtest real, quando o drawdown está sendo calculado, então lembre-se de que o código não foi desativado! Por favor, deixe-o até a conclusão.
Se você deseja visualizar o desempenho do backtest, basta usar o output. py para visualizar uma curva de patrimônio, retornos de período (ou seja, retornos tick-to-tick) e uma curva de rebaixamento:
E é isso! Nesta fase você está pronto para começar a criar seus próprios backtests modificando ou anexando estratégias em strategy / strategy. py e usando dados reais baixados do DukasCopy (dukascopy / swiss / english / marketwatch / historical /).
Se você tiver alguma dúvida sobre a instalação, por favor, sinta-se à vontade para me enviar um e-mail para mike @ quantstart.
Se você tiver algum bug ou outros problemas que você acha que podem estar relacionados à base de código especificamente, sinta-se à vontade para abrir um problema do Github aqui: github / mhallsmoore / qsforex / issues.
Copyright (c) 2015 Michael Halls-Moore.
É concedida permissão, gratuitamente, a qualquer pessoa que obtenha uma cópia deste software e dos arquivos de documentação associados (o "Software"), para negociar o Software sem restrições, incluindo, sem limitação, os direitos de uso, cópia, modificação e fusão , publicar, distribuir, sublicenciar e / ou vender cópias do Software e permitir que pessoas a quem o Software é fornecido o façam, sujeitas às seguintes condições:
O aviso de copyright acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do Software.
O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM FIM ESPECÍFICO E NÃO VIOLAÇÃO. EM NENHUMA CIRCUNSTÂNCIA, OS AUTORES OU PROPRIETÁRIOS DE DIREITOS DE AUTOR PODERÃO SER RESPONSABILIZADOS POR QUAISQUER REIVINDICAÇÕES, DANOS OU OUTRAS RESPONSABILIDADES, QUER EM ACÇÃO DE CONTRATO, DELITO OU DE OUTRA FORMA, DECORRENTES DE, OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO PROGRAMAS.
A negociação de divisas estrangeiras na margem acarreta um alto nível de risco e pode não ser adequada para todos os investidores. O desempenho passado não é indicativo de resultados futuros. O alto grau de alavancagem pode funcionar contra você e também para você. Antes de decidir investir em moeda estrangeira, você deve considerar cuidadosamente seus objetivos de investimento, nível de experiência e apetite de risco. Existe a possibilidade de você sustentar uma perda de parte ou de todo o seu investimento inicial e, portanto, não deve investir dinheiro que não pode perder. Você deve estar ciente de todos os riscos associados à negociação em moeda estrangeira e procurar orientação de um consultor financeiro independente, caso tenha alguma dúvida.
&cópia de; 2018 GitHub, Inc. Termos Privacidade Status de Segurança Ajuda.
Você não pode realizar essa ação no momento.
Você entrou com outra guia ou janela. Recarregue para atualizar sua sessão. Você saiu de outra guia ou janela. Recarregue para atualizar sua sessão.
Backtesting baseado em eventos com Python - Parte I.
Backtesting baseado em eventos com Python - Parte I.
Nós passamos o último par de meses no QuantStart fazendo backtesting de várias estratégias de negociação utilizando Python e pandas. A natureza vetorizada dos pandas garante que certas operações em grandes conjuntos de dados sejam extremamente rápidas. No entanto, as formas de backtester vetorizado que estudamos até agora sofrem de algumas desvantagens na maneira como a execução da negociação é simulada. Nesta série de artigos, vamos discutir uma abordagem mais realista da simulação de estratégia histórica, construindo um ambiente de backtesting baseado em eventos usando o Python.
Software orientado a eventos.
Antes de nos aprofundarmos no desenvolvimento de um backtester, precisamos entender o conceito de sistemas baseados em eventos. Os videogames fornecem um caso de uso natural para software orientado a eventos e fornecem um exemplo direto para explorar. Um videogame tem vários componentes que interagem entre si em uma configuração em tempo real em altas taxas de quadros. Isso é feito executando todo o conjunto de cálculos dentro de um loop "infinito" conhecido como loop de evento ou loop de jogo.
A cada tick do loop de jogo, uma função é chamada para receber o último evento, que terá sido gerado por alguma ação prévia correspondente dentro do jogo. Dependendo da natureza do evento, que pode incluir um pressionamento de tecla ou um clique do mouse, alguma ação subseqüente é executada, o que terminará o loop ou gerará alguns eventos adicionais. O processo continuará então. Aqui está um exemplo de pseudo-código:
O código está continuamente verificando novos eventos e, em seguida, realizando ações com base nesses eventos. Em particular, ele permite a ilusão de manipulação de resposta em tempo real, porque o código está continuamente em loop e os eventos são verificados. Como ficará claro, é precisamente disso que precisamos para realizar a simulação de negociação de alta frequência.
Por que um backtester baseado em eventos?
Os sistemas orientados a eventos fornecem muitas vantagens sobre uma abordagem vetorizada:
Reutilização de código - um backtester baseado em eventos, por design, pode ser usado tanto para backtesting histórico quanto para negociação ao vivo com o mínimo de troca de componentes. Isso não é verdade para os backtesters vetorizados, onde todos os dados devem estar disponíveis ao mesmo tempo para realizar a análise estatística. Lookahead Bias - Com um backtester baseado em eventos, não há viés de antecipação, pois o recebimento de dados de mercado é tratado como um "evento" que deve ser considerado. Assim, é possível "drenar" um backtester orientado a eventos com dados de mercado, replicando como um sistema de gerenciamento de pedidos e portfólio se comportaria. Realismo - backtesters orientados a eventos permitem personalização significativa sobre como os pedidos são executados e os custos de transação são incorridos. É fácil lidar com ordens básicas de mercado e de limite, assim como com o mercado aberto (MOO) e com o mercado no fechamento (MOC), já que um manipulador de troca personalizado pode ser construído.
Embora os sistemas orientados a eventos tenham muitos benefícios, eles sofrem de duas grandes desvantagens em relação aos sistemas vetoriais mais simples. Em primeiro lugar, eles são significativamente mais complexos para implementar e testar. Existem mais "partes móveis" que levam a uma maior chance de introduzir bugs. Para mitigar esta metodologia adequada de teste de software, como o desenvolvimento orientado a testes, pode ser empregado.
Em segundo lugar, eles são mais lentos para executar em comparação com um sistema vetorizado. Operações otimizadas vetorizadas não podem ser utilizadas ao realizar cálculos matemáticos. Vamos discutir maneiras de superar essas limitações em artigos posteriores.
Visão geral do backtester orientado a eventos.
Para aplicar uma abordagem orientada a eventos em um sistema de backtesting, é necessário definir nossos componentes (ou objetos) que manipularão tarefas específicas:
Evento - O Evento é a unidade de classe fundamental do sistema baseado em eventos. Ele contém um tipo (como "MARKET", "SIGNAL", "ORDER" ou "FILL") que determina como ele será tratado no loop de eventos. Fila de Eventos - A Fila de Eventos é um objeto Fila Python na memória que armazena todos os objetos de subclasse Event que são gerados pelo restante do software. DataHandler - O DataHandler é uma classe base abstrata (ABC) que apresenta uma interface para lidar com dados históricos ou ao vivo no mercado. Isso proporciona uma flexibilidade significativa, pois os módulos de Estratégia e Portfólio podem ser reutilizados entre as duas abordagens. O DataHandler gera um novo MarketEvent a cada pulsação do sistema (veja abaixo). Estratégia - A Estratégia também é um ABC que apresenta uma interface para obter dados de mercado e gerar SignalEvents correspondentes, que são utilizados pelo objeto Portfolio. Um SignalEvent contém um símbolo, uma direção (LONG ou SHORT) e um timestamp. Portfólio - Este é um ABC que lida com o gerenciamento de pedidos associado às posições atuais e subsequentes de uma estratégia. Ele também executa o gerenciamento de riscos em todo o portfólio, incluindo a exposição do setor e o dimensionamento de posições. Em uma implementação mais sofisticada, isso poderia ser delegado a uma classe RiskManagement. O Portfólio pega SignalEvents da Fila e gera OrderEvents que são adicionados à Fila. ExecutionHandler - O ExecutionHandler simula uma conexão com uma corretora. O trabalho do manipulador é pegar OrderEvents da Fila e executá-los, seja por meio de uma abordagem simulada ou de uma conexão real com uma corretora de fígado. Quando as ordens são executadas, o manipulador cria FillEvents, que descreve o que foi realmente transacionado, incluindo taxas, comissão e derrapagem (se modelado). O Loop - Todos esses componentes são agrupados em um loop de eventos que manipula corretamente todos os tipos de eventos, roteando-os para o componente apropriado.
Este é um modelo básico de um mecanismo de negociação. Existe um espaço significativo para expansão, particularmente no que diz respeito à forma como a Carteira é utilizada. Além disso, os diferentes modelos de custo de transação também podem ser abstraídos em sua própria hierarquia de classes. Nesta fase, introduz desnecessária complexidade dentro desta série de artigos, por isso não vamos discutir mais sobre isso. Em tutoriais posteriores, provavelmente expandiremos o sistema para incluir realismo adicional.
Aqui está um trecho de código Python que demonstra como o backtester funciona na prática. Existem dois loops ocorrendo no código. O loop externo é usado para dar ao backtester um heartbeat. Para negociação ao vivo, essa é a frequência com que os novos dados de mercado são pesquisados. Para estratégias de backtesting, isso não é estritamente necessário, já que o backtester usa os dados de mercado fornecidos na forma de alimentação por gotejamento (veja a linha bars. update_bars ()).
O loop interno realmente manipula os eventos do objeto Fila de eventos. Eventos específicos são delegados ao respectivo componente e, subsequentemente, novos eventos são adicionados à fila. Quando os eventos Queue estão vazios, o loop de pulsação continua:
Este é o esboço básico de como um backtester baseado em eventos é projetado. No próximo artigo, discutiremos a hierarquia de classes de eventos.
A Quantcademy.
Participe do portal de associação da Quantcademy que atende à crescente comunidade de traders de quantificação de varejo e aprenda como aumentar a lucratividade de sua estratégia.
Negociação Algorítmica Bem Sucedida.
Como encontrar novas ideias de estratégia de negociação e avaliá-las objetivamente para o seu portfólio usando um mecanismo de backtesting personalizado no Python.
Comércio Algorítmico Avançado.
Como implementar estratégias de negociação avançadas usando análise de séries temporais, aprendizado de máquina e estatísticas Bayesianas com R e Python.
Forex Mecânico
Negociação no mercado de câmbio usando estratégias de negociação mecânicas.
Backtesting Trading Systems em Python: Não é uma boa escolha.
A linguagem python é extremamente versátil, fácil de usar e conveniente. Não há discussão sobre a versatilidade desta linguagem quando se trata da quantidade de tempo que leva para colocar uma ideia utilizável no código. Quer carregar um arquivo csv? Quer realizar um cálculo de indicador? Quer traçar um conjunto de valores? Todas essas coisas podem ser feitas com apenas algumas linhas de código em python, enquanto certamente seriam necessárias páginas inteiras, se não milhares, de linhas para fazer as mesmas coisas em linguagens como C e Fortran. No entanto python tem várias fraquezas que o tornam uma má escolha quando se trata de back-testing estratégias de negociação, especialmente quando se trata de back-testing baseado em eventos. Neste post irei analisar as diferentes coisas que tornam o python uma má escolha para codificar mecanismos de back-testing e porque & # 8211; apesar do muito mais tempo de codificação & # 8211; os benefícios de usar uma linguagem de nível mais baixo provavelmente superam os problemas para certos tipos de teste. Para realizar o teste abaixo, faça o download do código aqui.
Em geral, é importante entender que há duas maneiras principais de fazer back-testing. O primeiro é o que é chamado de back-testing baseado em vetores e o segundo é chamado de back-testing baseado em eventos. Quando você faz um back-teste baseado em vetor, você calcula vetores que representam decisões de negociação e então faz operações vetoriais para extrair o desempenho dessas variáveis. Digamos que você queira fazer back-teste de uma estratégia cruzada de média móvel da forma vetorial, você primeiro calcula um vetor com todos os valores de média móvel, então cria um segundo vetor que contém um booleano com a média móvel maior ou menor que preço, você então usa estes valores para calcular um vetor que representa a equidade de acordo com o local onde você tem sinais, etc. O teste de fundo baseado em vetor faz tudo através de vetores de cálculo e esses vetores são usados para gerar os resultados do teste. É uma maneira matematicamente eficiente de realizar back-testing de certos tipos de sistemas.
No entanto, existem muitas desvantagens em usar testes baseados em vetores (que deixarei para discutir em um post futuro), o que leva muitas pessoas à alternativa, que são testes baseados em eventos. No back-testing baseado em eventos, você percorre os dados de negociação disponíveis e transmite ao seu algoritmo todas as informações disponíveis em cada ponto no tempo. Este é o caminho do back-testing que mais se aproxima da execução real do mercado, porque sua estratégia é apenas fazer a mesma coisa, é receber dados e tomar decisões sobre cada unidade de tempo quando for necessário. Por essa razão, os back-tests baseados em eventos podem testar todas as estratégias que poderiam ser negociadas no mercado, e os algoritmos codificados para back-testing baseado em eventos geralmente podem ser usados sem modificações no comércio ao vivo, porque a mecânica é simplesmente a mesma. No back-testing baseado em eventos, você faz uma simulação explícita da sua estratégia através de seus dados, como a sua estratégia teria feito em negociação ao vivo (ou pelo menos o mais perto possível).
Se você deseja codificar um mecanismo de teste de retorno baseado em eventos em python, você enfrentará alguns problemas sérios devido à natureza do python. Você pode ter decidido usar python porque codificar dentro desta linguagem é muito fácil, mas você logo descobrirá que isso tem um grande custo. Se você deseja executar um simples carregamento de dados e um exercício de teste baseado em eventos, provavelmente usará algum código como o mostrado no exemplo acima. Este exemplo carrega dados de um arquivo chamado TEST_60.csv (dados 1H de 1 ano gerados aleatoriamente) e, em seguida, executa um loop simples por todo o dataframe do pandas para calcular o intervalo médio de 20 bar em cada barra (algo extremamente simples). Fazer este exercício simples leva cerca de 12-15 segundos para carregar os dados em um dataframe pandas & # 8211; principalmente devido à data de análise & # 8211; e depois vários minutos para realizar o exercício de looping. É extremamente lento percorrer um dataframe de pandas porque bibliotecas como pandas simplesmente não são projetadas para executar esse tipo de tarefa, elas são projetadas para operações baseadas em vetores que são otimizadas dentro de funções baseadas em C dentro da biblioteca.
Quando você usa bibliotecas como pandas ou numpy, o custo do loop é realmente muito maior do que o custo de looping através de uma lista python simples, porque essas bibliotecas têm funções ineficientes para acessar elementos únicos dentro de seus objetos porque esse tipo de operação não é para o qual as bibliotecas foram projetadas. Os dataframes e os matrizes numpy do Pandas não devem ser iterados, eles devem ser usados para executar operações baseadas em vetores (essa é a coisa que o Pythonic faz). Você pode executar alguns testes e ver o quanto seu tempo muda quando você altera a função usada para acessar valores dentro do dataframe do pandas, se você mudar de ix para iat ou iloc você notará algumas diferenças importantes nos tempos de execução (veja aqui mais sobre desempenho do método de indexação). Usar uma biblioteca como pandas ou numpy é ótimo em termos da quantidade de tempo de codificação salva, mas se você estiver fazendo back-testing baseado em eventos, nunca terá algo rápido o suficiente.
O custo de executar esse tipo de looping em Python torna a linguagem praticamente inútil para qualquer projeto de teste de back-end em grande escala que exija testes baseados em eventos. O loop de barras 1H codificado acima leva vários minutos para ser executado e nem sequer Fazendo cálculos altamente exigentes, não está nem acompanhando a equidade, negociando ou fazendo qualquer geração de sinal. Isso tudo porque looping através de objetos pandas é tremendamente lento. Claro, poderíamos torná-lo mais rápido se não utilizássemos pandas para isso ou se usássemos ctypes, mas, em seguida, você já está se movendo para o território de idiomas de baixo nível. Você está desistindo de algo que é tremendamente amigável para codificar com (pandas) algo mais rápido (ctypes). Se você está disposto a aumentar seu tempo de codificação para ganhar velocidade, então é melhor simplesmente ir para um idioma de nível mais baixo. Se você está gastando 10 vezes mais tempo fazendo o código python mais rápido, então gaste esse tempo codificando-o em C, onde você saberá que será o mais rápido possível.
É claro que não estou argumentando que não há lugar para python em back-testing (afinal, codificamos uma biblioteca de análise de séries temporais de código aberto em python chamada qqpat). Você pode executar testes rápidos baseados em vetores simples usando esta linguagem e se você está disposto a abrir mão das bibliotecas mais fáceis de usar, você pode codificar algo muito mais rápido usando ctypes e acelerar ainda mais usando algo como pypy . No entanto, o melhor uso que eu encontrei para python é realmente usá-lo como um frontend para bibliotecas de back-testing muito mais rápidas codificadas em C / C ++. Em nossa comunidade, usamos python para fazer coisas como carregar configurações, gerar gráficos e carregar arquivos csv, enquanto uma biblioteca C muito mais eficiente realiza o back-testing real baseado em eventos. Fazendo isso, podemos executar backtests de 30 anos inteiros em barras de 1H em questão de segundos, enquanto fazendo isso em python usando bibliotecas fáceis de usar, como pandas, provavelmente levaria 100 vezes o tempo, se não mais. Não é um mistério, então, por que existem simplesmente programas de back-testing baseados em eventos comerciais que usam python, simplesmente não é um corte de linguagem para esse trabalho.
Se você gostaria de aprender mais sobre back-testing e como você também pode codificar e testar estratégias usando nossa estrutura de programação C / C ++, por favor considere juntar-se à Asirikuy, um site repleto de vídeos educacionais, sistemas de negociação, desenvolvimento e um som honesto e transparente. abordagem para negociação automatizada.
3 Responses to & # 8220; Backtesting Trading Systems em Python: Não é uma boa escolha & # 8221;
Eu acho que alguns pequenos ajustes no seu código resultarão em uma aceleração significativa e podem tornar o Python um pouco mais aceitável.
1) a impressão é bastante cara. Se você quiser imprimir os dados contidos em average_range em intervalos específicos, poderá fazê-lo depois de preenchê-los.
2) Considere pré-alocar um array NumPy vazio:
& gt; & gt; n_elements = len (intervalo (2, len (main_rates. index)) * 20.
& gt; & gt; average_range [(i-2) * 20 + j] = range_value.
Apenas fazendo isso, chego a um tempo total de execução de 0,033 s em dois Intel Xeon E5-2620s. Eu estou no IPython de 64 bits usando o NumPy 1.10 e o Pandas 0.17.1, pelo que vale a pena.
Obrigado por publicar! Melhoria realmente agradável, claramente a função de impressão estava lá apenas para fins ilustrativos (eu só queria que os usuários vissem o que a função estava fazendo), mas bom trabalho na redução do tempo, pré-alocando o array numpy. Claro que existem todos os tipos de coisas que você pode fazer para tornar o código mais rápido em python & # 8212; Eu definitivamente não estou dizendo que isso não pode ser feito, especialmente em casos específicos como este. No entanto, acredito que ainda exista um ponto válido para que, para obter um desempenho aceitável no Python, você precise abrir mão de uma boa parte da "facilidade de codificação" & # 8221; Isso faz com que seja uma linguagem tão atraente para começar. Quando seu código se torna realmente complexo & # 8211; como se você quiser fazer aprendizado de máquina & # 8211; modificações como a que você postou se tornam cada vez mais difíceis de alcançar. No final, para chegar a tempos de execução como os do C / C ++, você pode acabar gastando tempo como se estivesse codificando nessas linguagens de nível mais baixo.
O que você acha? Você acredita que este é o caso? Você acha que há sempre uma otimização factível que pode fazer um código python atingir um desempenho semelhante ao C / C ++ sem muito esforço? Alguma dica de python que você gostaria de compartilhar? É claro que eu não tenho a última palavra em python, então qualquer abridor de olhos é definitivamente bem-vindo! Deixe-me saber e muito obrigado pela sua contribuição,
Eu acho que, em geral, se a operação não é vetorizada, ficando "mais perto do metal" # 8217; usando cython (ou algo parecido) será ótimo e você está vivendo no mundo C / C ++.
Dito isso, obtive ótimos resultados usando o Numba (uma biblioteca de compilação just-in-time que funciona muito bem com o NumPy) para acelerar ARMA e outras computações não-vetorizadas. Para mais informações, veja:
Existem todos os tipos de personalizações e otimizações disponíveis para você, mas simplesmente decorar um loop numérico isolado, por exemplo, com @jit parece ser bastante eficaz na maioria dos casos.
No comments:
Post a Comment