Jon V.
BigData. Iniciantes. Negociação.
BigData. Iniciantes. Negociação.
Construindo um sistema backtesting em Python: ou como perdi $ 3400 em duas horas.
Construir um sistema de backtest é realmente muito fácil. Fácil de estragar, quero dizer. Embora existam toneladas de excelentes bibliotecas por aí (e as abordaremos em algum momento), eu sempre gosto de fazer isso por conta própria para ajustá-la.
De todos os sistemas backtesting que eu vi, podemos assumir que existem duas categorias:
Hoje, falaremos sobre "loopers".
Os "for-loopers" são o meu tipo favorito de backtesters. Eles são triviais para escrever e super divertidos para 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 funciona o looping? Usando um loop for (como você pode ter adivinhado). É algo assim:
Muito simples, certo? É assim que funciona um sistema de backtesting, que executa uma estratégia de impulso:
Então qual é o problema?
Muito difícil de escalar (horizontalmente) Precisa de muito trabalho para manter sua estratégia de aplicação () trabalhando no backtesting e na produção Você precisa ter tudo na mesma linguagem de programação.
Vamos mergulhar nessas, uma a uma.
Escalabilidade. Eu estava experimentando um par de semanas atrás com um algoritmo de escalada de colina para otimizar uma das minhas estratégias. Ainda está em execução. Depois de duas semanas. E eu construo sistemas robustos para uma vida. Por que ainda está funcionando? Você pode usar multiprocessamento, Disco, produtor / consumidor (usando o ZeroMQ) ou apenas threads para acelerar isso, mas alguns problemas não são "paralisações embaraçosas" (sim, este é um termo real, e não uma das minhas palavras inventadas). A quantidade de trabalho para escalar um backtester como esse (especialmente quando você quer fazer a mesma máquina aprendendo em cima dela) é enorme. Você pode fazê-lo, mas é o caminho errado.
Produção e backtesting em sincronia. As vezes que fui mordido por isso. Posso recordar as trocas perdidas onde eu estava "hm, por que eu entrei nesse comércio?" ou o meu antigo favorito "POR QUE A PARADA DE REALIZAÇÃO FOI APLICADA AGORA?".
Tempo da história: tive uma ideia para otimizar minha estratégia, para executar um backtester para ver o que aconteceria se eu pudesse colocar uma parada posterior depois que o comércio fosse rentável para garantir sempre lucros. Backtesting funcionou como um charme com um aumento de 13% nos ganhos e a produção perdeu todo comércio. Descobri que depois do meu algo perdi US $ 3400 em algumas horas (uma lição muito cara).
Manter a estratégia apply_strategy em sincronia é muito difícil e torna-se quase impossível quando você deseja fazê-lo de forma distribuída. E você não quer ter duas versões de sua estratégia que sejam "quase" idênticas. A menos que você tenha US $ 3400 de sobra.
Usando diferentes idiomas, adoro Python. E Erlang. E Clojure. E J. E C. E R. E Ruby (na verdade eu odeio Ruby). Eu quero poder aproveitar a força de outros idiomas no meu sistema. Quero experimentar estratégias em R onde há 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 crunch dados. Se você quer ser bem sucedido (não apenas na negociação), você precisa usar todos os recursos disponíveis sem prejuízos. Aprendi toneladas de coisas de sair com os desenvolvedores R sobre como você pode delta hedge bonds e visualizá-los ou por que razão Sharpe pode ser uma mentira. Todo idioma tem uma multidão diferente e você quer que muitas pessoas despejam idéias em seu sistema. Se você tentar aplicar a estratégia apply_strategy em idioma diferente, então, boa sorte com (2).
Você está convencido agora? Bem, eu não estou tentando convencê-lo como for-loopers é uma ótima maneira de executar seus testes iniciais. É como eu comecei e, para muitas estratégias, não as envio para o pipeline. Um "melhor" caminho (para que você possa dormir à noite) são os geradores de eventos.
Próximamente, compartilhando e discutindo meu backtester mais simples (mas com maior sucesso)!
Se você tiver mais comentários, clique-me no jonromero ou inscreva-se no boletim informativo.
Legal outro. Este é um tutorial de engenharia sobre como construir uma plataforma algotrading para experimentação e FUN. Qualquer sugestão aqui não é um conselho financeiro. Se você perder qualquer (ou todos) o seu dinheiro porque seguiu quaisquer conselhos de negociação ou implantou este sistema na produção, não pode culpar este blog aleatório (e / ou eu). Aproveite a seu próprio risco.
bt - Backtesting flexível para Python¶
O que é bt? ¶
bt é um framework flexível de backtesting para Python usado para testar estratégias de negociação quantitativas. Backtesting é o processo de testar uma estratégia em um dado conjunto de dados. Esta estrutura permite que você crie facilmente estratégias que combinam e combinam diferentes Algos. Ele visa 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 comerciais complexas.
O objetivo: salvar quants de reinventar a roda e deixá-los concentrar-se na parte importante do trabalho - desenvolvimento da estratégia.
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 sinal e estatísticas e podem ser alavancadas para evitar reinventar a roda - algo que acontece muitas vezes ao usar outras linguagens que não têm a mesma riqueza de alta qualidade, projetos de fontes.
bt é construído em cima do ffn - uma biblioteca de funções financeiras para Python. Confira!
Um exemplo rápido¶
Aqui está um gosto rápido de bt:
Um Backtest de Estratégia Simples¶
Vamos criar uma estratégia simples. Criaremos uma estratégia mensal reequilibrada e de longa duração, onde colocamos pesos iguais em cada ativo em nosso universo de ativos.
Primeiro, vamos baixar alguns dados. Por padrão, bt. get (alias para ffn. get) baixa o Fechar ajustado do Yahoo! Finança. Vamos baixar alguns dados a partir de 1º de janeiro de 2018 para os propósitos desta demonstração.
Uma vez que possamos nossos dados, criaremos nossa estratégia. O objeto Estratégia contém a lógica estratégica ao combinar vários Algos.
Finalmente, vamos criar um Backtest, que é a combinação lógica de uma estratégia com um conjunto de dados.
Uma vez 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¶
Agora, e se fizé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 é ligar 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 idéia de usar Algos simples e composíveis 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 composição de estratégias complexas de negociação algorítmica que são modulares e reutilizáveis. Além disso, cada nó de árvore possui seu próprio índice de preços que pode ser usado por Algos para determinar a alocação de um nó & # 8217; s. Algorithm Stacks Algos e AlgoStacks são outras características principais que facilitam a criação de lógica de estratégia modular e reutilizável. Devido à sua modularidade, esses blocos de lógica também são mais fáceis de testar - um passo importante na construção de soluções financeiras robustas. Charting and Reporting bt também fornece muitas funções de gráficos úteis que ajudam a visualizar os resultados do backtest. Também planejamos adicionar mais gráficos, tabelas e formatos de relatório no futuro, como relatórios PDF gerados automaticamente. Estatísticas detalhadas Além disso, 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 através dos métodos de exibição dos resultados.
Futuros esforços de desenvolvimento incidirã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 desejamos melhorar o desempenho tanto quanto possível. Algos Também desenvolveremos mais algoritmos com o passar do tempo. Também incentivamos alguém a contribuir com seus próprios algos também. Cartografia e Relatórios Esta é outra área que desejamos melhorar constantemente, pois o relatório é um aspecto importante do trabalho. A elaboração de gráficos e relatórios também facilitam a descoberta de erros na lógica da estratégia.
QuantStart.
Junte-se ao portal de membros privados da Quantcademy que atende à comunidade de comerciantes de varejo de varejo em rápido crescimento. Você encontrará um grupo bem informado de mentalistas quant pronto para responder suas perguntas comerciais mais importantes.
Confira meu ebook sobre o comércio de quant, onde eu ensino você como criar estratégias de negociação sistemáticas lucrativas com ferramentas Python, desde o início.
Dê uma olhada no meu novo ebook sobre estratégias de negociação avançadas usando análise de séries temporais, aprendizado de máquina e estatísticas bayesianas, com Python e R.
Por Michael Halls-Moore em 11 de março de 2017.
Passamos os últimos dois meses no QuantStart backtesting várias estratégias de negociação utilizando Python e pandas. A natureza vectorizada dos pandas garante que determinadas operações em grandes conjuntos de dados sejam extremamente rápidas. No entanto, as formas de backtester vectorizados que estudamos até à data sofrem de algumas desvantagens na forma como a execução comercial é simulada. Nesta série de artigos, vamos discutir uma abordagem mais realista da simulação de estratégia histórica através da construção de um ambiente de backtesting baseado em eventos usando o Python.
Software dirigido por eventos.
Antes de aprofundar o desenvolvimento de um backtester, precisamos entender o conceito de sistemas orientados a eventos. Os jogos de vídeo fornecem um caso de uso natural para o software baseado em eventos e fornecem um exemplo direto para explorar. Um videogame tem vários componentes que interagem uns com os outros em uma configuração em tempo real em alta velocidade. Isso é gerenciado executando todo o conjunto de cálculos dentro de um loop "infinito" conhecido como loop de eventos ou loop de jogo.
Em cada marca do jogo, uma função é chamada para receber o último evento, que será gerado por alguma ação anterior correspondente dentro do jogo. Dependendo da natureza do evento, que pode incluir uma tecla pressionada ou um clique do mouse, são tomadas algumas ações subseqüentes, que irão encerrar o loop ou gerar alguns eventos adicionais. O processo continuará. Aqui está um exemplo de pseudo-código:
O código está verificando continuamente novos eventos e, em seguida, executando ações com base nesses eventos. Em particular, permite a ilusão de tratamento de resposta em tempo real porque o código está sendo continuamente roteado e os eventos são verificados. Como ficará claro, isso é precisamente o que precisamos para realizar simulação de negociação de alta freqüência.
Por que um Backtester dirigido por eventos?
Os sistemas orientados a eventos oferecem muitas vantagens em relação a uma abordagem vetorializada:
Reutilização de código - Um backtester com base em eventos, por design, pode ser usado tanto para testes históricos quanto para negociação ao vivo com a troca mínima de componentes. Isso não é verdade para testadores vectorizados, onde todos os dados devem estar disponíveis ao mesmo tempo para realizar análises estatísticas. Lookahead Bias - Com um backtester dirigido por eventos, não existe um viés de lookahead, pois o recebimento de dados de mercado é tratado como um "evento" que deve ser atuado. Assim, é possível "gotejar alimentação" um backtester dirigido por eventos com dados de mercado, replicando como um sistema de gerenciamento de pedidos e de portfólio se comportaria. Realismo - Os backtesters dirigidos a eventos permitem uma personalização significativa sobre como as ordens são executadas e os custos de transação são incorridos. É direto lidar com pedidos básicos de mercado e limite, bem como mercado-em-aberto (MOO) e mercado-em-fechar (MOC), uma vez que um manipulador de troca personalizado pode ser construído.
Embora os sistemas orientados a eventos tenham muitos benefícios, eles sofrem de duas desvantagens principais em relação aos sistemas vectorizados mais simples. Em primeiro lugar, eles são significativamente mais complexos para implementar e testar. Há 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 por teste, podem ser empregados.
Em segundo lugar, eles são mais lentos para serem executados em comparação com um sistema vectorizado. Operações vectorizadas ótimas não podem ser utilizadas ao realizar cálculos matemáticos. Discutiremos formas de superar essas limitações em artigos posteriores.
Resumo do Backtester com Drivers de Eventos.
Para aplicar uma abordagem orientada a eventos para um sistema de teste posterior, é necessário definir nossos componentes (ou objetos) que irão lidar com tarefas específicas:
Evento - O evento é a unidade de classe fundamental do sistema de eventos. Ele contém um tipo (como "MERCADO", "SINAL", "ORDEM" ou "ENCHIMENTO") que determina como ele será tratado dentro do ciclo do evento. Fila de eventos - A fila de eventos é um objeto de fila Python na memória que armazena todos os objetos de subclasse do evento que são gerados pelo resto do software. DataHandler - O DataHandler é uma classe base abstrata (ABC) que apresenta uma interface para lidar com dados de mercado históricos ou ao vivo. Isso proporciona uma flexibilidade significativa, pois os módulos da Estratégia e do portfólio podem ser reutilizados entre ambas as abordagens. O DataHandler gera um novo MarketEvent em cada batimento cardíaco do sistema (veja abaixo). Estratégia - A Estratégia também é um ABC que apresenta uma interface para tirar dados do mercado e gerar SignalEvents correspondentes, que são, em última instância, utilizados pelo objeto Portfolio. Um SignalEvent contém um símbolo de ticker, uma direção (LONG ou SHORT) e um timestamp. Portfolio - Este é um ABC que lida com o gerenciamento de pedidos associado a posições atuais e posteriores para uma estratégia. Ele também realiza gerenciamento de riscos em todo o portfólio, incluindo exposição do setor e dimensionamento de posição. Em uma implementação mais sofisticada, isso pode ser delegado a uma classe RiskManagement. O Portfolio leva SignalEvents da fila e gera OrderEvents que são adicionados à fila. ExecutionHandler - ExecutionHandler simula uma conexão com uma corretora. O trabalho do manipulador é levar 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. Uma vez que as ordens são executadas, o manipulador cria FillEvents, que descreve o que realmente foi negociado, incluindo taxas, comissão e derrapagem (se modelado). O Loop - Todos esses componentes estão envolvidos em um loop de eventos que lida corretamente com todos os tipos de eventos, roteando-os para o componente apropriado.
Este é um modelo bastante básico de um mecanismo comercial. Existe um margem de manobra significativa para a expansão, particularmente no que diz respeito ao uso do portfólio. Além disso, os diferentes modelos de custos de transações também podem ser abstraídos em sua própria hierarquia de classes. Nesta fase, introduz uma complexidade desnecessária nesta série de artigos, então não discutiremos mais sobre isso. Em tutoriais posteriores, provavelmente expandiremos o sistema para incluir realismo adicional.
Aqui está um trecho do código Python que demonstra como o backtester funciona na prática. Existem dois loops no código. O loop externo é usado para dar ao backtester um batimento cardíaco. Para negociação ao vivo, esta é a frequência na qual novos dados de mercado são consultados. Para estratégias de backtesting, isso não é estritamente necessário, pois o backtester usa os dados de mercado fornecidos no formulário de 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, posteriormente, novos eventos são adicionados à fila. Quando a fila de eventos está vazia, o ciclo de pulsação continua:
Este é o esboço básico de uma forma como um backtester dirigido por eventos foi projetado. No próximo artigo, discutiremos a hierarquia da classe Event.
Apenas iniciando o comércio quantitativo?
3 razões para se inscrever para a lista de e-mails QuantStart:
1. Quant Trading Lessons.
Você terá acesso instantâneo a um curso de e-mail gratuito de 10 partes, repleto de sugestões e dicas para ajudá-lo a começar a negociação quantitativa!
2. Todo o conteúdo mais recente.
Todas as semanas, vou enviar-lhe um envoltório de todas as atividades no QuantStart para que você nunca mais perca uma postagem novamente.
Real, dicas de negociação viáveis, sem tonturas.
Forex backtesting python
Solicitações de envio 11.
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 QSForex é uma plataforma de negociação de backtesting e de negociação aberta de código aberto para uso nos mercados cambiais ("forex"), atualmente em um estado "alfa".
Ele foi criado como parte da série Forex Trading Diary no QuantStart para fornecer à comunidade comercial sistemática um motor de negociação robusto que permite a implementação e o teste direto da estratégia forex.
O software é fornecido sob uma licença permissiva "MIT" (veja abaixo).
Open-Source - QSForex foi lançado sob uma Licença MIT de código aberto extremamente permissiva, que permite o uso total em aplicativos comerciais e de pesquisa, sem restrições, mas sem garantia de qualquer tipo. Grátis - QSForex é completamente 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. Todos os erros são rapidamente determinados e corrigidos. Desenvolvimento de Software - QSForex está escrito na linguagem de programação Python para suporte direto à plataforma cruzada. QSForex contém um conjunto de testes unitários para a maioria do seu código de cálculo e novos testes são constantemente adicionados para novos recursos. Arquitetura dirigida a eventos - O QSForex é completamente conduzido por eventos tanto para backtesting quanto para negociação ao vivo, o que leva a uma 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 testadas anteriormente. Backtesting - QSForex possui backtesting de vários dias de multi-moeda multi-dia intradía. Negociação - O QSForex atualmente oferece suporte à negociação intradiária ao vivo usando a OANDA Brokerage API em um portfólio de pares. Métricas de desempenho - O QSForex atualmente oferece suporte a medição básica de desempenho 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, que você precisará realizar uma negociação ao vivo. Eu explico como realizar isso neste artigo: quantstart / articles / Forex-Trading-Diary-1-Automated-Forex-Trading-with-the-OANDA-API.
Clonar 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. Alternativa, você pode baixar o arquivo zip do ramo mestre atual no 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. Alternativamente, você pode "codificar" suas configurações específicas substituindo as chamadas os. environ. get (.) Por cada configuração:
Isso criará um novo ambiente virtual para instalar os pacotes. Supondo que você baixou o repositório QSForex git em um diretório de exemplo, como.
/ projects / qsforex / (altere este diretório abaixo para onde você instalou QSForex), então, para instalar os pacotes, você precisará executar os seguintes comandos:
Isso levará algum tempo, como NumPy, SciPy, Pandas, Scikit-Learn e Matplotlib devem ser compilados. Há muitos pacotes necessários para que isso funcione, então por favor dê uma olhada nestes dois artigos para obter mais informações:
Você também precisará criar um link simbólico do seu diretório de pacotes do site para seu diretório de instalação QSForex para poder chamar importar qsforex dentro do código. Para fazer isso, você precisará de um comando semelhante ao seguinte:
Certifique-se de mudar.
/ projects / qsforex para o diretório de instalação e.
/venv/qsforex/lib/python2.7/site-packages/ para o seu diretório de pacotes do site virtualenv.
Agora você poderá executar os comandos subseqüentes corretamente.
Nesta fase, se você simplesmente deseja realizar práticas ou negociação ao vivo, você pode executar o 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 cada 5 vezes. É puramente para testar - não use isso em um ambiente de comércio ao vivo!
Se você deseja criar uma estratégia mais útil, basta criar uma nova classe com um nome descritivo, por exemplo, MeanReversionMultiPairStrategy e assegure-se de que ele tenha um método de calcule_signals. Você precisará passar esta classe a lista de pares, bem como a fila de eventos, como em trading / trading. py.
Por favor, consulte Strategy / Strategy. py para obter detalhes.
Para realizar qualquer backtesting, é necessário gerar dados de Forex simulados ou baixar dados de ticks históricos. Se você deseja 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 por QSForex é o mesmo que o fornecido pelo DukasCopy Historical Data Feed em dukascopy / swiss / english / marketwatch / historical /.
Para gerar alguns dados históricos, verifique se a configuração CSV_DATA_DIR na settings. py é configurar para um diretório onde deseja que os dados históricos sejam exibidos. Você então precisa gerar generate_simulated_pair. py, que está no diretório / script. Ele espera um único argumento de linha de comando, que neste caso é o par de moedas no formato BBBQQQ. Por exemplo:
Nesta fase, o script é codificado para criar dados de um único mês para janeiro de 2017. Ou seja, você verá arquivos individuais, do formato BBBQQQ_YYYYMMDD. csv (por exemplo, GBPUSD_20170112.csv) aparecem em seu CSV_DATA_DIR para todos os dias úteis nesse mês. Se você deseja alterar o mês / ano da saída de dados, simplesmente modifique o arquivo e re-execute.
Agora que os dados históricos foram gerados, é possível realizar um backtest. O arquivo backtest em si é armazenado no backtest / backtest. py, mas isso contém apenas a classe Backtest. Para realmente executar um backtest, você precisa instanciar esta classe e fornecer os módulos necessários.
A melhor maneira de ver como isso é feito é olhar para o exemplo de Implementação de Crossover em Moving Average no arquivo examples / mac. py e usá-lo como um modelo. Isso faz uso do MovingAverageCrossStrategy que é encontrado em strategy / strategy. py. Este padrão é negociar GBP / USD e EUR / USD para demonstrar uso de par de moedas múltiplas. Ele usa dados encontrados em CSV_DATA_DIR.
Para executar o exemplo 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, leva cerca de 5-10 minutos para serem executados. Uma grande parte deste 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 desligado! Deixe-o até a conclusão.
Se você deseja visualizar o desempenho do backtest, você pode simplesmente usar output. py para ver uma curva de equivalência patrimonial, retornos de período (ou seja, tick-to-tick) e uma curva de redução:
E é isso! Nesta fase, você está pronto para começar a criar seus backtests, modificando ou anexando estratégias em strategy / strategy. py e usando dados reais baixados da DukasCopy (dukascopy / swiss / english / marketwatch / historical /).
Se você tiver dúvidas sobre a instalação, então fique à vontade para me enviar um e-mail no mike @ quantstart.
Se você tiver algum erro ou outros problemas que você acha que podem ser devido especificamente à base de código, sinta-se à vontade para abrir um problema Github aqui: github / mhallsmoore / qsforex / issues.
Copyright (c) 2018 Michael Halls-Moore.
A permissão é concedida, gratuitamente, a qualquer pessoa que obtenha uma cópia deste software e dos arquivos de documentação associados (o "Software"), para lidar com o Software sem restrições, incluindo, sem limitação, os direitos de uso, cópia, modificação, mesclagem , publicar, distribuir, sublicenciar e / ou vender cópias do Software e permitir que pessoas a quem o Software seja fornecido, sujeito às seguintes condições:
O aviso de direitos autorais acima e este aviso de permissão devem ser incluídos em todas as cópias ou porções substanciais do Software.
O SOFTWARE É FORNECIDO "NO ESTADO EM QUE SE ENCONTRAM", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, APTIDÃO PARA UM PROPÓSITO ESPECÍFICO E NÃO INFRACÇÃO. EM NENHUMA CIRCUNSTÂNCIA, OS AUTORES OU TITULARES DE DIREITOS AUTORAIS SERÃO RESPONSÁVEIS POR QUALQUER RECLAMAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM AÇÃO DE CONTRATO, DELITO OU DE OUTRA FORMA, DECORRENDO, DESTE OU RELACIONADO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NA PROGRAMAS.
A negociação de câmbio em margem comporta 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ê, bem como para você. Antes de decidir investir em divisas, você deve considerar cuidadosamente seus objetivos de investimento, nível de experiência e apetite de risco. Existe a possibilidade de que você possa sustentar uma perda de algum ou todo seu investimento inicial e, portanto, você não deve investir dinheiro que não pode perder. Você deve estar ciente de todos os riscos associados à negociação cambial e procurar o aconselhamento de um consultor financeiro independente se tiver dúvidas.
&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.
Forex Mecânico.
Negociação no mercado FX usando estratégias mecânicas de negociação.
Backtesting Trading Systems em Python: não é uma escolha muito boa.
O idioma python é extremamente versátil, fácil de usar e conveniente. Não há discussão sobre a versatilidade deste idioma quando se trata da quantidade de tempo que leva para colocar uma idéia utilizável em código. Deseja carregar um arquivo csv? Deseja realizar um cálculo de indicador? Deseja traçar um conjunto de valores? Todas essas coisas podem ser feitas com apenas algumas linhas de código em python, enquanto certamente levaria páginas inteiras, senão milhares de linhas, para fazer as mesmas coisas em idiomas como C e Fortran. No entanto, o python possui várias fraquezas que tornam uma escolha fraca quando se trata de testar as estratégias de negociação, particularmente quando se trata de testes baseados em eventos. Nesta publicação, abordarei as diferentes coisas que fazem da Python uma má escolha para codificar os mecanismos de teste de back-ups e por que? apesar do tempo de codificação muito maior & # 8211; os benefícios de usar uma linguagem de nível mais baixo, provavelmente, superam os problemas para certos tipos de testes. Para executar o teste abaixo, baixe o código aqui.
Em geral, é importante entender que existem 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 back-tests baseados em vetores, você calcula vetores que representam decisões de negociação e você faz operações vetoriais para extrair o desempenho dessas variáveis. Digamos que você deseja testar uma estratégia de cross-over média móvel do modo vetorial, você primeiro calcula um vetor com todos os valores médios móveis, então você cria um segundo vetor que contém um booleano com a média móvel maior ou menor do que preço, você usa esses valores para calcular um vetor que represente equidade de acordo com onde você possui sinais, etc. O teste baseado em vetor em geral faz tudo ao calcular vetores e esses vetores são usados para gerar os resultados dos testes. É uma maneira matematicamente eficiente de realizar back-testing de certos tipos de sistemas.
Há, no entanto, muitas desvantagens na utilização de testes baseados em vetores (o que deixarei para discutir em uma publicação futura), o que leva muitas pessoas à alternativa, que são testes baseados em eventos. No caso de back-testing baseado em eventos, você envia os dados de negociação disponíveis e você passa o seu algoritmo todas as informações que ele tem disponíveis em cada ponto do tempo. Esta é a maneira de fazer back-testing que mais se aproxima da execução real do mercado porque sua estratégia está fazendo exatamente a mesma coisa, ele está recebendo dados e tomando decisões em cada unidade de tempo quando é necessário. Por este motivo, os testes baseados no evento podem testar todas as estratégias que podem ser negociadas no mercado e os algoritmos codificados para testes baseados em eventos geralmente podem ser usados sem modificações no comércio ao vivo, porque a mecânica é simplesmente a mesma. No caso de back-testing baseado em eventos, você faz uma corrida simulada explícita de sua estratégia através de seus dados como sua estratégia teria feito em negociação ao vivo (ou pelo menos tão perto quanto você pode gerenciar).
Se você quiser codificar um mecanismo de teste de retorno baseado em eventos no Python, você enfrentará alguns problemas sérios devido à natureza de Python & # 8217; s. Você pode ter decidido usar o Python porque a codificação dentro deste idioma é muito fácil, mas em breve você descobrirá que isso vem em um ótimo custo. Se você quiser realizar um exercício de teste de carregamento de dados simples mais baseado em eventos, você provavelmente usará algum código como o mostrado no exemplo acima. Este exemplo carrega dados de um arquivo chamado TEST_60.csv (30 anos, gerado aleatoriamente 1H) e, em seguida, executa um loop simples através de todo o quadro de dados de pandas para calcular o alcance 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 banco de dados de pandas & # 8211; principalmente devido à análise da data & # 8211; e depois vários minutos para executar o exercício looping. É extremamente lento percorrer um quadro de dados de pandas porque as 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 nas 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 do looping através de uma lista de python simples, porque essas bibliotecas possuem funções bastante ineficientes para acessar elementos únicos em seus objetos porque este tipo de operação não é para o qual as bibliotecas foram projetadas. Os quadros de dados de pandas e as matrizes numpy não devem ser iterados, eles devem ser usados para executar operações baseadas em vetores (ou seja, o & # 8220; pythonic & # 8221; coisa a fazer). Você pode executar alguns testes e ver o quanto seu tempo muda quando você altera a função usada para acessar os valores dentro do quadro de dados do pandas, se você mudar de ix para iat ou iloc, você notará algumas diferenças importantes nos tempos de execução (veja aqui para mais informações 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 economizado, mas se você estiver fazendo back-testing baseado em eventos, você nunca terá algo rápido o suficiente.
O custo de executar este tipo de looping em python torna o idioma praticamente inútil para qualquer projeto de back-testing de grande escala que exija testes baseados em eventos. O ciclo de barra 1H codificado acima leva vários minutos para executar e não é mesmo fazendo cálculos altamente exigentes, nem sequer rastreia equidade, negocia ou faz qualquer geração de sinal. Isso é tudo porque o looping através de objetos de pandas é tremendamente lento. Claro, poderíamos torná-lo mais rápido se não usássemos pandas por isso ou se usássemos ctypes, mas então você está se movendo para o território de linguagens de baixo nível já. Você está desistindo de algo que é tremendamente amigável para codificar com (pandas) para algo que é mais rápido (ctypes). Se você está disposto a aumentar seu tempo de codificação para ganhar velocidade, então você está melhor simplesmente indo para um idioma de nível inferior. Se você gastar 10 vezes o tempo fazendo o código python mais rápido, então, apenas gaste esse tempo codificando 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 o python no back-testing (depois de tudo, codificamos uma biblioteca de análise de séries temporais de código aberto em python chamado qqpat). Você pode executar testes baseados em vetores simples um pouco rápidos usando este idioma e se você está disposto a desistir das bibliotecas mais fáceis de usar, você provavelmente pode codificar algo muito mais rápido usando ctypes e acelerá-lo ainda mais usando algo como pypy . No entanto, o melhor uso que eu encontrei para o python é realmente usá-lo como um frontend para bibliotecas de back-testing muito mais rápidas codificadas em C / C ++. Em nossa comunidade, usamos o Python para fazer coisas como configurações de carga, gerar gráficos e carregar arquivos csv, enquanto uma biblioteca C muito mais eficiente executa os testes baseados no evento real. Fazendo isso, podemos realizar testes de tempo inteiros de 30 anos nas barras de 1H em questão de segundos enquanto faz isso em Python, usando bibliotecas fáceis de usar, como os pandas, provavelmente tomarão 100 vezes o tempo, se não mais. Não é um mistério, então, por que simplesmente existem programas de teste de back-up baseados em eventos comerciais que usam o Python, não é simplesmente um corte de idioma para este trabalho.
Se você quiser saber mais sobre back-testing e como você também pode codificar e testar estratégias usando nosso framework de programação C / C ++, considere se juntar a 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 e # 8221;
Eu acho que alguns ajustes menores ao seu código resultarão em uma aceleração significativa e, em última instância, tornarão Python um pouco mais aceitável.
1) a impressão é bastante dispendiosa. Se você quiser imprimir os dados contidos no intervalo médio em intervalos específicos, você pode fazê-lo depois de preenchê-lo.
2) Considere pré-atribuir uma matriz NumPy vazia:
& 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 ao tempo de execução total de 0,033 seg no dual Intel Xeon E5-2620 & # 8217; s. I & # 8217; m em IPython de 64 bits usando NumPy 1.10 e Pandas 0.17.1, para o que vale a pena.
Obrigado por publicar! Realmente boa melhoria, claramente a função de impressão foi apenas para fins ilustrativos (eu só queria que os usuários vejam o que a função estava fazendo), mas bom trabalho na redução do tempo ao pré-alocar a matriz numpy. Claro que existem todos os tipos de coisas que você pode fazer para tornar o código mais rápido em Python & # 8212; Definitivamente, não estou dizendo que não pode ser feito, especialmente em casos específicos como este. No entanto, acredito que ainda existe um ponto válido para obter um desempenho aceitável em Python, você precisa desistir de uma boa parte da amizade de codificação & # 8220; & # 8221; Isso faz com que seja uma linguagem tão atraente para começar. Quando o seu código se torna realmente complexo & # 8211; como se você quisesse aprender a máquina e # 8211; modificações como a que você publicou tornam-se cada vez mais difíceis de conseguir. No final, para chegar a tempos de execução como os de C / C ++, você pode acabar gastando tempo como se estivesse codificando nesses idiomas de nível inferior.
O que você acha? Você acredita que este é o caso? Você acha que sempre há uma otimização acessível que pode fazer com que um código de python atinja um C / C ++ como desempenho sem muito esforço? Alguma dicas de python que você gostaria de compartilhar? Claro que não tenho a última palavra em python, então qualquer oculto é definitivamente bem-vindo! Deixe-me saber e agradeço muito pela sua contribuição,
Eu acho que, de maneira geral, se a operação não é vetorializada, ficando mais perto do metal e # 8217; usando o cython (ou algo parecido) será ótimo e você está vivendo no mundo de C / C ++.
Dito isto, eu tenho resultados ótimos usando o Numba (uma biblioteca de compilação just-in-time que joga muito bem com o NumPy) para acelerar ARMA & # 8217; s e outras computações não vetorizadas. Para mais informações, veja:
Existem todos os tipos de customizações e otimizações disponíveis para você, mas simplesmente decorando um loop numérico isolado, por exemplo, com @jit parece ser bem executado na maioria dos casos.
Комментариев нет:
Отправить комментарий