Backtesting estratégias de negociação em python
Pesquise Ambientes de Backtesting em Python com pandas.
Pesquise Ambientes de Backtesting em Python com pandas.
Backtesting é o processo de pesquisa da aplicação de uma ideia de estratégia de negociação aos dados históricos, a fim de verificar o desempenho passado. Em particular, um backtester não garante o desempenho futuro da estratégia. No entanto, eles são um componente essencial do processo de pesquisa de pipeline da estratégia, permitindo que as estratégias sejam filtradas antes de serem colocadas em produção.
Neste artigo (e aqueles que o seguem), um sistema básico de backtesting orientado a objeto escrito em Python será descrito. Este sistema inicial será principalmente um "auxiliar de ensino", usado para demonstrar os diferentes componentes de um sistema de backtesting. À medida que avançamos nos artigos, funcionalidades mais sofisticadas serão adicionadas.
Visão geral do backtesting.
O processo de projetar um sistema de backtesting robusto é extremamente difícil. Simular efetivamente todos os componentes que afetam o desempenho de um sistema de negociação algorítmica é um desafio. Pouca granularidade de dados, opacidade de roteamento de ordens em um corretor, latência de pedidos e uma miríade de outros fatores conspiram para alterar o desempenho "verdadeiro" de uma estratégia versus o desempenho de backtested.
Ao desenvolver um sistema de backtesting, é tentador querer constantemente "reescrevê-lo do zero", já que mais fatores são considerados cruciais na avaliação do desempenho. Nenhum sistema de backtesting é concluído e um julgamento deve ser feito em um ponto durante o desenvolvimento que fatores suficientes foram capturados pelo sistema.
Com essas preocupações em mente, o backtester apresentado aqui será um pouco simplista. À medida que exploramos outras questões (otimização de portfólio, gerenciamento de riscos, manipulação de custos de transação), o backtester se tornará mais robusto.
Tipos de sistemas de backtesting.
Geralmente, existem dois tipos de sistema de backtesting que serão de interesse. O primeiro é baseado em pesquisa, usado principalmente nos estágios iniciais, onde muitas estratégias serão testadas para selecionar aquelas para uma avaliação mais séria. Esses sistemas de backtesting de pesquisa são frequentemente escritos em Python, R ou MatLab, já que a velocidade de desenvolvimento é mais importante do que a velocidade de execução nesta fase.
O segundo tipo de sistema de backtesting é baseado em eventos. Ou seja, ele realiza o processo de backtesting em um loop de execução semelhante (se não idêntico) ao próprio sistema de execução de negociação. Ele irá modelar de forma realista os dados de mercado e o processo de execução de ordens, a fim de fornecer uma avaliação mais rigorosa de uma estratégia.
Os últimos sistemas geralmente são escritos em uma linguagem de alto desempenho, como C ++ ou Java, em que a velocidade de execução é essencial. Para estratégias de frequência mais baixa (embora ainda intradiário), o Python é mais que suficiente para ser usado neste contexto.
Backtester de pesquisa orientada a objeto em Python.
O projeto e a implementação de um ambiente de backtesting baseado em pesquisa orientado a objeto serão agora discutidos. A orientação a objetos foi escolhida como o paradigma de design de software pelos seguintes motivos:
As interfaces de cada componente podem ser especificadas antecipadamente, enquanto as partes internas de cada componente podem ser modificadas (ou substituídas) à medida que o projeto progride Ao especificar as interfaces antecipadamente, é possível testar efetivamente como cada componente se comporta (por meio de testes de unidade). Os novos componentes do sistema podem ser construídos ou em adição a outros, seja por herança ou composição.
Nesta fase, o backtester é projetado para facilidade de implementação e um grau razoável de flexibilidade, em detrimento da verdadeira precisão do mercado. Em particular, este backtester só será capaz de lidar com estratégias que atuam em um único instrumento. Posteriormente, o backtester será modificado para lidar com conjuntos de instrumentos. Para o backtester inicial, os seguintes componentes são necessários:
Estratégia - Uma classe Strategy recebe um Pandas DataFrame de barras, ou seja, uma lista de pontos de dados Open-High-Low-Close-Volume (OHLCV) em uma frequência específica. A Estratégia produzirá uma lista de sinais, que consistem em um registro de data e hora e um elemento do conjunto $ \ $ indicando um sinal longo, retido ou curto, respectivamente. Portfólio - A maior parte do trabalho de backtesting ocorrerá na classe Portfolio. Ele receberá um conjunto de sinais (conforme descrito acima) e criará uma série de posições, alocadas em um componente em dinheiro. O trabalho do objeto Portfolio é produzir uma curva de capital, incorporar os custos básicos de transação e acompanhar os negócios. Desempenho - O objeto Performance pega um portfólio e produz um conjunto de estatísticas sobre seu desempenho. Em particular, ele produzirá características de risco / retorno (Sharpe, Sortino e Proporções de Informações), métricas de comércio / lucro e informações de rebaixamento.
O que está a faltar?
Como pode ser visto, esse backtester não inclui nenhuma referência ao gerenciamento de portfólio / risco, manuseio de execução (ou seja, sem ordens de limite) nem fornecerá modelagem sofisticada dos custos de transação. Isso não é muito problemático neste estágio. Isso nos permite ganhar familiaridade com o processo de criação de um backtester orientado a objetos e as bibliotecas Pandas / NumPy. Com o tempo, será melhorado.
Implementação.
Vamos agora proceder para delinear as implementações para cada objeto.
O objeto Strategy deve ser bastante genérico neste estágio, já que ele estará lidando com estratégias de previsão, reversão à média, momentum e volatilidade. As estratégias que estão sendo consideradas aqui serão sempre baseadas em séries temporais, ou seja, "orientadas pelo preço". Um requisito inicial para esse backtester é que as classes Strategy derivadas aceitarão uma lista de barras (OHLCV) como entrada, em vez de ticks (preços de trade-by-trade) ou dados de pedidos. Assim, a melhor granularidade considerada aqui será de 1 segundo.
A classe Strategy também sempre produzirá recomendações de sinal. Isso significa que ele irá aconselhar uma instância do portfólio no sentido de ir longo / curto ou manter uma posição. Essa flexibilidade nos permitirá criar vários "consultores" de estratégia que fornecem um conjunto de sinais, que uma classe de portfólio mais avançada pode aceitar para determinar as posições reais que estão sendo inseridas.
A interface das classes será aplicada utilizando uma metodologia de classe base abstrata. Uma classe base abstrata é um objeto que não pode ser instanciado e, portanto, somente classes derivadas podem ser criadas. O código Python é dado abaixo em um arquivo chamado backtest. py. A classe Strategy requer que qualquer subclasse implemente o método generate_signals.
Para evitar que a classe Strategy seja instanciada diretamente (já que é abstrata!), É necessário usar os objetos ABCMeta e abstractmethod do módulo abc. Nós definimos uma propriedade da classe, chamada __metaclass__, para ser igual a ABCMeta e depois decoramos o método generate_signals com o decorador abstractmethod.
Embora a interface acima seja simples, ela se tornará mais complicada quando essa classe for herdada para cada tipo específico de estratégia. Em última análise, o objetivo da classe Strategy nesta configuração é fornecer uma lista de sinais long / short / hold para cada instrumento a ser enviado para um Portfólio.
A classe Portfolio é onde a maioria da lógica de negociação residirá. Para este backtester de pesquisa, a Carteira é responsável por determinar o tamanho da posição, a análise de risco, a gestão dos custos de transação e o processamento da execução (ou seja, ordens de mercado em aberto e de fecho de mercado). Posteriormente, essas tarefas serão divididas em componentes separados. No momento, eles serão encaminhados para uma aula.
Esta classe faz amplo uso de pandas e fornece um ótimo exemplo de onde a biblioteca pode economizar uma enorme quantidade de tempo, particularmente no que diz respeito a disputas de dados "clichê". Como um aparte, o principal truque com pandas e NumPy é evitar iterar sobre qualquer conjunto de dados usando o for d in. sintaxe. Isso ocorre porque o NumPy (que sustenta os pandas) otimiza o loop por operações vetorizadas. Assim, você verá poucas iterações diretas (se houver alguma) ao utilizar pandas.
O objetivo da classe Portfolio é, em última análise, produzir uma sequência de negociações e uma curva de capital, que será analisada pela classe Performance. Para conseguir isso, deve ser fornecida uma lista de recomendações de negociação de um objeto Strategy. Mais tarde, este será um grupo de objetos Strategy.
A classe Portfolio precisará ser informada sobre como o capital deve ser implantado para um determinado conjunto de sinais de negociação, como lidar com custos de transação e quais formulários de ordens serão utilizados. O objeto Estratégia está operando em barras de dados e, portanto, as premissas devem ser feitas em relação aos preços alcançados na execução de um pedido. Como o preço alto / baixo de qualquer barra é desconhecido a priori, só é possível usar os preços de abertura e fechamento para negociação. Na realidade, é impossível garantir que uma encomenda seja preenchida a um desses preços específicos quando se utiliza uma ordem de mercado, pelo que será, na melhor das hipóteses, uma aproximação.
Além das suposições sobre pedidos sendo preenchidos, este backtester irá ignorar todos os conceitos de restrições de margem / corretagem e assumirá que é possível ir de forma longa e curta em qualquer instrumento livremente, sem quaisquer restrições de liquidez. Isto é claramente uma suposição muito irrealista, mas é algo que pode ser relaxado mais tarde.
A listagem a seguir continua backtest. py:
Nesta fase, as classes base abstratas de Strategy e Portfolio foram introduzidas. Estamos agora em posição de gerar algumas implementações derivadas concretas dessas classes, a fim de produzir uma "estratégia de brinquedo" funcional.
Começaremos gerando uma subclasse de Estratégia chamada RandomForecastStrategy, cuja única tarefa é produzir sinais longos / curtos escolhidos aleatoriamente! Embora esta seja claramente uma estratégia comercial absurda, ela atenderá às nossas necessidades demonstrando a estrutura de backtesting orientada a objeto. Assim, iniciaremos um novo arquivo chamado random_forecast. py, com a listagem do preditor aleatório, da seguinte maneira:
Agora que temos um sistema de previsão "concreto", devemos criar uma implementação de um objeto Portfolio. Este objeto irá abranger a maioria do código de backtesting. Ele é projetado para criar dois DataFrames separados, o primeiro dos quais é um quadro de posições, usado para armazenar a quantidade de cada instrumento contido em qualquer barra específica. A segunda carteira, na verdade, contém o preço de mercado de todas as participações de cada barra, bem como uma contagem do dinheiro, assumindo um capital inicial. Isso acaba por fornecer uma curva de capital para avaliar o desempenho da estratégia.
O objeto Portfolio, embora extremamente flexível em sua interface, requer escolhas específicas quando se trata de como lidar com custos de transação, ordens de mercado, etc. Neste exemplo básico, considerei que seria possível usar um instrumento muito fácil, sem restrições ou margem, comprar ou vender diretamente ao preço de abertura da barra, custos de transação zero (englobando derrapagem, taxas e impacto no mercado) e especificando a quantidade de estoque diretamente para comprar para cada negociação.
Esta é a continuação da listagem random_forecast. py:
Isso nos dá tudo o que precisamos para gerar uma curva de capital baseada em tal sistema. O passo final é amarrar tudo junto com uma função __main__:
A saída do programa é a seguinte. A sua será diferente da saída abaixo, dependendo do período selecionado e da semente aleatória usada:
Neste caso, a estratégia perdeu dinheiro, o que não é surpreendente, dada a natureza estocástica do previsor! As próximas etapas são criar um objeto Performance que aceite uma instância de portfólio e forneça uma lista de métricas de desempenho sobre as quais basear uma decisão para filtrar a estratégia ou não.
Também podemos melhorar o objeto Portfolio para ter um tratamento mais realista dos custos de transação (como comissões e slippage do Interactive Brokers). Também podemos incluir diretamente um mecanismo de previsão em um objeto Strategy, que (esperançosamente) produzirá melhores resultados. Nos artigos a seguir, exploraremos esses conceitos com mais profundidade.
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.
Backtesting Systematic Trading Strategies em Python: Considerações e Open Source Frameworks.
Backtesting Systematic Trading Strategies em Python: Considerações e Open Source Frameworks.
Neste artigo, Frank Smietana, um dos colaboradores convidados especializados da QuantStart, descreve o cenário de software de backtesting de código aberto Python e fornece conselhos sobre qual framework de backtesting é adequado para as necessidades de seu próprio projeto.
O backtesting é, sem dúvida, a parte mais crítica do processo de produção da SST (Estratégia de Negociação Sistemática), situada entre o desenvolvimento e a implementação da estratégia (negociação ao vivo). Se uma estratégia é falha, espera-se que um backtesting rigoroso exponha isso, impedindo que uma estratégia deficitária seja implantada.
Vários recursos relacionados se sobrepõem ao backtesting, incluindo simulação comercial e negociação ao vivo. O backtesting usa dados históricos para quantificar o desempenho do STS. Os simuladores de negociação levam o backtesting um passo adiante, visualizando o desencadeamento de negociações e o desempenho de preços em uma base barra a barra. A negociação simulada / ao vivo implanta um STS testado em tempo real: sinalizando negociações, gerando ordens, roteando ordens para corretores e mantendo posições conforme as ordens são executadas.
A maioria dos frameworks vai além do backtesting para incluir alguns recursos de negociação ao vivo. Isso é conveniente se você quiser implantar a partir de sua estrutura de backtesting, que também funciona com seu corretor e fontes de dados preferidos. O Quantopian / Zipline dá um passo adiante, fornecendo uma solução totalmente integrada de desenvolvimento, backtesting e implantação.
A comunidade Python está bem atendida, com pelo menos seis estruturas de backtesting de código aberto disponíveis. Eles estão, no entanto, em vários estágios de desenvolvimento e documentação. Se você gosta de trabalhar em uma equipe criando uma estrutura de backtesting de código aberto, confira os repositórios do Github.
Antes de avaliar as estruturas de backtesting, vale a pena definir os requisitos do seu STS.
Qual (is) classe (s) de ativos você está negociando? Enquanto a maioria dos frameworks suportam dados de Ações dos EUA via YahooFinance, se uma estratégia incorpora derivativos, ETFs ou títulos de EM, os dados precisam ser importados ou fornecidos pela estrutura. As coberturas de classes de ativos vão além dos dados. O framework pode lidar com futuros e opções de tamanho finito e gerar transações roll-over automaticamente? E quanto aos mercados sem liquidez, quão realista uma suposição deve ser feita ao executar grandes pedidos?
Qual freqüência de dados e detalhes seu STS é construído? Um sistema de negociação que exige cada tick ou lance / pedido tem um conjunto muito diferente de problemas de gerenciamento de dados que um intervalo de 5 minutos ou de hora em hora. Os fundos de hedge e as lojas HFT investiram significativamente na criação de estruturas de backtesting robustas e escalonáveis para lidar com esse volume e frequência de dados. Algumas plataformas fornecem um conjunto rico e profundo de dados para várias classes de ativos, como ações da S & P, com resolução de um minuto.
Que tipo (s) de pedido exige o seu STS? No mínimo, limite, paradas e OCO devem ser suportados pelo framework.
Nível de suporte & amp; documentação necessária. Os frameworks de estágio inicial têm escassa documentação, poucos têm suporte além de conselhos comunitários.
Os componentes de um framework de backtesting.
Aquisição de dados e STS: Os componentes de aquisição consomem o arquivo de script / definição STS e fornecem os dados necessários para o teste. Se a estrutura exigir que qualquer STS seja recodificado antes do backtesting, a estrutura deverá suportar funções enlatadas para os indicadores técnicos mais populares para acelerar o teste de STS. Os usuários determinam quanto tempo um período histórico será backtest com base no que o framework fornece ou no que eles são capazes de importar.
O teste de desempenho aplica a lógica STS à janela de dados históricos solicitada e calcula uma ampla gama de riscos & amp; métricas de desempenho, incluindo redução máxima, taxas de Sharpe e Sortino. A maioria das estruturas suporta um número decente de recursos de visualização, incluindo curvas de equidade e estatísticas decifradas.
A otimização tende a exigir a maior parte dos recursos de computação no processo STS. Se o seu STS exigir otimização, concentre-se em uma estrutura que suporte o processamento distribuído / paralelo escalável.
No contexto de estratégias desenvolvidas usando indicadores técnicos, os desenvolvedores de sistemas tentam encontrar um conjunto ideal de parâmetros para cada indicador. Mais simplesmente, a otimização pode achar que um STS crossover médio de 6 e 10 dias acumulou mais lucro sobre os dados de teste históricos do que qualquer outra combinação de períodos de tempo entre 1 e 20. Já com este exemplo trivial, 20 * 20 = 400 combinações de parâmetros ser calculado & amp; classificado.
Em um contexto de portfólio, a otimização busca encontrar a ponderação ideal de todos os ativos do portfólio, incluindo instrumentos em curto e alavancados. Periodicamente, a carteira é reequilibrada, resultando na compra e venda de participações de carteira conforme necessário para alinhar com os pesos otimizados.
O dimensionamento de posição é um uso adicional de otimização, ajudando os desenvolvedores de sistemas a simular e analisar o impacto da alavancagem e o dimensionamento dinâmico da posição no STS e no desempenho do portfólio.
Seis Quadros de Backtesting para Python.
Os recursos padrão das plataformas de backtesting de Python de código aberto parecem incluir:
Evento orientado Licenciamento muito flexível e irrestrito Coleção decente de indicadores técnicos predefinidos Capacidades de cálculo / visualização / relatório de métricas de desempenho padrão.
PyAlgoTrade.
O PyAlgoTrade é uma estrutura de backtesting mutuamente documentada, juntamente com recursos de negociação em papel e ao vivo. O suporte de dados inclui o Yahoo! Finanças, Google Finance, NinjaTrader e qualquer tipo de série temporal baseada em CSV, como o Quandl. Tipos de pedidos suportados incluem Market, Limit, Stop e StopLimit.
O PyAlgoTrade suporta negociação Bitcoin via Bitstamp, e manipulação de eventos do Twitter em tempo real.
bt - Backtesting para Python.
bt “visa fomentar a criação de blocos facilmente testáveis, reutilizáveis e flexíveis de lógica estratégica para facilitar o rápido desenvolvimento de estratégias de negociação complexas”.
A estrutura é particularmente adequada para testar o STS baseado em portfólio, com algos para ponderação de ativos e reequilíbrio de portfólio. Modificar uma estratégia para executar diferentes frequências de tempo ou pesos de ativos alternativos envolve um ajuste de código mínimo. bt é construído sobre o ffn - uma biblioteca de funções financeiras para Python.
Backtrader.
Essa plataforma é excepcionalmente bem documentada, com um blog de acompanhamento e uma comunidade on-line ativa para postar perguntas e solicitações de recursos. Backtrader suporta vários formatos de dados, incluindo arquivos CSV, Pandas DataFrames, iteradores de blaze e feeds de dados em tempo real de três corretores. Esses feeds de dados podem ser acessados simultaneamente e podem até representar diferentes períodos de tempo. Corretores suportados incluem Oanda para negociação de FX e negociação de classe de múltiplos ativos via Interactive Brokers e Visual Chart.
pysystemtrade.
O desenvolvedor do pysystemtrade, Rob Carver, tem um ótimo post discutindo por que ele se propôs a criar outro framework de backtesting em Python e os argumentos a favor e contra o desenvolvimento de frameworks. O framework de backtesting para o pysystemtrade é discutido no livro de Rob, "Systematic Trading".
O pysystemtrade lista vários recursos de roteiro, incluindo um testador completo completo que inclui técnicas de otimização e calibração e negociação de futuros totalmente automatizada com a Interactive Brokers. Contribuidores de código aberto são bem-vindos.
Zipline é um simulador de negociação algorítmica com capacidades de negociação em papel e ao vivo. Acessível através da interface IPython Notebook baseada em navegador, o Zipline fornece uma alternativa fácil de usar às ferramentas de linha de comando. Suportado e desenvolvido pela Quantopian, o Zipline pode ser usado como uma estrutura de backtesting autônoma ou como parte de um ambiente de desenvolvimento, teste e implementação de STS completo da Quantipian / Zipline. O Zipline fornece 10 anos de dados de estoque históricos americanos com resolução de minutos e várias opções de importação de dados.
O QSTrader é um framework de backtesting com recursos de negociação ao vivo. O Fundador da QuantStart, Michael Halls-Moore, lançou o QSTrader com o intuito de construir uma plataforma robusta e escalável o suficiente para atender às necessidades dos fundos institucionais de hedge, bem como aos traders quantificados de varejo. O QSTrader atualmente suporta dados de resolução "bar" do OHLCV em várias escalas de tempo, mas permite que dados de ticks sejam usados.
Ambos backtesting e live trading são completamente orientados a eventos, simplificando a transição de estratégias de pesquisa para testes e, finalmente, negociação ao vivo. A estratégia principal / código do portfólio é geralmente idêntica em ambas as implantações.
O principal benefício do QSTrader é a sua modularidade, permitindo uma ampla personalização de código para aqueles que possuem requisitos específicos de gerenciamento de risco ou portfólio.
Abraçando o Backtest.
É da natureza humana concentrar-se na recompensa de desenvolver um (esperançosamente lucrativo) STS, e então se apressar em implantar uma conta financiada (porque estamos esperançosos), sem gastar tempo e recursos suficientes para fazer backtesting da estratégia. Mas o backtesting não é apenas um gatekeeper para nos impedir de implementar estratégias falhas e perder o capital comercial, ele também fornece uma série de diagnósticos que podem informar o processo de desenvolvimento do STS. Por exemplo, testar um STS idêntico em dois períodos de tempo diferentes, compreender o empate máximo de uma estratégia no contexto de correlações de ativos e criar portfólios mais inteligentes, fazendo backtesting de alocações de ativos em várias regiões geográficas.
Em posts futuros, cobriremos backtesting frameworks para ambientes não-Python, e o uso de várias técnicas de sampling como bootstrapping e jackknife para backtesting de modelos preditivos de trading.
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.
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 sozinho 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 o meu tipo favorito 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 por aí é "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 "paralelos embaraçosos" (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 comentários, 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, não poderá culpar este blog aleatório (e / ou eu). Aproveite por sua conta e risco.
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 back-tests baseados em vetores, calcula vetores que representam decisões de negociação e, em seguida, faz operações de vetor 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 retorno baseado em vetor faz tudo através de vetores de cálculo e esses vetores são usados para gerar seus resultados de 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 algoritmos codificados para back-testing baseados 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 sua estratégia teria feito no comércio ao vivo (ou pelo menos o mais próximo 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 a média de 20 bar em cada barra (algo extremamente simples). Fazer este exercício simples leva cerca de 12 a 15 segundos para carregar os dados em um dataframe de 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 não está nem fazendo cálculos altamente exigentes, ele não está nem acompanhando a equidade, negoceia 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 ++, considere juntar-se 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.
Комментарии
Отправить комментарий