![Teste e otimização de estratégias para opções binárias no MetaTrader 5](https://c.mql5.com/2/0/binary-strategy-tester_600x314.jpg)
Teste e otimização de estratégias para opções binárias no MetaTrader 5
Introdução
Boa tarde, caros usuários da comunidade MQL5. Recentemente, eu me interessei pelo tema de opções binárias. Depois de explorar o vasto espaço da Internet e analisar diferentes corretoras, constatei que praticamente todas usam suas próprias plataformas para negociação. Essas plataformas não possuem a capacidade de testar estratégias e, na melhor das hipóteses, possuem um conjunto limitado de indicadores padrão. Depois de revisar uma ampla variedade de estratégias para opções binárias, surgiu a questão de como verificar essas estratégias, sem mencionar a otimização. Como sempre, o nosso querido MetaTrader 5 veio ao meu auxílio. Como de costume, farei o meu melhor para compartilhar com vocês minhas experiências da maneira mais simples possível, apresentando o material sem recorrer a fórmulas e códigos complexos. Mas, antes de mais nada, um pouco de teoria e argumentos sobre se vale a pena ou não se envolver com opções binárias.
Teoria
Uma opção binária é um contrato digital cujo objeto é a previsão da direção do preço de um ativo em um intervalo de tempo escolhido. Como trabalhar com opções binárias? A tarefa é corretamente determinar um dos dois possíveis cenários para o desenvolvimento da situação de mercado: se o ativo irá aumentar ou diminuir de valor. Hoje, uma vasta seleção de opções online para moedas, valores mobiliários e commodities está disponível. O ativo neste tipo de procedimento pode ser qualquer coisa, como foi demonstrado, até mesmo a previsão do tempo. Começar a negociar não requer grandes investimentos nem profundo conhecimento financeiro e econômico no campo dos processos de negociação de mercado.
Tipos de opções binárias
"Alta/Baixa" (Call/Put) é o tipo mais simples e compreensível de opções binárias, aqui para lucrar, basta que o trader determine a direção em que o preço irá se mover, para cima ou para baixo. Em uma tendência de alta, é aconselhável comprar "Alta" (Call). A opção "Baixa" (Put) é comprada se for esperado um movimento de queda do ativo. O lucro das opções Alta/Baixa varia de 10% a 80% da aposta.
"One Touch" (Um Toque) representa um acordo no qual é necessário determinar se o preço atingirá o nível de preço desejado. Onde as cotações estarão no fechamento não é relevante; o fato de tocar o nível definido será decisivo. A lucratividade do "One touch" é maior do que o normal, pois na maioria dos casos é muito difícil prevê-los e pode chegar a 95%, mas também é possível perder todos os 100%.
"Intervalo" (Range) determina o corredor de preço, dentro do qual o valor do ativo estará localizado no momento da expiração. Também é difícil de entender e prever. Rendimento de até 95%.
Abaixo, no artigo, iremos realizar testes e otimização de estratégias para as opções "Alta/Baixa", que, na minha opinião, são as mais populares.
Vantagens e desvantagens
As vantagens incluem:
- Simplicidade: A obtenção de uma fixação na quantidade de perdas ou lucros potenciais permite evitar a necessidade de realizar cálculos complexos de stop loss e estabelecer níveis de lucro. Isso é especialmente benéfico para iniciantes, que não possuem experiência como traders e desejam evitar complicações.
- Cadastro simples no site da corretora de opções: É necessário um tempo mínimo sem a necessidade de enviar pacotes de documentos extensos, o que é comum em bolsas de valores ou futuros.
- Maior variedade de recursos: É possível negociar ações de empresas, índices de ações, petróleo, ouro, criptomoedas e muito mais com um valor mínimo de fundos, a partir de $100. Algumas corretoras até possuem valores mínimos ainda menores. Em comparação, ao negociar nos mercados de ações ou futuros, são necessários depósitos iniciais mais substanciais.
Algumas desvantagens:
- Alto risco e expectativa negativa: A relação entre vitórias e derrotas é desfavorável, exigindo duas vitórias para compensar uma derrota. Eficiência lucrativa de até 80%: Embora possa ser lucrativa, a eficiência da operação é limitada a 80%, o que pode não ser ideal em certas situações.
- Falhas no modo "Casino" à distância: Algumas pessoas tentam aplicar truques de cassino ao negociar, como a estratégia de "Martingale", que contradiz as regras da negociação adequada. Isso pode levar à perda total do depósito à distância.
- Comissões consideráveis cobradas em qualquer caso conveniente ao negociar: Ao negociar, comissões substanciais são aplicadas, independentemente da situação, o que pode afetar os lucros.
Par de moedas, alcance da otimização e testes avançados, bem como opções
Aqui vou dar todos os parâmetros para otimização e teste para que não se repitam no texto:
- Mercado Forex;
- Par de moedas EURUSD;
- Período M5, M15, M30, H1;
- Tempo de expiração 5, 15, 30 minutos e 1 hora.
- Faixa de otimização 1 ano. De 28/01/2021 a 2022.01.28.
- Intervalo de teste forward 1 ano. De 28/01/2022 a 28/01/2023;
- Depósito inicial 10000;
- Aposta 10;
- O percentual da remuneração é de 80%.
Aspectos técnicos
Para realizar os testes e a otimização, precisamos de parâmetros de entrada:
- StartDepo - depósito inicial;
- OptionRate - aposta;
- ExpirationTime - tempo de expiração;
- ProfitPercent - percentual de lucro;
- TimeFrame - período gráfico dos indicadores;
- Optimization - interruptor de otimização;
- OptimizationFileName – nome do arquivo para armazenar os resultados da otimização.
input string N0 = "------------Open settings----------------"; input double StartDepo = 10000; input int OptionRate = 10; input string N1 = "------------Close settings---------------"; input int ExpirationTime = 1; //ExpirationTime 1=5 min, 2=15 min, 3=30 min, 4=60 min input double ProfitPercent = 80; input string N2 = "------------Optimization settings--------"; input int TimeFrame = 1; //TimeFrame 1=5 min, 2=15 min, 3=30 min, 4=60 min input bool Optimization = false; input string OptimizationFileName = "Optimization.csv"; input string N3 = "------------Other settings---------------"; input int Slippage = 10; input int Magic = 111111; input string EAComment = "2Ma+RSI+Stochastic Oscillator";
Também serão necessárias variáveis para armazenar e acompanhar as alterações no depósito e o número de compras de opções lucrativas e perdedoras:
- XStartDepo - armazenamento do depósito atual;
- Profit - armazenamento do número de compras de opções lucrativas;
- Loss - armazenamento do número de compras de opções não lucrativas;
double XStartDepo = StartDepo; int Profit=0; int Loss=0;
Para rastrear o tempo de abertura da posição e fechar a posição após o tempo de expiração no MetaTrader 5, usaremos uma função que retorna o tempo de abertura da posição.
//+------------------------------------------------------------------+ //| Get open time in positions | //+------------------------------------------------------------------+ datetime GetTime(string symb="0", int type=-1, int mg=-1,int index=0) { datetime p[]; int c=-1, pr=0; if(symb=="0") { symb=Symbol();} for(int i=PositionsTotal()-1;i>=0;i--){ if(position.SelectByIndex(i)) { if(position.PositionType()==POSITION_TYPE_BUY || position.PositionType()==POSITION_TYPE_SELL) { if((position.Symbol()==symb||symb=="")&&(type<0||position.PositionType()==type)&&(mg<0||position.Magic()==mg)) { c++; ArrayResize(p, c+1); p[c]=position.Time(); pr=c>=index?index:c; }}}} return(c==-1?0:p[pr]); }
Para rastrear a lucratividade de uma posição e decidir se ganhamos uma aposta ou não, usaremos uma função que retorna o lucro de uma posição aberta no momento atual. Comissões e swaps não são levados em consideração.
//+------------------------------------------------------------------+ //| Get profit in positions | //+------------------------------------------------------------------+ double GetProfit(string symb="0", int type=-1, int mg=-1,int index=0) { double p[]; int c=-1, pr=0; if(symb=="0") { symb=Symbol();} for(int i=PositionsTotal()-1;i>=0;i--){ if(position.SelectByIndex(i)) { if(position.PositionType()==POSITION_TYPE_BUY || position.PositionType()==POSITION_TYPE_SELL) { if((position.Symbol()==symb||symb=="")&&(type<0||position.PositionType()==type)&&(mg<0||position.Magic()==mg)) { c++; ArrayResize(p, c+1); p[c]=position.Profit(); pr=c>=index?index:c; }}}} return(c==-1?0:p[pr]); }
Para utilizar apenas um novo sinal de entrada, utilizamos vários gatilhos. Isso significa que a permissão para entrar no mercado só é concedida quando há um sinal novo. Entradas repetidas no mesmo sinal são ignoradas.
- TrigerSell - compra de uma opção Put;
- TrigerBuy - compra de uma opção Call;
int TrigerSell=0; int TrigerBuy=0;
A saída de uma posição, a adição e retirada de fundos do depósito inicial, bem como o cálculo das compras de opções lucrativas e não lucrativas são realizados rastreando o tempo atual em relação à abertura da posição e o tempo de expiração.
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Durante a otimização, usamos variáveis para determinar o período gráfico desejado e o tempo de expiração. O modo de otimização é ativado pela variável Optimization. A otimização, por sua vez, se resume ao uso de arquivos CSV. Depois que o teste é concluído em OnDeinit, escrevemos todas as variáveis necessárias em um arquivo. Ao otimizar, nossos EAs criam um arquivo CSV que contém o resultado no caminho "C:\Users\Your username\AppData\Roaming\MetaQuotes\Terminal\Common\Files".
- Depósito final;
- Número de negociações lucrativas;
- Número de negociações não lucrativas;
- Período gráfico
- Tempo de expiração.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if (Optimization==true){ if (FileIsExist(OptimizationFileName)==false){ filehandle = FileOpen(OptimizationFileName,FILE_WRITE|FILE_READ|FILE_CSV|FILE_COMMON|FILE_ANSI, ";"); if(filehandle!=INVALID_HANDLE) { FileSeek(filehandle, 0, SEEK_END); FileWrite(filehandle,DoubleToString(XStartDepo),IntegerToString(Profit),IntegerToString(Loss),IntegerToString(XTimeFrame),IntegerToString(XExpirationTime)); FileClose(filehandle); } } } }
É possível observar o teste no modo de visualização usando Comment() para apresentar o resultado atual de forma simples.
Estratégias
Estratégia "2Ma+RSI+Stochastic Oscillator"
Essa estratégia é disponibilizada por uma corretora bem conhecida como uma estratégia de escalpelamento para opções binárias, sugerindo um período gráfico de 5 minutos e um tempo de expiração de 5 minutos.
Indicadores:
- Um par de médias móveis exponenciais com períodos de 5 e 10;
- Índice de força relativa (RSI), configurações padrão;
- Oscilador estocástico com configurações 14, 3, 3.
Um sinal "para cima", ou uma opção Call de compra, aparece se várias condições forem atendidas:
- A média móvel vermelha cruza a média móvel azul de baixo para cima;
- O índice de força relativa está acima do nível 50;
- A linha estocástica rápida cruza a linha lenta (pontilhada) de baixo para cima.
- O movimento vermelho cruza o azul de cima para baixo;
- RSI está abaixo do nível 50;
- A linha rápida do oscilador estocástico cruza a lenta de cima para baixo.
//Sell (Put) if((ind_In1S1[1]>ind_In2S1[1]) && (ind_In1S1[2]>ind_In2S1[2])){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1S1[1]<ind_In2S1[1]) && (ind_In1S1[0]<ind_In2S1[0]) && (ind_In4S1[1]<50) && (ind_In4S1[0]<50) && (ind_In3S1_1[1]<ind_In3S1_2[1])){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if((ind_In1S1[1]<ind_In2S1[1]) && (ind_In1S1[2]<ind_In2S1[2])){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1S1[1]>ind_In2S1[1]) && (ind_In1S1[0]>ind_In2S1[0]) && (ind_In4S1[1]>50) && (ind_In4S1[0]>50) && (ind_In3S1_1[1]>ind_In3S1_2[1])){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Após o teste, obtemos o resultado:
- Depósito final 1964;
- Negociações lucrativas 1273;
- Negociações perdedoras 1822.
Após a otimização, obtemos o resultado. Como podemos ver, não obtivemos um aumento positivo em nosso depósito em nenhum período e tempo de expiração.
Estratégia "Maverick"
Vejamos uma estratégia fascinante e descomplicada para opções, chamada Maverick. Essa estratégia se fundamenta em dois indicadores de análise técnica e é conhecida por sua precisão ao determinar os momentos de entrada e saída. Ela é ideal para negociações com duração de 1 a 5 minutos, e para obter mais sinais, é possível abrir múltiplos gráficos com diferentes ativos simultaneamente.
Indicadores:
- Indicador Bollinger Bands com parâmetros 20 e StDev (desvio padrão) 2;
- Indicador RSI. Parâmetros do RSI - 4, com bordas de 80 e 20.
Previsão de crescimento. Compra de opção Call:
Depois que a linha do indicador RSI entra na zona de sobrevenda, abaixo de 20, e a linha de preço toca ou ultrapassa as Bandas de Bollinger, esperamos pela primeira vela de alta e abrimos uma negociação PARA CIMA.
Previsão de queda. Compra de opção Put:
Depois que a linha do indicador RSI entra na zona de sobrecompra, acima de 80, e a linha de preço ultrapassa os limites superiores do Bollinger, esperamos pela primeira vela de baixa e abrimos uma negociação PARA BAIXO.
Como gatilho nessa estratégia para um novo sinal, escolhi o fechamento da vela anterior dentro do canal do Bollinger. Abaixo está o código da estratégia.
//Sell (Put) if(iClose(symbolS1.Name(),XTimeFrame,1)<ind_In1S1_1[1]){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (iClose(symbolS1.Name(),XTimeFrame,2)>ind_In1S1_1[2]) && (ind_In2S1[2]>80) && (iClose(symbolS1.Name(),XTimeFrame,1)<iOpen(symbolS1.Name(),XTimeFrame,1))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if(iClose(symbolS1.Name(),XTimeFrame,1)>ind_In1S1_2[1]){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (iClose(symbolS1.Name(),XTimeFrame,2)<ind_In1S1_2[2]) && (ind_In2S1[2]<20) && (iClose(symbolS1.Name(),XTimeFrame,1)>iOpen(symbolS1.Name(),XTimeFrame,1))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Passemos à verificação. Testamos no período gráfico M5. Obtemos o resultado:
- Depósito final 3312;
- Negociações lucrativas 1589;
- Negociações perdedoras 1940.
O que obtivemos foi uma perda, embora o resultado seja um pouco melhor do que na estratégia anterior. Vamos realizar a otimização esperando valores positivos para o depósito. Mas, infelizmente, a estratégia não funciona:
Estratégia "Vortex+TSI"
Essa estratégia de opções binárias é chamada de Vortex, por causa do uso do indicador de mesmo nome. De fato, há dois indicadores envolvidos na estratégia - o principal e o secundário como filtro. O período gráfico sugerido é de 1 a 5 minutos.
Indicadores:
- Vortex com parâmetro 14;
- True Strength Indicator (TSI) com parâmetros 25, 13, 5, Exponencial.
Para compra de opção com o crescimento do preço:
- Espera até que ambos os indicadores se cruzem ao mesmo tempo, com as linhas azuis subindo e as linhas vermelhas descendo;
- As linhas do indicador Vortex devem divergir.
Para compra uma opção com a queda do preço:
- Espera até que ambos os indicadores se cruzem ao mesmo tempo, com as linhas vermelhas subindo e as linhas azuis descendo;
- As linhas do indicador Vortex devem divergir.
//Sell (Put) if(ind_In1S1_1[1]>ind_In1S1_2[1]){TrigerSell=1;} if ((TrigerSell==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1S1_1[0]<ind_In1S1_2[0]) && (ind_In1S1_1[1]<ind_In1S1_2[1]) && (ind_In2S1_1[0]<ind_In2S1_2[0]) && (ind_In2S1_1[1]<ind_In2S1_2[1]) && (ind_In2S1_1[0]<ind_In2S1_1[1]) && (ind_In2S1_2[0]>ind_In2S1_2[1]) && (ind_In2S1_1[1]<ind_In2S1_1[2]) && (ind_In2S1_2[1]>ind_In2S1_2[2])){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerSell=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if(ind_In1S1_1[1]<ind_In1S1_2[1]){TrigerBuy=1;} if ((TrigerBuy==1) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1S1_1[0]>ind_In1S1_2[0]) && (ind_In1S1_1[1]>ind_In1S1_2[1]) && (ind_In2S1_1[0]>ind_In2S1_2[0]) && (ind_In2S1_1[1]>ind_In2S1_2[1]) && (ind_In2S1_1[0]>ind_In2S1_1[1]) && (ind_In2S1_2[0]<ind_In2S1_2[1]) && (ind_In2S1_1[1]>ind_In2S1_1[2]) && (ind_In2S1_2[1]<ind_In2S1_2[2])){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); TrigerBuy=0; } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Procedemos ao teste de nossa estratégia com uso de indicadores. Testamos no período gráfico M5. Obtemos o resultado:
- Depósito final -3118;
- Negociações lucrativas 1914;
- Negociações perdedoras 2843.
Negociações perdedoras são muito mais do que as lucrativas. O depósito final foi negativo. Talvez a otimização ajude.
Os resultados da otimização falam por si:
Após testar mais umas 10 estratégias diferentes e não obter o resultado desejado, resolvi desenvolver minha própria estratégia. Com base na experiência adquirida de que os próprios indicadores não funcionam, decidi tentar uma abordagem diferente. Decidi chamar a estratégia pelo nome simples de "New".
Estratégia "New"
Usaremos as situações de sobrevenda e sobrecompra como ideia principal. Também decidimos adicionar o cálculo de média. Embora eu seja contra essa solução, é interessante experimentar o que acontecerá.
Indicadores:
Um indicador Envelopes com configurações padrão de 14, 0, 0,1 método Simole aplicado ao Close .
Um sinal "para cima" ou a compra de uma opção Call:
- O preço Ask é menor que a linha inferior do indicador Envelopes;
- A distância em pips da linha inferior do indicador Envelopes até o preço Ask é maior do que o valor Distance.
Sinal “para baixo” ou compra de uma opção Put:
- O preço de compra é maior que a linha superior do indicador Envelopes;
- A distância em pips da linha inferior do indicador Envelopes até o preço Bid é maior do que o valor Distance.
Essa estratégia não utiliza gatilho. Um novo sinal de entrada é monitorado continuamente se as condições forem atendidas e não houver nenhuma negociação aberta. Abaixo está o código da estratégia sem usar a média:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((OptionRate*ProfitPercent)/100); Profit++; } else{ XStartDepo=XStartDepo-OptionRate; Loss++; } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Testamos no período gráfico de 5 minutos. Parâmetro Distance=150. O resultado do teste sem usar o cálculo da média é mostrado na captura de tela abaixo:
Negociações perdedoras 804.
As entradas lucrativas superam as perdedoras, mas perdemos parte do depósito. É isso: retorno esperado negativo. Com essa abordagem, a série máxima de entradas perdedoras consecutivas foi de 2, o que considero bom para fazermos a média.O resultado da otimização sem usar a média está na captura de tela abaixo. Optou-se por incluir no relatório apenas situações lucrativas por conveniência e clareza:
Vamos adicionar o cálculo da média. Decidimos limitar o número de entradas com cálculo da média. Para isso, introduzimos um novo parâmetro Averaging, cujo valor padrão é 4. Abaixo está o código da estratégia com cálculo de média:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+(((XOptionRate*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-(XOptionRate*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+(((XOptionRate*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-(XOptionRate*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Resultados de teste com média. Viva, conseguimos:
Resultados de otimização com média:
Resultados de uma variante mais interessante com a multiplicação da aposta depois de negociações perdedoras. Abaixo está o código:
//Sell (Put) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (BidS1>(ind_In1S1_1[0]+(Distance*PointS1)))){ OpenSell(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_SELL, Magic, 0)>0){ XStartDepo=XStartDepo+((((XOptionRate*LossIn)*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-((XOptionRate*LossIn)*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment); } //Buy (Call) if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (AskS1<(ind_In1S1_2[0]-(Distance*PointS1)))){ OpenBuy(symbolS1.Name(), 0.01, 0, 0, EAComment); Print(((XOptionRate*LossIn)*LossIn)); } if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)>0) && (TimeCurrent()>=(GetTime(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)+(XExpirationTime*60)))){ if(GetProfit(symbolS1.Name(), POSITION_TYPE_BUY, Magic, 0)>0){ XStartDepo=XStartDepo+((((XOptionRate*LossIn)*LossIn)*ProfitPercent)/100); Profit++; LossIn=1; } else{ XStartDepo=XStartDepo-((XOptionRate*LossIn)*LossIn); Loss++; LossIn++; if(LossIn>Averaging){LossIn=1;} } Comment("Depo = ",XStartDepo," Profit = ",Profit," Loss = ",Loss); ClosePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment); }
Resultados da otimização de uma variante interessante:
Considerações finais
Que conclusões podem ser tiradas de todo esse trabalho? Que 99% de todas as estratégias baseadas em indicadores praticamente não funcionam. Se mudarmos um pouco a abordagem, é possível desenvolver uma boa estratégia que trará lucro. É necessário verificar tudo antes de usá-lo no mercado, e o MetaTrader 5 sempre nos ajudará nisso. A propósito, já existem opções com 100% de lucratividade, o que dá mais o que pensar. Você pode baixar todas as estratégias apresentadas aqui na forma de Expert Advisors no arquivo anexo. Obrigado por sua atenção, amigos, e até breve.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/12103
![Como escolher um Expert Advisor: Vinte caraterísticas de um robô de baixa qualidade](https://c.mql5.com/2/0/Avatar_Twenty_strong_criteria_to_reject_a_trading_bot.png)
![Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 12): Nascimento do SIMULADOR (II)](https://c.mql5.com/2/54/replay-p12-avatar.png)
![Exemplo de criação da estratégia de negociação abrangente Owl](https://c.mql5.com/2/0/Example_of_creating_Avatar.png)
![Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 11): Nascimento do SIMULADOR (I)](https://c.mql5.com/2/54/Desenvolvendo_um_sistema_de_Replay_Parte_11_Avatar.png)
![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso