Monday 16 April 2018

Estratégia de negociação svm


Aprendizado de máquina: como as máquinas de vetor de suporte podem ser usadas na negociação.


O que é uma máquina de vetor de suporte?


Uma máquina de vetores de suporte é um método de aprendizado de máquina que tenta obter dados de entrada e classificar em uma das duas categorias. Para que uma máquina de vetor de suporte seja efetiva, é necessário primeiro usar um conjunto de dados de entrada e saída de treinamento para construir o modelo de máquina vetorial de suporte que pode ser usado para classificar novos dados.


Uma máquina de vetor de suporte desenvolve esse modelo, levando as entradas de treinamento, mapeando-as para o espaço multidimensional e, em seguida, usando regressão para encontrar um hiperplano (um hiperplano é uma superfície no espaço n-dimensional que separa o espaço em dois meios) que se separa melhor as duas classes de insumos. Uma vez que a máquina de vetores de suporte tenha sido treinada, ela é capaz de avaliar novas entradas em relação ao hiperplano de separação e classificá-lo em uma das duas categorias.


Uma máquina de vetores de suporte é essencialmente uma máquina de entrada / saída. Um usuário é capaz de colocar uma entrada, e com base no modelo desenvolvido através do treinamento, ele retornará uma saída. O número de entradas para qualquer dada máquina de vetores de suporte teoricamente varia de um a infinito, no entanto, em termos práticos, a capacidade de computação limita o número de entradas que podem ser usadas. Se, por exemplo, N entradas são usadas para uma máquina de vetor de suporte particular (o valor inteiro de N pode variar de um para o infinito), a máquina de vetor de suporte deve mapear cada conjunto de entradas em espaço N-dimensional e encontrar um (N-1 ) - hiperplaneamento dimensional que melhor separa os dados de treinamento.


Figura 1. As máquinas de vetor de suporte são máquinas de entrada / saída.


A melhor maneira de conceituar como uma máquina de vetor de suporte funciona é considerando o caso bidimensional. Suponha que queremos criar uma máquina de vetor de suporte que tenha duas entradas e retorna uma única saída que classifique o ponto de dados como pertencente a uma das duas categorias. Podemos visualizar isso, plotando-o em um gráfico bidimensional, como o gráfico abaixo.


Figura 2. Esquerda: Entradas da máquina de vetores de suporte mapeadas para um gráfico 2D. Os círculos vermelhos e as cruzes azuis são usados ​​para denotar as duas classes de entradas.


Figura 3. Direita: Entradas da máquina de vetor de suporte mapeadas para um gráfico 2D. Os círculos vermelhos e os cruzamentos azuis são usados ​​para denotar as duas classes de entradas com uma linha preta indicando o hiperplano separador.


Neste exemplo, os cruzamentos azuis indicam pontos de dados que pertencem à categoria 1 e os círculos vermelhos que representam pontos de dados pertencentes à categoria 2. Cada um dos pontos de dados individuais tem valor exclusivo de entrada 1 (representado por sua posição no eixo x ) e um valor único de entrada 2 (representado por sua posição no eixo y) e todos esses pontos foram mapeados para o espaço bidimensional.


Uma máquina de vetor de suporte é capaz de classificar dados criando um modelo desses pontos no espaço bidimensional. A máquina de vetores de suporte observa os dados no espaço bidimensional e usa um algoritmo de regressão para encontrar um hiperplano de 1 dimensão (também conhecido como linha) que separa com mais precisão os dados em suas duas categorias. Essa linha de separação é então usada pela máquina de vetores de suporte para classificar novos pontos de dados na categoria 1 ou na categoria 2.


A animação abaixo ilustra o processo de treinamento de uma nova máquina vetorial de suporte. O algoritmo começará fazendo uma descoberta aleatória ao encontrar um hiperplano separador, então melhorará iterativamente a precisão do hiperplano. Como você pode ver, o algoritmo começa de forma bastante agressiva, mas depois diminui quando ele começa a se aproximar da solução de desejos.


Figura 4. Uma animação que mostra um treinamento de máquina vetorial de suporte. O hiperplaneiro converge progressivamente na geometria ideal para separar as duas classes de dados.


O cenário bidimensional acima apresentado nos permite visualizar o processo de uma máquina vetorial de suporte, no entanto, ele só é capaz de classificar um ponto de dados usando duas entradas. E se quisermos usar mais entradas? Felizmente, o algoritmo de máquina de vetores de suporte nos permite fazer o mesmo em dimensões mais altas, embora se torne muito mais difícil de conceituar.


Considere isso, você deseja criar uma máquina de vetor de suporte que leva 20 entradas e pode classificar qualquer ponto de dados usando essas entradas para categoria 1 ou categoria 2. Para fazer isso, a máquina de vetores de suporte precisa modelar os dados em espaço de 20 dimensões e use um algoritmo de regressão para encontrar um hiperplano de 19 dimensões que separa os pontos de dados em duas categorias. Isso é extremamente difícil de visualizar, pois é difícil para nós compreender algo acima de 3 dimensões, no entanto, tudo o que você precisa saber é que funciona exatamente da mesma forma que para o caso bidimensional.


Como funcionam as máquinas de suporte de vetores? Exemplo: é um Schnick?


Imagine este cenário hipotético, você é um pesquisador que investiga um animal raro encontrado apenas nas profundezas do Ártico chamado Shnicks. Dado o afastamento destes animais, apenas um pequeno punhado foi encontrado (digamos, cerca de 5000). Como pesquisador, você está preso à questão. Como posso identificar um Schnick?


Tudo o que você tem à sua disposição são os trabalhos de pesquisa publicados anteriormente por um punhado de pesquisadores que viram um. Nestes trabalhos, os autores descrevem certas características sobre os Schnicks que encontraram, ou seja, altura, peso, número de pernas, etc. Mas todas essas características variam entre os trabalhos de pesquisa sem padrão discernível.


Como podemos usar esses dados para identificar um novo animal como um schnick?


Uma possível solução para nosso problema é usar uma máquina de vetores de suporte para identificar os padrões nos dados e criar uma estrutura que possa ser usada para classificar os animais como schnick ou não schnick. O primeiro passo é criar um conjunto de dados que podem ser usados ​​para treinar sua máquina de vetores de suporte para identificar os schnicks. Os dados de treinamento são um conjunto de entradas e saídas correspondentes para a máquina de vetores de suporte para analisar e extrair um padrão.


Portanto, devemos decidir quais entradas serão usadas e quantos. Teoricamente, podemos ter tantas entradas como desejamos, no entanto isso geralmente pode levar a um treinamento lento (quanto mais entradas você tiver, mais tempo demora a máquina de vetor de suporte para extrair padrões). Além disso, você deseja escolher valores de entrada que tenderão a ser relativamente consistentes em todos os schnicks. Por exemplo, altura ou peso do animal seria um bom exemplo de uma contribuição porque você esperaria que isso fosse relativamente consistente em todos os schnicks. No entanto, a idade média de um animal seria uma má escolha de insumo, porque você esperaria que a idade dos animais identificados variaria consideravelmente.


Por esse motivo, as seguintes entradas foram escolhidas:


Altura Peso O número de pernas O número de olhos O ​​comprimento dos braços do animal A velocidade média dos animais A freqüência dos animais que se acasalam chamam.


Com as entradas escolhidas, podemos começar a compilar nossos dados de treinamento. Os dados de treinamento efetivos para uma máquina vetorial de suporte devem atender a certos requisitos:


Os dados devem ter exemplos de animais que são schnicks. Os dados devem ter exemplos de animais que não são schnicks.


Neste caso, temos os documentos de pesquisa do cientista que identificaram com sucesso um schnick e listaram suas propriedades. Portanto, podemos ler esses trabalhos de pesquisa e extrair os dados em cada uma das entradas e alocar uma saída de verdade ou falso para cada um dos exemplos. Os dados de treinamento neste caso podem parecer semelhantes à tabela abaixo.


Tabela 1. Tabela de exemplo de observações schnick.


Uma vez que reunimos os dados para todas as nossas entradas e saídas de treinamento, podemos usá-lo para treinar nossa máquina de vetores de suporte. Durante o processo de treinamento, a máquina de vetor de suporte criará um modelo em espaço de sete dimensões que pode ser usado para classificar cada um dos exemplos de treinamento em verdade ou em falso. A máquina de vetores de suporte continuará a fazer isso até que tenha um modelo que represente com precisão os dados de treinamento (dentro da tolerância de erro especificada). Uma vez que o treinamento está completo, este modelo pode ser usado para classificar novos pontos de dados como verdadeiro ou falso.


A máquina de suporte de vetores realmente funciona?


Usando o cenário de Schnick, escrevi um script que testa o quão bem uma máquina de vetor de suporte pode realmente identificar novos schnicks. Para fazer isso, usei a Biblioteca de funções "Support Vector Machine Learning Tool" que pode ser baixada do Market.


Para modelar este cenário de forma eficaz, precisamos primeiro decidir quais são as propriedades reais de um Schnick. As propriedades que assumi neste caso foram listadas na tabela abaixo. Se um animal satisfaz todos os critérios abaixo, então é um Schnick.


Tabela 2. Resumo dos parâmetros que definem um schnick.


Agora que definimos nosso Schnick, podemos usar essa definição para experimentar com máquinas de vetor de suporte. O primeiro passo é criar uma função que seja capaz de tomar as sete entradas para qualquer animal dado e devolver a classificação real do animal como um schnick ou não. Esta função será usada para gerar dados de treinamento para a máquina de vetores de suporte, bem como para avaliar o desempenho do mesmo no final. Isso pode ser feito usando a função abaixo;


O próximo passo no processo é criar uma função que pode gerar entradas e saídas de treinamento. As entradas neste caso serão geradas criando números aleatórios dentro de um intervalo definido para cada um dos sete valores de entrada. Então, para cada um dos conjuntos de entradas aleatórias geradas, a função isItASchnick () acima será usada para gerar a saída desejada correspondente. Isso é feito na função abaixo:


Agora temos um conjunto de entradas e saídas de treinamento, agora é hora de criar nossas máquinas de vetores de suporte usando a "Ferramenta de Aprendizado de Máquinas de Vector de Suporte" disponível no Mercado. Uma vez criada uma nova máquina de vetores de suporte, é necessário passar as entradas e saídas de treinamento para ela e executar o treinamento.


Agora temos uma máquina de vetor de suporte que foi treinada com sucesso na identificação de Scnhicks. Para verificar isso, podemos testar a máquina de vetores de suporte final pedindo que ela classifique novos pontos de dados. Isso é feito primeiro gerando entradas aleatórias e, em seguida, usando a função isItASchnick () para determinar se essas entradas correspondem a um Schnick real, use a máquina de vetor de suporte para classificar as entradas e determinar se o resultado previsto corresponde ao resultado real. Isso é feito na função abaixo:


Eu recomendo jogar com os valores dentro das funções acima para ver como a máquina de vetores de suporte se comporta sob diferentes condições.


Por que o Support Vector Machine é tão útil?


O benefício de usar uma máquina de vetor de suporte para extrair um padrão complexo dos dados é que não é necessário uma compreensão prévia do comportamento dos dados. Uma máquina de vetor de suporte é capaz de analisar os dados e extrair seus únicos insights e relacionamentos. Desta forma, funciona de forma semelhante a uma caixa preta recebendo entradas e gerando uma saída que pode revelar-se muito útil na busca de padrões nos dados que são muito complexos e não óbvios.


Uma das melhores características das máquinas de vetores de suporte é que elas são capazes de lidar com erros e ruído nos dados muito bem. Muitas vezes, eles são capazes de ver o padrão subjacente dentro dos dados e afastar os outliers de dados e outras complexidades. Considere o seguinte cenário, ao realizar sua pesquisa em Schnicks, você se deparou com vários trabalhos de pesquisa que descrevem Schnicks com características maciçamente diferentes (como um schnick com 200kg e 15000mm de altura).


Erros como esse podem levar a distorções em seu modelo do que é um Schnick, o que poderia fazer com que você cometa um erro ao classificar novas descobertas de Schnick. O benefício da máquina de vetores de suporte é que ela desenvolverá um modelo que esteja de acordo com o padrão subjacente, oposto a um modelo que se encaixa em todos os pontos de dados de treinamento. Isso é feito permitindo-se um certo nível de erro no modelo para permitir que a máquina de vetores de suporte ignore qualquer erro nos dados.


No caso da máquina de vetores de suporte Schnick, se permitirmos uma tolerância de erro de 5%, o treinamento tentará apenas desenvolver um modelo que corresponda a 95% dos dados de treinamento. Isso pode ser útil porque permite que o treinamento ignore a pequena porcentagem de valores esporádicos.


Podemos investigar ainda mais essa propriedade da máquina de vetores de suporte modificando nosso script Schnick. A função abaixo foi adicionada para introduzir erros aleatórios deliberados em nosso conjunto de dados de treinamento. Esta função selecionará pontos de treinamento aleatoriamente e substituirá as entradas e a saída correspondente com variáveis ​​aleatórias.


Esta função nos permite introduzir erros deliberados nos nossos dados de treinamento. Usando esses dados preenchidos por erros, podemos criar e formar uma nova máquina de vetores de suporte e comparar seu desempenho com o original.


Quando o script é executado, ele produz os seguintes resultados no registro de especialistas. Dentro de um conjunto de dados de treinamento com 5000 pontos de treinamento, conseguimos introduzir 500 erros aleatórios. Ao comparar o desempenho dessa máquina de vetores de suporte preenchida por erros com a original, o desempenho é reduzido apenas em & lt; 1%. Isso ocorre porque a máquina de vetor de suporte é capaz de ignorar os outliers no conjunto de dados ao treinar e ainda é capaz de produzir um modelo impressionantemente preciso dos dados verdadeiros. Isso sugere que as máquinas de vetor de suporte poderiam potencialmente ser uma ferramenta mais útil na extração de padrões complexos e insights de conjuntos de dados ruidosos.


Figura 5. O log perito resultante após a execução do script "Schnick" no MetaTrader 5.


Uma versão completa do código acima pode ser baixada do Code Base, entretanto este script só pode ser executado no seu terminal se você comprou uma versão completa da ferramenta Support Vector Machine Learning do Market. Se você tiver apenas uma versão de demonstração desta ferramenta baixada, você estará limitado a usar a ferramenta através do testador de estratégia. Para permitir o teste do código "Schnick" usando a versão demo da ferramenta, reescrevi uma cópia do script em um Expert Advisor que pode ser implantado usando o testador de estratégia. Ambas as versões de código podem ser baixadas seguindo os links abaixo:


Versão Completa - Usando um Script que é implantado no terminal MetaTrader 5 (requer uma versão adquirida da Ferramenta de Aprendizagem de Máquinas de Vetores de Suporte)


Versão de Demonstração - Usando um Expert Advisor que é implementado no testador de estratégia do MetaTrader 5 (requer apenas uma versão demo da Ferramenta de Aprendizado de Máquina de Vetor de Suporte)


Como as máquinas de vetores de suporte podem ser usadas no mercado?


É certo que o exemplo de Schnick discutido acima é bastante simples, no entanto, existem algumas semelhanças que podem ser desenhadas entre este exemplo e o uso de máquinas de vetor de suporte para análises técnicas de mercado.


A análise técnica é fundamentalmente sobre o uso de dados históricos do mercado para prever futuros movimentos de preços. Da mesma forma, dentro do exemplo do schnick, estávamos usando as observações feitas por cientistas do passado para prever se um novo animal é um schnick ou não. Além disso, o mercado está atormentado com ruído, erros e valores atípicos estatísticos que tornam o uso de uma máquina vetorial de suporte um conceito interessante.


A base para um número significativo de abordagens de negociação de análise técnica envolve as seguintes etapas:


Monitorando vários indicadores Identificando quais condições para cada indicador se correlacionam com um comércio potencialmente bem-sucedido Observe cada um dos indicadores e avalie quando todos (ou a maioria) estão sinalizando uma negociação.


É possível adotar uma abordagem semelhante para usar máquinas de vetor de suporte para sinalizar novos negócios de forma semelhante. A ferramenta de aprendizado de máquina de vetor de suporte foi desenvolvida com isso em mente. Uma descrição completa de como usar esta ferramenta pode ser encontrada no Market, então eu só darei uma visão geral rápida. O processo para usar essa ferramenta é o seguinte:


Figura 6. O diagrama de blocos que mostra o processo para implementar a máquina-ferramenta de vetor de suporte em um Expert Advisor.


Antes de poder usar a Ferramenta de Aprendizado de Máquina de Vetor de Suporte, é importante primeiro entender como as entradas e saídas de treinamento são geradas.


Como são geradas Entradas de Treinamento?


Portanto, os indicadores que você deseja usar como entradas já foram inicializados, bem como sua nova máquina de vetores de suporte. O próximo passo é passar as alças de indicadores para a sua nova máquina de vetores de suporte e instruí-lo sobre como gerar os dados de treinamento. Isso é feito chamando a função setIndicatorHandles (). Esta função permite que você passe as alças dos indicadores inicializados para a máquina de vetores de suporte. Isso é feito passando e matriz inteira contendo as alças. As outras duas entradas para esta função são o valor de deslocamento e o número de pontos de dados.


O valor do deslocamento denota o deslocamento entre a barra atual e a barra de partida a ser usada na geração das entradas de treinamento e o número de pontos de treinamento (denotado por N) define o tamanho dos dados de treinamento. O diagrama abaixo ilustra como usar esses valores. Um valor de deslocamento de 4 e um valor N de 6 dirão à máquina de vetor de suporte que use apenas as barras capturadas no quadrado branco para gerar entradas e saídas de treinamento. Da mesma forma, um valor de deslocamento de 8 e um valor N de 8 dirão à máquina de vetor de suporte que use apenas as barras capturadas no quadrado azul para gerar entradas e saídas de treinamento.


Uma vez que a função setIndicatorHandles () foi chamada, é possível chamar a função genInputs (). Essa função usará as alças do indicador para passar para gerar uma matriz de dados de entrada a serem usados ​​para treinamento.


Figura 7. Gráfico de velas que ilustra os valores de Offset e N.


Como são geradas as saídas de treinamento?


Os resultados de treinamento são gerados simulando negociações hipotéticas com base em dados de preços históricos e determinando se tal comércio teria sido bem sucedido ou mal sucedido. Para fazer isso, existem alguns parâmetros que são usados ​​para instruir a ferramenta de aprendizado da máquina de vetor de suporte, como avaliar um comércio hipotético como bem sucedido ou mal sucedido.


A primeira variável é OP_TRADE. O valor disso pode ser COMPRA ou VENDA e corresponderá a negociações hipotéticas de compra ou venda. Se o valor deste for BUY, então, ao gerar os outputs, ele irá apenas olhar para o sucesso potencial de negociações de compra hipotéticas. Alternativamente, se o valor deste é VENDER, então, ao gerar as saídas, apenas analisará o potencial sucesso de negociações de venda hipotéticas.


Os próximos valores utilizados são Stop Loss e Take Profit para esses negócios hipotéticos. Os valores são definidos em pips e definem os níveis de parada e limite para cada uma das negociações hipotéticas.


O parâmetro final é a duração do comércio. Essa variável é medida em horas e garantirá que somente negociações concluídas dentro dessa duração máxima serão consideradas bem-sucedidas. A razão para incluir esta variável é evitar o suporte de máquinas de vetor de sinalização comercial em um mercado paralelo lento.


Considerações a serem feitas ao escolher entradas.


É importante colocar algum pensamento na seleção de entrada ao implementar máquinas de vetor de suporte em sua negociação. Similar ao exemplo de Schnick, é importante escolher uma entrada que seria esperada ter similar entre incidências de diferença. Por exemplo, você pode se sentir tentado a usar uma média móvel como entrada, mas como o preço médio de longo prazo tende a mudar drasticamente com o tempo, uma média móvel isolada pode não ser a melhor entrada para usar. Isso ocorre porque não haverá semelhança significativa entre o valor médio móvel hoje e os valores médios móveis de seis meses atrás.


Suponha que estamos negociando EURUSD e usando uma máquina de vetores de suporte com uma entrada de média móvel para sinalizar negociações de 'compra'. Digamos que o preço atual é 1,10, no entanto, está gerando dados de treinamento de seis meses atrás, quando o preço foi de 0,55. Ao treinar a máquina de vetores de suporte, o padrão encontrado pode levar apenas a uma negociação sendo sinalizada quando o preço estiver em torno de 0,55, já que esses são os únicos dados que ele conhece. Portanto, sua máquina de vetores de suporte pode nunca sinalizar um comércio até que o preço caia de volta para 0,55.


Em vez disso, uma entrada melhor para usar na máquina de vetores de suporte pode ser um MACD ou um oscilador semelhante, porque o valor do MACD é independente do nível médio de preço e apenas sinaliza o movimento relativo. Eu recomendo que você experimente isso para ver o que produz os melhores resultados para você.


Outra consideração a ser feita ao escolher entradas é garantir que a máquina de vetor de suporte tenha um instantâneo adequado de um indicador para sinalizar um novo comércio. Você pode achar em sua própria experiência de negociação que um MACD só é útil quando você tem as últimas cinco barras para ver, pois isso irá mostrar uma tendência. Uma única barra do MACD pode ser inútil isoladamente, a menos que você possa dizer se está indo para cima ou para baixo. Portanto, pode ser necessário passar as últimas barras do indicador MACD para a máquina vetorial de suporte. Existem duas maneiras possíveis de fazer isso:


Você pode criar um novo indicador personalizado que usa as últimas cinco barras do indicador MACD para calcular uma tendência como um valor único. Este indicador personalizado pode então ser passado para a máquina de vetor de suporte como uma única entrada, ou.


Você pode usar as cinco barras anteriores do indicador MACD na máquina de vetores de suporte como cinco entradas separadas. A maneira de fazer isso é inicializar cinco instâncias diferentes do indicador MACD. Cada um dos indicadores pode ser inicializado com um deslocamento diferente da barra atual. Em seguida, as cinco alças dos indicadores separados podem ser passadas para a máquina vetorial de suporte. Deve-se notar que a opção 2 tenderá a causar tempos de execução mais longos para o seu Expert Advisor. Quanto mais entradas você tiver, mais tempo será necessário para treinar com êxito.


Implementando Support Vector Machines e Expert Advisor.


Eu preparei um Expert Advisor que é um exemplo de como alguém poderia potencialmente usar máquinas de vetor de suporte em suas próprias negociações (uma cópia disso pode ser baixada seguindo este link mql5 / pt / code / 1229). Esperemos que o Consultor Especialista permita que você experimente um pouco com máquinas de vetor de suporte. Eu recomendo que você copie / altere / modifique o Expert Advisor para se adequar ao seu próprio estilo de negociação. A EA funciona da seguinte forma:


Duas novas máquinas de vetor de suporte são criadas usando a biblioteca svMachineTool. Um é configurado para assinalar novos negócios 'Buy' e o outro está configurado para assinalar novos negócios 'Sell'.


Sete indicadores padrão são inicializados com cada um de seus identificadores armazenados em uma matriz inteira (Nota: qualquer combinação de indicadores pode ser usada como entradas, eles só precisam ser passados ​​para o SVM em uma única matriz de números inteiros).


A matriz de alças de indicadores é passada para as novas máquinas de vetor de suporte.


Usando a matriz de alças de indicadores e outros parâmetros, os dados de preços históricos são usados ​​para gerar entradas e saídas precisas a serem usadas para treinar as máquinas de vetor de suporte.


Uma vez que todas as entradas e saídas foram geradas, ambas as máquinas de vetor de suporte são treinadas.


As máquinas de vetores de suporte treinados são usadas na EA para sinalizar novos negócios "comprar" e "vender". Quando um novo comércio "comprar" ou "vender" é sinalizado, o comércio abre junto com as ordens manuais Stop Loss e Take Profit.


A inicialização e o treinamento da máquina de vetores de suporte são executados dentro da função onInit (). Para sua referência, este segmento do svTrader EA foi incluído abaixo com notas.


Advanced Support Vector Machine Trading.


Capacidade adicional foi construída na ferramenta de aprendizado de máquina de vetor de suporte para os usuários mais avançados. A ferramenta permite que os usuários passem seus próprios dados de entrada e dados de saída personalizados (como no exemplo da Schnick). Isso permite que você crie seus próprios critérios para obter entradas e saídas de máquinas vetoriais de suporte, e passar manualmente nesses dados para treiná-lo. Isso abre a oportunidade de usar máquinas de vetor de suporte em qualquer aspecto de sua negociação.


Não é possível usar máquinas de vetor de suporte para sinalizar novos negócios, mas também pode ser usado para sinalizar o fechamento de negócios, gerenciamento de dinheiro, novos indicadores avançados, etc. No entanto, para garantir que você não receba erros, é importante entender como essas entradas e saídas devem ser estruturadas.


Entradas: As entradas são passadas para o SVM como uma matriz unidimensional de valores duplos. Observe que qualquer entrada que você crie deve ser passada como um valor duplo. Boolean, integer, etc. devem ser todos convertidos em um valor duplo antes de serem passados ​​para a máquina de vetores de suporte. As entradas são necessárias no seguinte formato. Por exemplo, suponha que estamos passando em entradas com 3 entradas x 5 pontos de treinamento. Para conseguir isso, nossa matriz dupla deve ter 15 unidades de comprimento no formato:


| A 1 | B 1 | C 1 | A 2 | B 2 | C 2 | A 3 | B 3 | C 3 | A 4 | B 4 | C 4 | A 5 | B 5 | C 5 |


Também é necessário passar um valor para o número de entradas. No caso, N_Inputs = 3.


Saídas: as saídas são passadas como uma matriz de valores booleanos. Esses valores booleanos são a saída desejada do SVM correspondente a cada um dos conjuntos de entradas passadas. Seguindo o exemplo acima, digamos que temos 5 pontos de treinamento. Neste cenário, passaremos em uma matriz booleana de valores de saída com 5 unidades de comprimento.


Ao gerar suas próprias entradas e saídas, verifique se o comprimento de suas matrizes corresponde aos valores que você passa. Se eles não corresponderem, será gerado um erro para notificá-lo da discrepância. Por exemplo, se passamos em N_Inputs = 3, e as entradas são uma matriz de comprimento 16, um erro será lançado (uma vez que, um valor N_inputs de 3 significará que o comprimento de qualquer matriz de entrada precisará ser um múltiplo de 3). Da mesma forma, assegure-se de que o número de conjuntos de entradas e o número de saídas que você passa são iguais. Novamente, se você tiver N_Inputs = 3, comprimento de entradas de 15 e um comprimento de saídas de 6, outro erro será lançado (como você tem 5 conjuntos de entradas e 6 saídas).


Tente garantir que você tenha variação suficiente em suas saídas de treinamento. Por exemplo, se você passar 100 pontos de treinamento, o que significa uma matriz de saída de comprimento 100, e todos os valores são falsos com apenas um verdadeiro, a diferenciação entre o caso verdadeiro e o caso falso não é suficiente. Isso tenderá a levar o treinamento SVM muito rápido, mas a solução final é muito ruim. Um conjunto de treinamento mais diversificado freqüentemente levará a um SVM mais afetivo.


Quintuitiva.


Visualizações Quantitativamente Intuitivas sobre Mercados.


Negociação com SVMs: Desempenho.


Para ter uma idéia do desempenho do SVM na negociação, eu corri diferentes configurações nos dados históricos S & # 038; P 500 do & # 8230; os anos 50. O motivo principal por trás de usar essa década foi decidir quais parâmetros variar e o que manter constante antes de executar os testes mais importantes. Trate-o como um & # 8220; in-sample & # 8221; teste para evitar (mais;)) ajuste excessivo. Primeiro o gráfico de desempenho:


S & # 038; P 500 Trading Performance.


Muito agradável! O uso dos 5 retornos diários atrasados ​​mostra um desempenho semelhante à estratégia ARMA + GARCH, que eu achei muito promissor. Se você se pergunta por que estou tão empolgado com esse fato, é porque aqui estamos na área onde o ARMA + GARCH é o melhor e, no entanto, os SVMs mostram desempenho comparável.


As estatísticas também são impressionantes:


Enquanto escrevia este post, encontrei outro esforço para usar SVMs na negociação pela Quantum Financier. Sua abordagem usa o RSI de comprimento diferente como entrada para o SVM, mas também usa classificação (mapeia os retornos para dois valores, curtos ou longos) em vez de regressão. Como estava planejando testar a classificação de qualquer forma, seu post me inspirou a implementá-lo e executar uma comparação adicional, regressão vs classificação:


S & # 038; P 500 SVM Trading & # 8211; Regressão vs Classificação.


O que eu posso dizer & # 8211; Ambos parecem funcionar perfeitamente. Como um leitor sugeriu nos comentários, a Classificação exibe retornos mais consistentes.


Olhando para a mesa, a classificação cortou pela metade o rebaixamento máximo, mas curiosamente, não melhorou significativamente o índice de Sharpe. Nada conclusivo aqui, porém, foi uma corrida rápida das mais rápidas (em termos de tempo de execução) estratégias.


Ainda há uma longa lista de tópicos para explorar, apenas para ter uma ideia, sem nenhuma ordem específica:


Adicione outros recursos. Principalmente pensando em adicionar algumas séries relacionadas ao Fed, esses dados remontam a 1960, então está em breve. Experimente outros parâmetros de svm: outras regressões, outras classificações, outros kerenls, etc. Isso é mais como uma estabilidade teste. Tente outras funções de erro. O padrão é usar o erro quadrático médio, mas no caso de regressão, por que não usar o Razão Sharpe (na amostra)? O caso de regressão é mais simples, já que temos os retornos reais e # 8211; verifique a entrada de tune. control. Experimente períodos mais longos em vez de dias. Semanalmente é um começo, mas idealmente eu gostaria de implementar períodos de dois ou três dias. Varie o período de loopback. Use mais classes com classificação: grandes dias, dias médios, etc.


Isso levará tempo. Como sempre, comentários e comentários são bem-vindos.


1) Você possui Razões Sharpe para regressão SVM versus classificação SVM? Ao olhar o gráfico, a classificação parece dar melhores retornos ajustados ao risco.


2) Você já ouviu falar do pacote Caret (caret. r-forge. r-project / index. html)? Parece que já incorporou muito do trabalho que vejo que você usa em seu código existente. Outro grande benefício é que você pode facilmente trocar um algoritmo de aprendizagem de ML (por exemplo, redes neurais) sem ter que recodificar tudo.


Blog muito interessante!


1) Bom ponto, cortou a redução, mas não a proporção de Sharpe significativamente & # 8211; Eu atualizei a postagem.


2) Obrigado por trazer o pacote Caret, esta é a segunda vez que eu ouço sobre isso, então é hora de dar uma olhada mais de perto :) Parece muito promissor, certamente muito a aprender com isso.


Você compartilha seu código? Os resultados são realmente impressionantes. Estou tentando construir um classificador SVM fazendo algo semelhante, mas eu quero usar mais parâmetros do que preços. Embora, talvez isso não seja tão útil, porque parece que os preços por si só fornecem valor preditivo. Obrigado.


Também estou planejando usar mais do que apenas os preços, mas esse tipo de dados não está disponível para os anos 50. Em geral, os anos 50 no S & # 038; P 500 são bastante preditivos. Modelos mais complexos provavelmente serão necessários em diante.


Verifique o post anterior (quintuitive / 2012/11/30 / trading-com-suporte-vector-machines-svm /) na série & # 8211; existe um link para o código que usei com base no pacote e1071. Desde que publiquei o código, mudei-me para o pacote de caixa que fornece uma interface unificada para muitos modelos. Parece muito bom até agora também.


Parece bom, obrigado por compartilhar. Muito bem sucedida.


Também estou tentando usar o SVM-SVR para prever o preço de fechamento dos estoques, como valor de índice como DJ CAC40, etc.


Minha idéia é muito simples e fácil, eu baixei os dados em um site de corretores, eu tenho acesso a 3 anos desses dados. A resposta é o valor próximo do índice, suponho que as características do dia anterior têm um impacto do valor próximo dos próximos dias, ou seja: maior valor menor valor de abertura de valor para segunda-feira são recursos para prever, para explicar o valor de fechamento of tuesday, i build my dataset with this assumptions, so i use feature with lag1, obviously i can add others feature like lag2,lag3. I put a sample of my data structure here :


openinglag1 highestlag1 smallestlag1 closing(response) volume lag1.


3950.59 3959.2 3936.33 4013.97 589818.


Finally i have a 764 data set, all the data set i using to train the svr, and i predict the next days as i mentionned above.


My questions are how can i predict for example the next 5days? Is my data structure right?


Not happy with the rolling forecast in svmComputeForecasts? See what it does for modelPeriod=’weeks’ por exemplo.


An alternative is to do weekly forecasts right upfront. In other words, summarize the data into weeks (or three/four day chunks), and call svmComputeForecasts using ‘days’ on this set. Each prediction applies for the entire period.


As far as I know, one cannot just do a five day ahead probabilistic prediction with SVMs (this is doable with ARMA techniques).


Espero que isto ajude,


I’ve been enjoying your posts and have a question. I was wondering what kind of improvement you found when moving from the simple ARMA model to the ARMA-GARCH model? Have you tested any other rolling window training parameters? Also did you find that the short side made much of a difference (i. e is it much/better or worse) than long only?


Hi, I addressed some of these questions in a later post: quintuitive/2012/12/27/armagarch-experiences/. Adding more statistics to the ARMA+GARCH tutorial is certainly on my list, but it will take time. One can do all these analysis by using the indicator (quintuitive/wp-content/uploads/2012/08/gspcInd3.csv) together with the GSPC from Yahoo. The indicator is already aligned – no need to lag.


Very impressive. However have you tried using random forest –


it claims to be superior to SVM as it allows for implicit non-linear effects and interaction terms among the exogenous variables. Also it whittles down the exogenous variable to the most important play-makers and its rather fast as well especially with your dataset.


Hi and thanks for the earlier reply. One thing I’m a bit confused about is that on the ARMA+GARCH post (quintuitive/2012/08/22/arma-models-for-trading/) you mention 18.87% CAGR and B&H looks to be about 7% CAGR from eyeballing the chart. Yet, in the table above you show, 30.88% and 15.4% for ARMA+GARCH and BH, respectively.


Is it a different time-frame or am I missing something? Obrigado novamente.


I see… it is only a 5 yr sample here. I was unable to delete the comment. Do you have CAGR for all systems across all years?


Quintuitive.


Quantitatively Intuitive Views on Markets.


Trading with Support Vector Machines (SVM)


Finally all the stars have aligned and I can confidently devote some time for back-testing of new trading systems, and Support Vector Machines (SVM) are the new “toy” which is going to keep me busy for a while.


SVMs are a well-known tool from the area of supervised Machine Learning, and they are used both for classification and regression. For more details refer to the literature.


It seems to me that the most intuitive application for trading is regression, so let’s start by building an SVM regression model.


Following our experience with ARMA+GARCH models, we will start by trying to forecast returns, instead of prices. Likewise, in our first tests, we will use only the returns of the previous 5 days as the features determining the return of a particular day. We will start with history of 500 days as the training set.


In more mathematical terms, for the training set we have N features, for each of them we have M samples. We also have M responses.


Given a row of feature values, the left matrix, the SVM is trained to produce the response value. In our specific example, we have five columns (features), each column corresponding to the returns with a different lag (from 1 to 5). We have 500 samples and the corresponding responses.


Once the SVM is trained on this set, we can start feeding it with sets of five features, corresponding to the returns for the five previous days, and the SVM will provide us with the response, which is the forecasted return. For example, after training the SVM on the previous 500 days, we will use the returns for days 500, 499, 498, 497 and 496 (these are ours as the input to obtain the forecasted return for day 501.


From all the packages available in R, I decided to choose the e1071 package. A close second choice was the kernlab package, which I am still planning to try in the future.


Then I tried a few strategies. First I tried something very similar to the ARMA+GARCH approach – the lagged returns from the five previous days. I was quite surprised to see this strategy performing better than the ARMA+GARCH (this is the home land of the ARMA+GARCH and I would have been quite happy just with comparable performance)!


Next, I tried to the same five features, but trying to select the best subset. The selection was done using a greedy approach, starting with 0 features, and interactively adding the feature which minimizes the error best. This approach improved things further.


Finally, I tried a different approach with about a dozen features. The features included returns over different period of time (1-day, 2-day, 5-day, etc), some statistics (mean, median, sd, etc) and volume. I used the same greedy approach to select features. This final system showed a very good performance as well, but it took a hell of a time to run.


Time to end this post, the back-testing results have to wait. Until then you can play with the full source code yourself. Here is an example of using it:


Hello, is it possible to have an example of application if your function?


Updated the post.


Great post about SVM’s. Obrigado por compartilhar. I’m an R newbie, could you please tell me what is the difference between doing this.


In windows doesn’t work because of multicore problem.


One more thing that I don’t understand is reflected in this to rows of the code.


In my opinion it’s more effective to merge series.


and to have only one argument=object to function call instead of 2.


Interesting work, thanks.


Argh, Windows – I use it seldom lately. Quite surprised still, since the parallel package is part of the base R distribution now. Hopefully it will be addressed soon.


Meanwhile, how about not using parallel execution? Also there are other packages providing parallel execution, but that would be more work.


You are right about the merge – I still wonder why I did it this way this time.:)


I’m receiving errors.


Now the error is.


& gt; data = svmFeatures( tt )[,c(1,2)]


Error in match. fun(FUN) : object ‘skewness’ not found.


But when I make manually data object I receive error in prediction.


svmComputeOneForecast <- function related to dimensions and.


It's difficult to me to debug.


skewness comes from the PerformanceAnalytics package, which you need to install from CRAN. Adding require(PerformanceAnalytics) as the first line of svmFeatures should address the first problem.


Error in merge. xts(res, xts(na. trim(lag(rollmean(rets, k = 21, align = “right”), :


length of ‘dimnames’ [2] not equal to array extent.


it seems that in windows code needs a lot of changes.


Mike, I never meant the code to be used directly (until now I was providing only snippets), but I am surprised that R on Windows is so ugly. Not sure what’s your goal, but to analyze the strategies performance, you can use the indicator series which are already computed.


It’s just pure academic interest on SVM. I used to work with clusters, PCA and I am curious how SVM is doing the same work.


In windows a lot of error are related to objects with dates as xts is or data frames.


UNIX is better but all brokers give API for windows. Some of them in Java and only this we may use from UNIX.


I don’t like win architecture but it’s a habit already and I don’t have time to change OS.


I just tried it on windows 7, 64 bit, R version 2.15.2. I get a warning from svmFeatures, which I know how to fix (calling sd on an xts/zoo object does interesting conversion to a matrix), but no problems. Running:


One question if you don’t mind.


Why are you using get with function cetSymbols from quantmod package?


I use call vers.


SPY <- getSymbols('SPY', auto. assign = FALSE)


You have a lot to compute and get consume memory and takes time to obtain objects name.


as a string var.


But I’m surprised with this result before call.


1 function (…, list = character(), package = NULL, lib. loc = NULL,


2 verbose = getOption(“verbose”), envir =.GlobalEnv)


4 fileExt <- function(x)


It seems that data is reserved word.


And now I don't know what is going to features function.


I am using R 2.15.2 on 64-bit linux. On my system data is also a function, but I don’t think this is the problem.


That’s probably a better way. Have seen it before, but didn’t pay attention till now to realize that it does exactly that. Obrigado.


What do you mean when you speak about the lagged returns? IS it the value 500,499,498,497,496 for the prediction of the return 501?


Yes, these returns are used to forecast the return of 501, which is used as the position (long/short depending on the sign) for 501. The model is trained on the previous data only, i. e. the last “row” in the training set is 499,498,497,496,495.


Ok, that’s sound good, and for the return do you use this formule :


return t=log(Price t+1/Price t)


And after you normalize (center and scale ) the return?


You can find these details in the accompanied source code. I use the discrete returns:


I don’t don’t center the data, neither I scale it. However, both packages which I use (caret+kernlab and e1071) seem to do that by default.


Another things, sorry, but you build your model on the previous 499 values, this is your training data set,


And afte, r to forecast the 501 return you use the last row as test values?


Why build a model on the 500 values and use the last row i. e 500,499 etc another time to test or to train?


in your tutorial you said: For example, after training the SVM on the previous 500 days, we will use the returns for days 500, 499, 498, 497 and 496 (these are ours as the input to obtain the forecasted return for day 501.


And in your response you said:Yes, these returns are used to forecast the return of 501, which is used as the position (long/short depending on the sign) for 501. The model is trained on the previous data only, i. e. the last “row” in the training set is 499,498,497,496,495.


Are you ok if i claim, i build the model on the 500 values, and to forecasted the 501 i use the model build previously and give him to “eat” the last row of the training dataset ie:500,499etc as input to obtain the forecasted 501’s value?


Regards and sorry for the multiple post, but i have got trouble with my network.


In general, I think it should be ok to use the approach you are suggesting. Notice that this approach will be much more demanding to implement in real-life trading, or at least the way I do it.


If one is to compute all reasonable closing prices in advance, the new approach will need to do one fit for each individual close and one predict. Compare to the other approach – the model is fit based on the previous 500 days, then only the new data (different for each close) is being fed. In other words, here we have one fit, many predicts.


Really admire your work mate, Im new to SVM with R, Im trying to use ten technical indictors to forecast stock index tommorrow’s movements(up or down as 1 or -1), when you train the model, what would you use as response column…if you are at 07/07/2012…you use that day movement or 08/07’s movement for 07/07’s technical indicators…if you use 07/07’s input…how do you forcast tommorrow’s results as you dont know tommorrow’s inputs…I hope that makes sense…


any help would be appreciated.


Hi Louis, if the target is only long/short, you may want to use classification instead of regression. Most packages silently switch to classification if the response vector is “factors” rather than numericals. Check quantumfinancier. wordpress/2010/06/26/support-vector-machine-rsi-system/ for an example.


Before starting the step forward process, I align the desired response with the data that predicts it. In general, this is a lag(1) of the predictors (data). This aligns the desired value of 08/07 (the return of 08/07) with its predictors (the indicators as of 07/07 close). Then I fit the model using the data by excluding the last date. In other words, let’s say I am about to predict 08/07. The last date I look when fitting is 07/07. Since the data is already lagged, the last date for the indicators is in fact 06/07. Finally to forecast one day ahead, I feed the data for 08/07, which corresponds to the indicators on 07/07. Now I can compare the predicted with the real value. This can relatively-easily be applied in practice, as long as the indicators are based on closing prices only. Anything using high/low/volume/etc (stochastics for instance), needs to either be lagged by an extra day, or the trading cannot happen right at the close … see my other post: quintuitive/2012/08/23/trading-at-the-close-the-mechanics/.


Espero que isto ajude.


Thats really helpful, thanks a lot mate…


most papers about SVM online are quite pointless…I guess not everyone likes to share their secrets haha.


sorry, one more question: for the model with the best performance, what inputs did you use to forecast tommorrow’s return..


AS quote”Finally, I tried a different approach with about a dozen features. The features included returns over different period of time (1-day, 2-day, 5-day, etc), some statistics (mean, median, sd, etc) and volume. I used the same greedy approach to select features. This final system showed a very good performance as well, but it took a hell of a time to run.”


The model with the best performance, by just a bit, was using lagged (by 1,2,3,4 and 5 days) daily returns. The only twist was that it was using a greedy method to select the “best” combination of features.


I just finished my work, I adopted a classification approach to predict tommorrow’s movement…


the accuracy is almost 86% on a 140days testdate.. I wonder if this is a little bit too high…


Nevertheless…Thank you so much.


Sounds too high to me. I’d certainly review it a few more times before taking it seriously – that’s like having a crystal ball.;)


Here is an idea, when you select the training set, try to divede your training set into two equal parts, one is the response returns above the average, the other is the returns below the average…this way, your forecast accuracy might not change much, but you can forecast the BIG movements much more accurate…


the performance should be improved…I’ve tried this and the results are quite nice…please let me know if this works for you..cheers.


My names is Krzysztof and I’m an author of this thread.


In this project I was using different machine learning algorithms (including SVM) trying to predict if certain trade with fixed TP/SL will be successful or not so classification.


Some comments/questions to your code.


1)Using cross validation (tune. control, cross=cross). Are you sure that using cross validation is correct in case of time series ?? In such case training will be done on past data and by definition of time series it introduce future leak and inflated results. Perhaps fix option should be used instead.


2)Kernel constants. The most important parameters for SVM are kernel constants. Why those fixed values are used and not another ??


3)Sample size/Choice of SVM. The training time of this SVM is exponentially correlated to the training sample size as far as I remember. But there are other SVMs specialized for use with bigger training sample size e. g. I was training my system on up to 150 000 bars within few hours. For example pegassos, libocas or SVMLight. In such case it is possible e. g. to use hourly data and bigger sample size which will give much better accuracy.


4) Why not use RWeka package and have the access perhaps more than hundred ML algos.


Quite an interesting thread, certainly something to take a look at – thanks for bringing it up. What do you mean by “TP/SL”?


1) The code is mostly for illustration purposes, and I didn’t find it very useful overall. I agree, it is dubious to consider each row in the training set as independent from the rest in the case of time series with their correlations, but it is an approach. According to robjhyndman/hyndsight/crossvalidation/, a better approach might be a one-step cross-validation using the past data, which should be relatively easy to add.


2) Nothing special about these kernel constants – just a set to iterate through. I think I used values found in examples using the package(s). The optimization chooses the best.


3) Good to know. Currently I don’t trade intraday, so I never had the need to deal with such big amounts of data. For daily data, increasing the window improves the performance, but up to a point from my experience. A bit counter intuitive that longer time window will improve the forecasts indefinitely - at some point the data is too much (as a ratio vs the number of parameters optimized).


4) Haven’t really looked into RWeka. Originally I started with e1071 because it’s fast and very stable. Then I switched to caret, which provides unified interface to many other packages, including some algorithms from RWeka. In my experience, I haven’t found an ML approach that really stands out for prediction of time series data. Have you?


Obrigado por compartilhar,


1)Using cross validation (tune. control, cross=cross). Are you sure that using cross validation is correct in case of time series ?? In such case training will be done on past data and by definition of time series it introduce future leak and inflated results. Perhaps fix option should be used instead.


should be ‘In such case training will be done on future data’


My implementation doesn’t (at least by design;)) use future data. If the history is 500 points, the cross validation is used within these 500 to determine the best fit.


TP/SL – take profit/ stop loss. System was trying to trade on every bar (buy or sell) than label.


was determined (trade successful/unsuccessful) depends if TP or SL was hit first.


“If the history is 500 points, the cross validation is used within these 500 to determine the best fit”


Well in such case in sample results will be inflated and has no meaning. For example if you divide training period for 10 sub periods and train on periods 1-8 and 10 than evaluate on period 9, future leak occurs as period 10 is after period 9 so in the future.


this how cross validation works i think and it is applicable only for static patterns. Only walk forward has a meaning in case of time series.


When i try the code i find the ROC 2 for the row 29/03/195: Is the difference of : value of 28/03 and 24/03 divide by value of 24/03, why is not the value of 27/03- value of 24/03 divide by value of 24/03….


The code is just for illustration. You can modify it anyway you want and use whatever features you think may improve the predictions. The ROC function comes from the TTR package.


Is it possible to have a plot of the ARMA model and SVM out-of-sample to compare their performance?


Not likely to get the time to go back to it, but will keep it in mind.


A Single SVM Trading Strategy.


Support Vector Machines (SVM) are gaining popularity in machine learning trading systems. They have advantages Neural Networks (NN) as they are guaranteed to find the optimal solution. NN can get caught in a local minima, so while you get a result using NN you can never be sure it is optimal. Also if NN are started with random weights you’ll probably get a different set of weights each time you run backpropagation on the same set of data.


SVMs do have their drawbacks too. Specifically the selection of the ‘hyper’ parâmetros. These are the penalty (C), gaussian width (g) if using an RBF kernel and epsilon insensitivity (e) if using Support Vector Regression (SVR).


My use of SVMs so far has been to use them in classification so I only need to select the C and g parameters – I use the standard RBF kernel. It’s hard enough trying to predict if the market will go up or down, let alone by how much.


We can select these parameters using a grid search . This means that we simply try each combination of parameters and see which worked best. The way the parameters are assessed is through n-fold cross-validation.


Cross Validation.


This is best explained with an example. If we have 1000 labelled training instances and we use 10 fold cross-validation, then for each combination of C, g we do the following:


Randomly take out 10% of the samples. This is our hold-out set of 100 training instances. Train the SVM on the remaining 90% and create a model. Use the model to test the accuracyon the hold-out set. Repeat the exercise 10 times and take the average accuracy.


The above is 10-fold cross validation. We could take this to the logical conclusion and only have a single instance in out hold-out ‘set’. This is leave-one-out cross validation. It would give us the most accurate assessment of the parameter combination but in practice 10-fold or even 5-fold is good enough.


So how do we actually do a cross-validation ?


The libSVM package at csie. ntu. edu. tw/


cjlin/libsvm/ contains some Python scripts in the tools directory. You’ll need to install Python and Gnuplot.


You can also use DeepThought available from deep-thought. co. In the examples below I’ll use DeepThought.


The first thing we need is some data. I’ll use a training set with the following features.


Hour of Day Average close price difference between the previous 30 bars Moving average differences between the previous 1,2,3,4,5,7,9,13,16,20,25,31,45,55,70,100 bars with MA periods of 5, 10, 20, 50 and 100.


The target is -1 for the price will go down at the close of the next bar, 1 for the price will go up at the close of the next bar. Once I’ve set these in the configuration, I run the command.


to extract the training set. I’ve also use min-max scaling. I’ll discuss feature preparation and scaling in another article. The command above will create training files from all models defined in the DeepThought configuration. After the command has completed a file h4-features. training. data is created the the same directory that I ran the command from. This is in libSVM format so we can use the libSVM tools to run the grid search, or use grid search built into DeepThought. Also created is the file h4-features. training. data. csv which contains the same data but in CSV format so you can play with it in other tools such as R, Python, Excel etc.


To run the grid search in DeepThought I use the command:


The results are in the logfile where Result: is the percentage accuracy:


The (uninteresting) results in the middle have been removed for brevity. We can see that the SVM seems to favour smaller gammas and the C looks to be a sensible value. We should be concerned if the best gamma was large and the C small as it probably means some sort of data error. The next highest values are roughly the same range as the best parameters which indicates that the parameter selection is relatively insensitive. We should be concerned if the values giving the best result were outliers.


Backtesting the Single SVM Strategy.


The final step is to assess how a single SVM performs in a backtest. In this backtest we simply buy with a +1 forecast and sell with a -1 forecast. If we are long and we get a buy signal we add another position to a maximum position size of 10. Conversely for sell signals.


Using the best C of 128 and gamma of 0.00195313 we can cut and past the following XML snippet from the grid search log file into the DeepThought configuration file:


The backtest is run with the following command:


The DeepThought backtest operates by creating a training set at the close of each bar, the EURUSD H4 in this case. When the close of the next bar is reached a forecast is made and trades entered and/or closed, then the model is retrained again ready for the next bar. Thus it is continuously adapting to the latest conditions and all tests are out-of-sample, avoiding over-fitting.


The results of the backtest were:


and a plot of the PnL (plotted using R):


It sort of looks ok, but probably not something we’d trade as is.


The next article will discuss ensembles to see if we can improve this result.


Trading with SVMs: Performance.


S&P 500 Trading Performance.


Muito agradável! Using the 5 lagged daily returns shows similar performance to the ARMA+GARCH strategy, which I found very promising. If you wonder why I am so excited about this fact, it’s because here we are in the area where ARMA+GARCH is best, and yet, SVMs show comparable performance.


The statistics are also impressive:


While writing this post, I found another effort to use SVMs in trading by Quantum Financier. His approach uses RSI of different length as input to the SVM, but it also uses classification (maps the returns to two values, short or long) instead of regression. Since I was planning to try classification anyways, his post inspired me to implement it and run an additional comparison, regression vs classification:


S&P 500 SVM Trading – Regression vs Classification.


What can I say – they both seem to work perfectly. As a reader suggested in the comments, the Classification does exhibit more consistent returns.


Looking at the table, the classification cut in half the maximum drawdown, but interestingly, it didn’t improve the Sharpe ratio significantly. Nothing conclusive here though, it was a quick run of the fastest (in terms of running time) strategies.


There is still a long list of topics to explore, just to give you an idea, in no particular order:


Add other features. Mostly thinking of adding some Fed-related series, this data goes back to 1960, so it’s coming soon.:) Try other svm parameters: other regressions, other classifications, other kerenls, etc. This is more like a stability test. Try other error functions. The default is to use the mean square error, but in the case of regression, why not use Sharpe Ratio (in-sample)? The regression case is simpler, since we have the actual returns – check the input of tune. control . Try longer periods instead of days. Weekly is a start, but ideally I’d like to implement two or three day periods. Vary the loopback period. Use more classes with classification: large days, medium days, etc.


This will take time. As always, feedback and comments are welcome.


Comentários estão fechados.


Posts populares recentes.


Artigos mais visitados da semana.


Empregos para usuários R.


É alimentado pelo WordPress usando um design bavotasan.


Direitos autorais e cópia; 2017 R-bloggers. Todos os direitos reservados. Terms and Conditions for this website.


Trading with Support Vector Machines (SVM)


Finally all the stars have aligned and I can confidently devote some time for back-testing of new trading systems, and Support Vector Machines (SVM) are the new “toy” which is going to keep me busy for a while.


SVMs are a well-known tool from the area of supervised Machine Learning, and they are used both for classification and regression. For more details refer to the literature.


It seems to me that the most intuitive application for trading is regression, so let’s start by building an SVM regression model.


Following our experience with ARMA+GARCH models, we will start by trying to forecast returns, instead of prices. Likewise, in our first tests, we will use only the returns of the previous 5 days as the features determining the return of a particular day. We will start with history of 500 days as the training set.


In more mathematical terms, for the training set we have N features, for each of them we have M samples. We also have M responses.


Given a row of feature values, the left matrix, the SVM is trained to produce the response value. In our specific example, we have five columns (features), each column corresponding to the returns with a different lag (from 1 to 5). We have 500 samples and the corresponding responses.


Once the SVM is trained on this set, we can start feeding it with sets of five features, corresponding to the returns for the five previous days, and the SVM will provide us with the response, which is the forecasted return. For example, after training the SVM on the previous 500 days, we will use the returns for days 500, 499, 498, 497 and 496 (these are ours as the input to obtain the forecasted return for day 501.


From all the packages available in R, I decided to choose the e1071 package. A close second choice was the kernlab package, which I am still planning to try in the future.


Then I tried a few strategies. First I tried something very similar to the ARMA+GARCH approach – the lagged returns from the five previous days. I was quite surprised to see this strategy performing better than the ARMA+GARCH (this is the home land of the ARMA+GARCH and I would have been quite happy just with comparable performance)!


Next, I tried to the same five features, but trying to select the best subset. The selection was done using a greedy approach, starting with 0 features, and interactively adding the feature which minimizes the error best. This approach improved things further.


Finally, I tried a different approach with about a dozen features. The features included returns over different period of time (1-day, 2-day, 5-day, etc), some statistics (mean, median, sd, etc) and volume. I used the same greedy approach to select features. This final system showed a very good performance as well, but it took a hell of a time to run.


Time to end this post, the back-testing results have to wait. Until then you can play with the full source code yourself. Here is an example of using it:

No comments:

Post a Comment