OrderSend() ou CTrade

Samuel Manoel De Souza  

Gostaria saber se usar a Classe CTrade funciona da mesma forma que a função OrderSend(). Estou tentando usar a Classe CTrade por que pode passar as informações da operação através de parâmetros em vez que ter que preencher todos os dados para usar OrderSend(), porém não está funcionando e já tentei usando a função PositionOpen, Buy e Sell, mas não consigo fazer elas funcionarem no backteste do EA.

Outra coisa: O indicador estocástico não aparece na tela na hora do backteste. 

Esse é o código:

//+------------------------------------------------------------------+
//|                                            Teste de CClasses.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Descrição da Estratégia                                          |
//+------------------------------------------------------------------+
/*
   ________________________
   ANÁLISE PRELIMINAR
   Se Check == false
  
      Check COMPRA x VENDA
         Se %D e %K < sobrevenda no Kandle[2];
            Compra = TRUE;
            Check = TRUE;
            
         Senão Se %D e %K > sobrecompra no Kandle[2];
            Venda = TRUE;
            Check = TRUE;
   ________________________
   VERIFICAR SE TEM POSIÇÃO EM ABERTO
   Se Comprado == TRUE
      Se %D<%K
         Feche todas as posições comradas
   Senão Vendido == TRUE
      Se %D>%K
         Feche todas as posições vendidas
  
   ________________________
   ABERTURA DE POSIÇÃO  
   Se Compra == True
      COMPRA
      Se %D>%K e %K>sobrevenda
         ordem de comra
         Compra = FALSE;
         Check = FALSE;
      
   Senão Se Venda ==True
      VENDA
      Se %D<%K e %K<sobrecompra
         ordem de venda
         Venda = FALSE;
         Check = FALSE;

*/


//+------------------------------------------------------------------+

//| Declaração de Classes de Funções                                 |

//+------------------------------------------------------------------+

/*

   --------------------Referências no site MGL5----------------------

   Indicadores    https://www.mql5.com/pt/docs/standardlibrary/technicalindicators
   Array          https://www.mql5.com/pt/docs/standardlibrary/datastructures
   Negociação     https://www.mql5.com/pt/docs/standardlibrary/tradeclasses
   Strings        https://www.mql5.com/pt/docs/standardlibrary/stringoperations
   Paineis        https://www.mql5.com/pt/docs/standardlibrary/controls
   Gráficos       https://www.mql5.com/pt/docs/standardlibrary/chart_object_classes
  
*/

//Inclusão de bibliotecas
#include <Trade\Trade.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Indicators\Oscilators.mqh>
#include <Trade\SymbolInfo.mqh>

//Declaração das classes de funções
CTrade         trade;         //Classe para a execução de operações de negociação
CAccountInfo   conta_info;    //CAccountInfo classe fornece acesso fácil às propriedades da conta de negociação atualmente abertas.
COrderInfo     ordem_info;    //A classe COrderInfo fornece acesso às propriedades das ordens pendente.
CPositionInfo  posicao_info;  //A clase CPositionInfo possibilita o fácil acesso às propriedades de abertura de posição.
CiStochastic   stochastic;    //A classe CiStochastic fornece a criação, setup e acesso aos dados do indicador Stochastic Oscillator.

//+------------------------------------------------------------------+
//| Entradas de dados                                                |
//+------------------------------------------------------------------+
input double Profit = 50.00;//Ganho Máximo(R$)
input double Loss = 150.00;//Perda Máxima(R$)
input double lote = 100;//Numero de Lotes
input int K = 34;//%K
input int D = 5;//%D
input int Retardar = 17;//Suavizar
input int sobrecompra = 80;//Sobrecompra
input int sobrevenda = 20;//Sobrevenda
input ENUM_MA_METHOD MA_Method = MODE_SMMA;//Tipo de Media
input ENUM_STO_PRICE Sto_Price = STO_LOWHIGH;//Preço Base

//+------------------------------------------------------------------+
//| Outras variáveis                                                 |
//+------------------------------------------------------------------+
double K_2,D_2,K_1,D_1;
bool check = false, compra = false, venda = false;
int Magic_Number = 123456;
double SL,TP;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
      K_2 = stochastic.Main(2);
      D_2 = stochastic.Signal(2);
      K_1 = stochastic.Main(1);
      D_1 = stochastic.Signal(1);
      
      if(D_2<0 || K_2<0 || D_1<0 || K_1<0)
      {
         Alert("Error Creating Handles for indicators - error: ",GetLastError(),"!!");
      }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
      ZeroMemory(K_1);
      ZeroMemory(K_2);
      ZeroMemory(D_1);
      ZeroMemory(D_2);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
      //--------------------------------------------------------------
      // Vrificar se a Kandles suficientes para os calculos
      if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
      {
         Alert("We have less than 60 bars, EA will now exit!!");
         return;
      }
      //--------------------------------------------------------------
      //As verificações devem ser feitas a cada Kandle. Então sair da função se não formou novo Kandle;
      static datetime Old_Time;
      datetime New_Time[1];
      bool IsNewBar=false;
      int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
      if(copied>0) // ok, the data has been copied successfully
      {
         if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
         {
            IsNewBar=true;   // if it isn't a first call, the new bar has appeared
            if(MQL5InfoInteger(MQL5_DEBUGGING)) Comment("We have new bar here ",New_Time[0]," old time was ",Old_Time);
            Old_Time=New_Time[0];            // saving bar time
         }
      }
      else
      {
         Alert("Error in copying historical times data, error =",GetLastError());
         ResetLastError();
         return;
      }
      if(IsNewBar==false)
      {
         return;
      }
      //--------------------------------------------------------------
      //Definição de estruturas para análise do indicador
      /*
      MqlTradeRequest request;
      MqlTradeResult result;
      MqlTick last_price;
      MqlRates rates;
      ZeroMemory(request);
      */

      //--------------------------------------------------------------
      //Atualização do valor das variaveis
      K_2 = stochastic.Main(2);
      D_2 = stochastic.Signal(2);
      K_1 = stochastic.Main(1);
      D_1 = stochastic.Signal(1);
      if(K_1 < 0 || K_2 < 0 || D_1 < 0 || D_2 < 0)
      {
         Alert("Erro ao obetor os valores do Oscilador");
         return;
      }
      
      if(check==false)//Análise Preliminar
      {
         if(K_2 < sobrevenda && D_2 < sobrevenda)//Veririfica interesse em compra
         {
            Comment("SOBREVENDIDO");
            compra = true;
            check = true;
         }
         else if(K_2 > sobrecompra && K_2 > sobrecompra)//Verifica interesse em venda
         {
            Comment("SOBRECOMPRADO");
            venda = true;
            check = true;
         }
         else if(posicao_info.PositionType() == POSITION_TYPE_BUY)//Fecha posições compradas em consolidação
         {
            if(D_1 < K_1)
            {
               trade.PositionClose(_Symbol);
               return;
            }
         }
         else if(posicao_info.PositionType() == POSITION_TYPE_SELL)//Fecha posições vendidas em consolidação
         {
            if(D_1 > K_1)
            {
               trade.PositionClose(_Symbol);
               return;
            }
         }
         else return;
      }
      //-------------------------------------------------------------
      //Ultima análise e ABERTURA DE POSIÇÃO
      //-------------------------------------------------------------
     if(compra == true)
      {
         if(D_1 > K_1 && K_1 > sobrevenda)//Ultima condição para compra
         {
            compra = false;
            check = false;
            //Fechando posições vendidas
            if(PositionsTotal()==true) if(posicao_info.PositionType() == POSITION_TYPE_SELL) trade.PositionClose(_Symbol);
            //Abrindo posição comprada
            SL = SymbolInfoDouble(_Symbol,SYMBOL_ASK) - Loss;
            TP = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + Profit;
            trade.Buy(lote,_Symbol,SymbolInfoDouble(_Symbol,SYMBOL_ASK),SL,TP);//Usando a função CTrade para compra
         }
      }
      else if(venda == true)
      {
         if(D_1 < K_1 && K_1 < sobrecompra)//Ultima condição para compra
         {
            venda = false;
            check = false;
            //Fechando posições compradas
            if(PositionsTotal()==true) if(posicao_info.PositionType() == POSITION_TYPE_BUY) trade.PositionClose(_Symbol);
            //Abrindo posição vendida
            SL = SymbolInfoDouble(_Symbol,SYMBOL_BID) + Loss;
            TP = SymbolInfoDouble(_Symbol,SYMBOL_BID) - Profit;
            trade.Sell(lote,_Symbol,SymbolInfoDouble(_Symbol,SYMBOL_BID),SL,TP);////Usando a função CTrade para venda
         }
      }
      
      return;
  }
//+------------------------------------------------------------------+
Negociação Automatizada e Análise de Estratégia
Negociação Automatizada e Análise de Estratégia
  • www.mql5.com
MQL5: linguagem de estratégias de negociação inseridas no Terminal do Cliente MetaTrader 5. A linguagem permite escrever seus próprios sistemas automáticos de negócios, indicadores técnicos, scripts e bibliotecas de funções
Rogerio Figurelli  
Samuel Manoel de Souza:

Gostaria saber se usar a Classe CTrade funciona da mesma forma que a função OrderSend(). Estou tentando usar a Classe CTrade por que pode passar as informações da operação através de parâmetros em vez que ter que preencher todos os dados para usar OrderSend(), porém não está funcionando e já tentei usando a função PositionOpen, Buy e Sell, mas não consigo fazer elas funcionarem no backteste do EA.

Outra coisa: O indicador estocástico não aparece na tela na hora do backteste. 

Esse é o código:...

Olá Samuel,

A classe CTrade utiliza a OrderSend(), abstraindo o acesso dessa função, mas não funciona exatamente da mesma forma, justamente porque faz um tratamento próprio dos estados operacionais e do retorno da função.

Ainda mais se considerarmos questões específicas dos diferentes mercados, como Forex e BM&FBovespa. 

Note também que no seu código não existe nenhum tratamento do retorno de trade.Buy e/ou trade.Sell, o que certamente irá facilitar resolver problemas assim, e que também considero fundamental para qualquer robô.

Para ajudar na solução, recomendo leres o artigo https://www.mql5.com/en/articles/481 que irá facilitar esse entendimento.

Sds.,

Rogério Figurelli 

Trade Operations in MQL5 - It's Easy
Trade Operations in MQL5 - It's Easy
  • 2012.08.21
  • MetaQuotes Software Corp.
  • www.mql5.com
Almost all traders come to market to make money but some traders also enjoy the process itself. However, it is not only manual trading that can provide you with an exciting experience. Automated trading systems development can also be quite absorbing. Creating a trading robot can be as interesting as reading a good mystery novel.
Samuel Manoel De Souza  
Rogerio Figurelli:

Olá Samuel,

A classe CTrade utiliza a OrderSend(), abstraindo o acesso dessa função, mas não funciona exatamente da mesma forma, justamente porque faz um tratamento próprio dos estados operacionais e do retorno da função.

Ainda mais se considerarmos questões específicas dos diferentes mercados, como Forex e BM&FBovespa. 

Note também que no seu código não existe nenhum tratamento do retorno de trade.Buy e/ou trade.Sell, o que certamente irá facilitar resolver problemas assim, e que também considero fundamental para qualquer robô.

Para ajudar na solução, recomendo leres o artigo https://www.mql5.com/en/articles/481 que irá facilitar esse entendimento.

Sds.,

Rogério Figurelli 

Obrigado, pela resposta. Já consegui entender como funciona o CTrade. Porém tenho outro problema. Fiz um novo código e testei com média móvel e funcionou corretamente. Então troquei para Stochastic, mas o oscilador não aparece.

Fiz Array e copybuffer da mesma forma que na média móvel e não foi reportado nenhum erro.

Segue o código; 

//+------------------------------------------------------------------+

//|                                                 TraderExpert.mq5 |

//|                                           Samuel Manoel de Souza |

//|                               Samuelmanoeldesouza@outlook.com.br |

//+------------------------------------------------------------------+

#property copyright "Samuel Manoel de Souza"

#property link      "Samuelmanoeldesouza@outlook.com.br"

#property version   "1.00"





#include <Trade\Trade.mqh>

CTrade trade;



input double Loss = 30;

input double Profit = 100;

input double Lote = 1.00;

input int K_period = 34;

input int D_period = 5;

input int Retadar = 17;

input int Sobrecompra = 80;

input int Sobrevenda = 20;

input ENUM_MA_METHOD Sto_Method = MODE_SMA;

input ENUM_STO_PRICE Price_Method= STO_LOWHIGH;

double SL,TP;

int StoHandle;

double K_Position[];

double D_Position[];

bool check, compra, venda;



//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//---

      StoHandle = iStochastic(_Symbol,_Period,K_period,D_period,Retadar,Sto_Method,Price_Method);

      if(!ArraySetAsSeries(K_Position,true))

      {

         Alert("Erro linha 37. Erro: ",GetLastError());

         return 0;

      }

      if(!ArraySetAsSeries(D_Position,true))

      {

         Alert("Erro linha 42. Erro: ",GetLastError());

         return 0;

      }

      check = false; compra = false; venda = false;

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

      IndicatorRelease(StoHandle);

      

      

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

      if(!CopyBuffer(StoHandle,0,0,3,K_Position))

      {

         Alert("Erro linha 66. Erro: ",GetLastError());

         return;

      }

      if(!CopyBuffer(StoHandle,1,0,3,D_Position))

      {

         Alert("Erro linha 71. Erro: ",GetLastError());

         return;

      }

      

      //===============================================================

      //TRECHO DE CÓDIGO DE https://www.mql5.com/pt/articles/100

      static datetime Old_Time;

      datetime New_Time[1];

      bool IsNewBar=false;



   // copying the last bar time to the element New_Time[0]

      int copied=CopyTime(_Symbol,_Period,0,1,New_Time);

      if(copied>0) // ok, the data has been copied successfully

      {

         if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time

         {

            IsNewBar=true;   // if it isn't a first call, the new bar has appeared

            if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);

            Old_Time=New_Time[0];            // saving bar time

         }

      }

      else

      {

         Alert("Error in copying historical times data, error =",GetLastError());

         ResetLastError();

         return;

      }



//--- EA should only check for new trade if we have a new bar

      if(IsNewBar==false)

      {

         return;

      }



//--- Do we have enough bars to work with

      int Mybars=Bars(_Symbol,_Period);

      if(Mybars<60) // if total bars is less than 60 bars

      {

         Alert("We have less than 60 bars, EA will now exit!!");

         return;

      }

      //================================================================

      //ANALISE DO INDICADOR

      if(check == false)

      {

         if(K_Position[2]<Sobrevenda && D_Position[2]<Sobrevenda)

         {

            compra = true;

            check = true;

         }

         else if(K_Position[2]>Sobrecompra && D_Position[2]>Sobrecompra)

         {

            venda = true;

            check = true;

         }

         else return;

      }

      

      

      if(compra == true) if(K_Position[1]>Sobrevenda && D_Position[1]>Sobrevenda)

      {

         ordem_compra();//Chama a função descrita no final

         compra = false;

         check = false;

         return;

      }

      if(venda == true) if(K_Position[1]<Sobrecompra && D_Position[1]<Sobrecompra)

      {

         ordem_venda();//Chama a função descrita no final

         venda = false;

         check = false;

         return;

      }

      

  }

//+------------------------------------------------------------------+



void ordem_compra()

{

   //=============================================================

      //Modelo ordem de compra

      if(PositionSelect(_Symbol)==true)

         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)

            trade.PositionClose(PositionGetTicket(0),-1);

         else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)

         {

            Print("Já existe uma posição comprada. Erro: ",GetLastError());

            return;

         }

      SL = SymbolInfoDouble(_Symbol,SYMBOL_ASK) - Loss;

      TP = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + Profit;

      if(!trade.Buy(Lote,_Symbol,SymbolInfoDouble(_Symbol,SYMBOL_ASK),SL,TP,NULL))

      {

         Print("Compra não sucedida. Erro: ",GetLastError());

         return;

      }

      Print("Compra Sucedida! Ordem: ",trade.ResultRetcode(),"\t", trade.ResultRetcodeDescription());

}



void ordem_venda()

{

   //=============================================================

      //Modelo ordem de venda

      if(PositionSelect(_Symbol)==true)

         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)

            trade.PositionClose(PositionGetTicket(0),-1);

         else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)

         {

            Print("Já existe uma posição vendida. Erro: ",GetLastError());

            return;

         }

      SL = SymbolInfoDouble(_Symbol,SYMBOL_BID) + Loss;

      TP = SymbolInfoDouble(_Symbol,SYMBOL_BID) - Profit;

      if(!trade.Sell(Lote,_Symbol,SymbolInfoDouble(_Symbol,SYMBOL_BID),SL,TP,NULL))

      {

         Print("Venda não sucedida. Erro: ",GetLastError());

         return;

      }

      Print("Venda Sucedida! Ordem: ",trade.ResultRetcode(),"\t", trade.ResultRetcodeDescription());

}

Guia passo a passo para iniciantes para escrever um Expert Advisor no MQL5
Guia passo a passo para iniciantes para escrever um Expert Advisor no MQL5
  • 2013.12.24
  • Samuel Olowoyo
  • www.mql5.com
A programação de Expert Advisors no MQL5 é simples, e você pode aprender facilmente. Neste guia passo a passo, você verá os passos básicos necessários para escrever um simples Expert Advisor com base em uma estratégia de negócio de desenvolvimento. São apresentados, a estrutura de um Expert Advisor, o uso de indicadores técnicos embutidos e funções de negociação, os detalhes do modo de Depuração e uso do Strategy Tester.
Rogerio Figurelli  
Samuel Manoel de Souza:

Obrigado, pela resposta. Já consegui entender como funciona o CTrade. Porém tenho outro problema. Fiz um novo código e testei com média móvel e funcionou corretamente. Então troquei para Stochastic, mas o oscilador não aparece.

Fiz Array e copybuffer da mesma forma que na média móvel e não foi reportado nenhum erro.

Segue o código; 

Olá Samuel,

Na próxima vez utilize o botão SRC para inserir códigos fonte (já arrumei seu post).

Quando você diz que o oscilador não aparece, está se referindo à tela de simulação ou ao gráfico de instalação do robô?

Sds.,

Rogério Figurelli

Samuel Manoel De Souza  
Rogerio Figurelli:

Olá Samuel,

Na próxima vez utilize o botão SRC para inserir códigos fonte (já arrumei seu post).

Quando você diz que o oscilador não aparece, está se referindo à tela de simulação ou ao gráfico de instalação do robô?

Sds.,

Rogério Figurelli

Não aparece na simulação; Verifiquei aqui e quando inicio a simulação carrega todos os arquivos mas informar um erro ao carregar o ocilador. O erro é 4002, segundo a referencia MQL5 - Parâmetro errado na chamada interna da função do terminal cliente.

Samuel Manoel De Souza  
Rogerio Figurelli:

Olá Samuel,

Na próxima vez utilize o botão SRC para inserir códigos fonte (já arrumei seu post).

Quando você diz que o oscilador não aparece, está se referindo à tela de simulação ou ao gráfico de instalação do robô?

Sds.,

Rogério Figurelli

Obrigado pela atenção. Testei cada parâmetro e Consegui resolver o problema. Não sei por qual motivo o compilador não reconheceu a variável Price_Method como variável de entrada. Troquei o nome da variavel para Price e funcionou.

Grato. 

Rogerio Figurelli  
Samuel Manoel de Souza:

Obrigado pela atenção. Testei cada parâmetro e Consegui resolver o problema. Não sei por qual motivo o compilador não reconheceu a variável Price_Method como variável de entrada. Troquei o nome da variavel para Price e funcionou.

Grato. 

Ótimo, obrigado por compartilhar.
Razão: