IMPLEMENTAR MARTINGALE NO EA - página 2

 
savio95:

Então, é exatamente essa a lógica que eu estava usando, com exceção desse "*-1". Mas tentei dessa forma que você colocou acima e também não funcionou.
Quando insiro essa funcionalidade o EA não abre ordens.

 
Não sei se os valores retornados estão em outro formato, e ao comparar com os valores inputados está dando alguma irregularidade.. 
Ou se eu estou inserindo a rotina no local errado.. Eu coloquei a rotina no final do EA, abaixo das funções (void) de traillingstop e breakeven.

olá Savio,

o "-1" é importante para transformar o valor inputado de perda máxima em negativo, a não ser que vc já input este valor como negativo, aí o "-1" ficaria errado. Pode postar o código para eu testar?

 
savio95:

Então, é exatamente essa a lógica que eu estava usando, com exceção desse "*-1". Mas tentei dessa forma que você colocou acima e também não funcionou.
Quando insiro essa funcionalidade o EA não abre ordens.

 
Não sei se os valores retornados estão em outro formato, e ao comparar com os valores inputados está dando alguma irregularidade.. 
Ou se eu estou inserindo a rotina no local errado.. Eu coloquei a rotina no final do EA, abaixo das funções (void) de traillingstop e breakeven.

Bem estranho mesmo! Deveria funcionar!


Teste também o exemplo abaixo [ou informa limite de perdas negativo (-) ou na hora da verificação multiplica por -1 como sugerido pelo Armando Jr.]:

#include <Trade\Trade.mqh>
CTrade trade;
#include <Controls\Dialog.mqh>

//+------------------------------------------------------------------+
//|                        DADOS DO INDICADOR                        |
//+------------------------------------------------------------------+ 

#property indicator_chart_window
#property indicator_buffers 10
#property indicator_plots   4
#property indicator_label1  "Average"
#property indicator_type1   DRAW_COLOR_LINE
#property indicator_color1  clrDeepSkyBlue,clrPaleVioletRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_label2  "Upperband"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
#property indicator_label3  "Lowerband"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  2
#property indicator_label4  "Keltner MA trend"
#property indicator_type4   DRAW_COLOR_BARS
#property indicator_color4  clrDeepSkyBlue,clrPaleVioletRed
#property indicator_style4  STYLE_SOLID
//
enum enPrices
{
   pr_close,      // Close
   pr_open,       // Open
   pr_high,       // High
   pr_low,        // Low
   pr_median,     // Median
   pr_typical,    // Typical
   pr_weighted,   // Weighted
   pr_haclose,    // Heiken ashi close
   pr_haopen ,    // Heiken ashi open
   pr_hahigh,     // Heiken ashi high
   pr_halow,      // Heiken ashi low
   pr_hamedian,   // Heiken ashi median
   pr_hatypical,  // Heiken ashi typical
   pr_haweighted, // Heiken ashi weighted
   pr_haaverage   // Heiken ashi average
};
//
enum enMaModes
{
   ma_Simple,  // Simple moving average
   ma_Expo     // Exponential moving average
};
//
enum enMaVisble
{
   mv_Visible,    // Middle line visible
   mv_NotVisible  // Middle line not visible
};
//
enum enCandleMode
{
   cm_None,   // Do not draw candles nor bars
   cm_Bars,   // Draw as bars
   cm_Candles // Draw as candles
};
//
enum enAtrMode
{
   atr_Rng,   // Calculate using range
   atr_Atr    // Calculate using ATR
};

double                        channelBo[];
double                        channelBh[];
double                        channelBl[];
double                        channelBc[];
double                        channelUp[];
double                        channelDn[];
double                        ma[];
double                        colorBuffer[];
double                        colorBufferb[];
double                        countBuffer[];
ENUM_TIMEFRAMES               timeFrame;
int                           mtfHandle;
int                           atrHandle;
bool                          calculating;

//+------------------------------------------------------------------+
//|                      INPUTS DO INDICADOR                         |
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES         TimeFrame       = PERIOD_CURRENT;  // Time frame
input int                     MAPeriod        = 20;              // Moving average period
input enMaModes               MAMethod        = ma_Expo;         // Moving average type
input enMaVisble              MAVisible       = mv_Visible;      // Midlle line visible ?
input enPrices                Price           = pr_typical;      // Moving average price 
input color                   MaColorUp       = clrWhite;        // Color for slope up
input color                   MaColorDown     = clrWhite;        // Color for slope down
input int                     AtrPeriod       = 14;              // Range period
input double                  AtrMultiplier   = 0.4;             // Range multiplier
input enAtrMode               AtrMode         = atr_Rng;         // Range calculating mode 
input enCandleMode            ViewBars        = cm_None;         // View bars as :
input bool                    Interpolate     = true;            // Interpolate mtf data

input double                  DailyProfit     =  100.00;         // Daily profit limit
input double                  DailyLoss       = -100.00;         // Daily loss limit

input ulong                   magicNum = 123456;                 //Magic Number
input ulong                   desvPts = 0;                       //Desvio em Pontos
input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN;//Preenchimento da Ordem

//+------------------------------------------------------------------+
//|                        INPUTS DO ROBÔ                            |
//+------------------------------------------------------------------+
input double                  Contratos = 1;                     //Nº de Contratos
input double                  stopLoss = 250;                    //Stop Loss
input double                  takeProfit = 85;                   //Take Profit
input double                  gatilhoBE = 40;                    //Gatilho BreakEven
input double                  gatilhoTS = 50;                    //Gatilho TrailingStop
input double                  stepTS = 40;                       //Step TrailingStop

double                        PRC;                               //Preço normalizado
double                        STL;                               //StopLoss normalizado
double                        TKP;                               //TakeProfit normalizado

double                        Upperband[];
double                        Lowerband[];
double                        Average[];

bool                          posAberta;
bool                          ordPendente;
bool                          beAtivo;

MqlTick                       ultimoTick;
MqlRates                      rates[];

//Variaveis Globais Para Plotar Indicador no Gráfico\\
int                           handle_kc = INVALID_HANDLE;
int                           sub_window=(int)ChartGetInteger(0,0);

//Variaveis Globais do Controle de Operações no Mesmo Candle\\
bool                          Operamos_Nesta_Vela=false;
string                        TIME_Abertura_Ultimo_Candle;
string                        Hora_Ultimo_Negocio;
//
CAppDialog AppWindow;
//

int OnInit()
  {
      ChartSetInteger(0, CHART_SHOW_GRID, false);
      
//+------------------------------------------------------------------+
//|                  INSERIR NÚMERO DA CONTA MT5                     |
//+------------------------------------------------------------------+  
//      if (AccountInfoInteger(ACCOUNT_LOGIN) != 00000000)
//         {
//            Alert("Você está tentando utilizar o robô numa conta não permitida! Entre em contato com o criador no Telegram: @FitBot");
//            return(INIT_FAILED);
//         }
      
      handle_kc = iCustom(Symbol(), Period(), "KeltnerChannel.ex5", TimeFrame, MAPeriod, MAMethod, MAVisible, Price, MaColorUp, MaColorDown, AtrPeriod, AtrMultiplier, AtrMode, ViewBars, Interpolate);
      if(handle_kc==INVALID_HANDLE)
         {
            Print("Erro ao criar Keltner - erro", GetLastError());
            return(INIT_FAILED);
         }
      
      if(ChartIndicatorsTotal(0,0) < 1)
         {
            ChartIndicatorAdd(0,0,handle_kc);
         }
      
      ArraySetAsSeries(rates, true);
      ArraySetAsSeries(Upperband, true);
      ArraySetAsSeries(Lowerband, true);
      ArraySetAsSeries(Average, true);     
      
      trade.SetTypeFilling(preenchimento);
      trade.SetDeviationInPoints(desvPts);
      trade.SetExpertMagicNumber(magicNum);
      
//+------------------------------------------------------------------+
//|                     CRIA PAINEL NO GRÁFICO                       |
//+------------------------------------------------------------------+
   if(!AppWindow.Create(0,"FitBot_2.0",0,20,20,360,324))
      return(INIT_FAILED);

   int total=AppWindow.ControlsTotal();
   CWndClient*myclient;
   for(int i=0;i<total;i++)
     {
      CWnd*obj=AppWindow.Control(i);
      string name=obj.Name();
      PrintFormat("%d is %s",i,name);
      //--- cor 
      if(StringFind(name,"Client")>0)
        {
         CWndClient *client=(CWndClient*)obj;
         client.ColorBackground(clrRed);
         myclient=client;
         Print("client.ColorBackground(clrRed);");
         ChartRedraw();
        }
      
      if(StringFind(name,"Back")>0)
        {
         CPanel *panel=(CPanel*) obj;
         panel.ColorBackground(clrWhite);
         Print("panel.ColorBackground(clrWhite);");
         ChartRedraw();
        }
     }
   Sleep(500);
   myclient.Destroy();

   AppWindow.Run();
      
      return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
  ChartIndicatorDelete(0, sub_window, ChartIndicatorName(0, sub_window, 0));
  handle_kc=INVALID_HANDLE;

  AppWindow.Destroy(reason);
}

void OnTick()
  {               


. . .

            
      double ProfitD1 = CurrentDayProfit();
      if(ProfitD1 < DailyProfit && ProfitD1 > DailyLoss)
         {
            if(CheckTradePause(1) && rates[2].close > Lowerband[2] && rates[2].close < Upperband[2] && rates[1].open < Upperband[1] && rates[1].open > Lowerband[1] && rates[1].close > Upperband[1] && !posAberta && !ordPendente && Operamos_Nesta_Vela==false)
               {
                  PRC = NormalizeDouble(ultimoTick.ask, _Digits);
                  STL = NormalizeDouble(PRC - stopLoss, _Digits);
                  TKP = NormalizeDouble(PRC + takeProfit, _Digits);
                  if(trade.Buy(Contratos, _Symbol, PRC, STL, TKP, ""))
                     
                     Hora_Ultimo_Negocio=TimeToString(TimeCurrent(),TIME_SECONDS);  
          
                        Operamos_Nesta_Vela=true; 
               }
                     
       
               
            else if(CheckTradePause(1) && rates[2].close > Lowerband[2] && rates[2].close < Upperband[2] && rates[1].open < Upperband[1] && rates[1].open > Lowerband[1] && rates[1].close < Lowerband[1] && !posAberta && !ordPendente && Operamos_Nesta_Vela==false)
               {
                  PRC = NormalizeDouble(ultimoTick.bid, _Digits);
                  STL = NormalizeDouble(PRC + stopLoss, _Digits);
                  TKP = NormalizeDouble(PRC - takeProfit, _Digits);
                  if(trade.Sell(Contratos, _Symbol, PRC, STL, TKP, ""))
                    
                     Hora_Ultimo_Negocio=TimeToString(TimeCurrent(),TIME_SECONDS);
          
                        Operamos_Nesta_Vela=true; 
               }
         }
              
}
  
//+------------------------------------------------------------------+
//|                       FUNÇÃO TRAILLINGSTOP                       |
//+------------------------------------------------------------------+
void TrailingStop(double preco)
   {
      for(int i = PositionsTotal()-1; i>=0; i--)
         {
            string symbol = PositionGetSymbol(i);
            ulong magic = PositionGetInteger(POSITION_MAGIC);
            if(symbol == _Symbol && magic==magicNum)
               {
                  ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
                  double StopLossCorrente = PositionGetDouble(POSITION_SL);
                  double TakeProfitCorrente = PositionGetDouble(POSITION_TP);
                  if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                     {
                        if(preco >= (StopLossCorrente + gatilhoTS) )
                           {
                              double novoSL = NormalizeDouble (StopLossCorrente + stepTS, _Digits);
                              if(trade.PositionModify(PositionTicket, novoSL, TakeProfitCorrente))
                                 {
                                    Print("TrailingStop - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                 }
                              else
                                 {
                                    Print("TrailingStop - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                 }
                           }
                     }
                  else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
                     {
                        if(preco <= (StopLossCorrente - gatilhoTS) )
                           {
                              double novoSL = NormalizeDouble (StopLossCorrente - stepTS, _Digits);
                              if(trade.PositionModify(PositionTicket, novoSL, TakeProfitCorrente))
                                 {
                                    Print("TrailingStop - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                 }
                              else
                                 {
                                    Print("TrailingStop - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                 }
                           }
                     }
               }
         }
   }

//+------------------------------------------------------------------+
//|                          FUNÇÃO BREAKEVEN                        |
//+------------------------------------------------------------------+
void BreakEven(double preco)
   {
      for(int i = PositionsTotal()-1; i>=0; i--)
         {
            string symbol = PositionGetSymbol(i);
            ulong magic = PositionGetInteger(POSITION_MAGIC);
            if(symbol == _Symbol && magic == magicNum)
               {
                  ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
                  double PrecoEntrada = PositionGetDouble(POSITION_PRICE_OPEN);
                  double TakeProfitCorrente = PositionGetDouble(POSITION_TP);
                  if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                     {
                        if( preco >= (PrecoEntrada + gatilhoBE) )
                           {
                              if(trade.PositionModify(PositionTicket, PrecoEntrada, TakeProfitCorrente))
                                 {
                                    Print("BreakEven - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                    beAtivo = true;
                                 }
                              else
                                 {
                                    Print("BreakEven - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                 }
                           }                           
                     }
                  else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
                     {
                        if( preco <= (PrecoEntrada - gatilhoBE) )
                           {
                              if(trade.PositionModify(PositionTicket, PrecoEntrada, TakeProfitCorrente))
                                 {
                                    Print("BreakEven - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                    beAtivo = true;
                                 }
                              else
                                 {
                                    Print("BreakEven - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
                                 }
                           }
                     }
               }
         }
   }
   
//+------------------------------------------------------------------+
//|    Verifica se o intervalo para o próximo trade foi cumprido     |
//+------------------------------------------------------------------+
bool CheckTradePause(int nBars)
  {
   //--- Determina quantas barras até o próximo trade
   datetime time_start = iTime(_Symbol, PERIOD_CURRENT, nBars);

   if(HistorySelect(time_start, TimeCurrent()))
     {
      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         const ulong Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetInteger(Ticket, DEAL_MAGIC) == magicNum)
           {return(false);}
        }
     }
   else
     {
      Print("Erro ao recuperar o histórico de operações ...");
      return(false);
     }

   //--- Intervalo cumprido
   return(true);
  }

//+------------------------------------------------------------------+ 
//| Calcula o lucro / prejuízo do dia atual                          |
//+------------------------------------------------------------------+ 
double CurrentDayProfit()
  {
   datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400));
   double   result = 0.0;
   ulong    ticket;
   int      cnt;

   if(HistorySelect(time_start, TimeCurrent()))
     {
      for(cnt = HistoryDealsTotal() - 1; cnt >= 0; cnt--)
        {
         ticket = HistoryDealGetTicket(cnt);

         if(HistoryDealGetInteger(ticket, DEAL_MAGIC) == magicNum)
           {
            result += HistoryDealGetDouble(ticket, DEAL_PROFIT);
           }
        }
     }
   else
     {
      Print("Erro ao recuperar o histórico de operações...");
     }

   return(result);
  }
//+------------------------------------------------------------------+
//|    FUNÇÃO DO PAINEL EXIBIDO NO GRÁFICO (AINDA EM CONSTRUÇÃO)     |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // ID do evento  
                  const long& lparam,   // parâmetro do evento do tipo long
                  const double& dparam, // parâmetro do evento do tipo double
                  const string& sparam) // parâmetro do evento do tipo string
  {
   AppWindow.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+
 
Em relação ao Martingale, caso você queira mesmo implementar esse sistema, [AQUI] tem vários exemplos de códigos que utilizam esse recurso.
 
Vinicius de Oliveira:

Bem estranho mesmo! Deveria funcionar!


Teste também o exemplo abaixo [ou informa limite de perdas negativo (-) ou na hora da verificação multiplica por -1 como sugerido pelo Armando Jr.]:

Deu certo, tanto desse ultimo modo, quanto da forma com que o Armando tinha passado.
O problema era na hora de fazer o teste. Fazendo direto pelo meta editor ele só faz corretamente na primeira tentativa, se eu altero algum parâmetro e faço novamente, ele não funciona corretamente.
Mas fazendo direto no testador de estratégias está perfeito.
mas ele só leva em conta as operações fechadas. Depois vou tentar fazer com ele encerre as operações abertas ao atingir os limites diários.

Mas muito obrigado, Vinicius e Armando!!! Me ajudaram muito!

 
Vinicius de Oliveira:
Em relação ao Martingale, caso você queira mesmo implementar esse sistema, [AQUI] tem vários exemplos de códigos que utilizam esse recurso.

Passei a tarde toda tentando encaixar o martingale, mas to apanhando ainda!!
Vou acabar tendo que usar um exemplo que achei no youtube como base (https://www.youtube.com/watch?v=VBC5ArUszTU&amp;t=913s)
O triste é que para implementar da forma com que ele ensina eu vou ter, praticamente, que refazer do zero o EA. 
Tentei fazer de uma forma que não precisasse alterar tanta coisa, mas não rolou ainda.

 
savio95:

....

Ja pensou em usar o modo de debug e entender o que acontece com o seu algoritmo ?

 
Jonathan Pereira:

Ja pensou em usar o modo de debug e entender o que acontece com o seu algoritmo ?

Sim, irmão, com certeza! Sempre rodo no modo visual pra ver oq está saindo errado. Ele está funcionando certinho, tenho que arrumar pra ele ficar mais estético, os inputs e tal.. mas está funcionando certinho! 

Em relação ao MG, da forma que eu fiz, ele sempre aumentava o lote, independente de ter tomado o loss na operação anterior ou não. 
Preciso pegar melhor essa parte. Mas não achei nenhum material em pra tomar como base, não digo nem uma "código base" não, digo um artigo mesmo.

Só preciso inserir essa questão do MG e acertar ele pra fechar as posições a mercado quando atingir os limites diários.

Mas estou feliz com o desenvolvimento do EA, é o meu primeiro contato com esse mundo de programação.. estou apanhando mas está saindo! rs

 
savio95:

....

Eu não disse modo visual e sim modo de debug, assim vc consegue acompanhar passo a passo do seu algoritmo. Embora também seja um teste visual, vc tem acesso a trilha do algoritmo o que leva a um entendimento melhor do que se passa.

 
Documentação sobre MQL5: Manipulação de eventos / OnTradeTransaction
Documentação sobre MQL5: Manipulação de eventos / OnTradeTransaction
  • www.mql5.com
OnTradeTransaction - Manipulação de eventos - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
Razão: