Assist me in my EA Program to open new trades when one closes

 

Hello,

Please I am trying to write an ea that does this: Creates buy order and sell stop order when attached to chart, for example

buy order:      entry = 1.1200, sl = 1.1160, tp = 1.1240

sell stop:  entry = 1.1160, sl = 1.1200, tp = 1.1120

after buy trade hit stop loss and sell stop is now active, create a buy stop order

buy stop: entry  = 1.1200, sl = 1.1160, tp = 1.1240

and it goes on like that till one of them hits tp, then any available pending order will be deleted and the process starts again.

I've studied it backward and it looked really profitable(especially on GBP pairs) not having to worry about predicting market direction.

Attached is the code i wrote to open the first 2 orders based on moving average position but i'm stuck there. any help would be really really appreciated.

If possible, it will be nice to have a way of simulating live trades in the strategy tester area. i mean like having a fake balance on the chart and adding profits(trades that hit tp) to it or subtracting losses(trades that hit stop loss) from it so i can backtest it with more acccuracy to be sure about the profitability of it.

Thank you very much in advance for your help. my email is daenny99@gmail.com

Files:
 
  1. int OnInit(){
       enterTrade();
    
    Don't try to use any price or server related functions in OnInit (or on load,) as there may be no connection/chart yet:
    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  2. daenny

    after buy trade hit stop loss and sell stop is now active, create a buy stop order

    and it goes on like that till one of them hits tp, then any available pending order will be deleted and the process starts again.

    I've studied it backward and it looked really profitable(especially on GBP pairs) not having to worry about predicting market direction.

    You have no code that does that. OnTick only updates pre_OrdersTotal and does some Alerts.

  3. res3 = OrderSend( …
          if(res3 == false
    OrderSend does not return a boolean. Your test will never be true.
 
daenny:

Hello,

Please I am trying to write an ea that does this: Creates buy order and sell stop order when attached to chart, for example

buy order:      entry = 1.1200, sl = 1.1160, tp = 1.1240

sell stop:  entry = 1.1160, sl = 1.1200, tp = 1.1120

after buy trade hit stop loss and sell stop is now active, create a buy stop order

buy stop: entry  = 1.1200, sl = 1.1160, tp = 1.1240

and it goes on like that till one of them hits tp, then any available pending order will be deleted and the process starts again.

I've studied it backward and it looked really profitable(especially on GBP pairs) not having to worry about predicting market direction.

Attached is the code i wrote to open the first 2 orders based on moving average position but i'm stuck there. any help would be really really appreciated.

If possible, it will be nice to have a way of simulating live trades in the strategy tester area. i mean like having a fake balance on the chart and adding profits(trades that hit tp) to it or subtracting losses(trades that hit stop loss) from it so i can backtest it with more acccuracy to be sure about the profitability of it.

Thank you very much in advance for your help. my email is daenny99@gmail.com

//+------------------------------------------------------------------+
//|                                                   exampleEA2.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict



extern double Lots =0.01;
extern double Difference =300;
extern int TrailingStop=0;
extern int Slippage=3;
double Trade_Balance = 1000;
double RecordedPrice;
string RecordedDirection;
bool res1;
bool res2;
bool res3;
bool res4;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Comment("Balance: ", Trade_Balance);
   enterTrade();
//---
   return(INIT_SUCCEEDED);
  }
  
  
  
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
  
  
  
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
      //if(RecordedDirection == "Buy")
      //{
         //int takeProfit = RecordedPrice+Difference*Point;
         //int stopLoss = RecordedPrice-Difference*Point;
      //}
      
       CheckTrades();
      
       static bool first = true;
       static int pre_OrdersTotal = 0;
       int _OrdersTotal = OrdersTotal();
       Alert(_OrdersTotal);
    
       // If this is the first launch of the Expert, we don't know the amount of orders on the previous tick.
       // So just remeber it, mark that the first launch has been happened, and exit.
       if ( first )
       {
           pre_OrdersTotal = _OrdersTotal;
           first = false;
       }
    
       // Compare the amount of positions on the previous tick with the current amount
       // If it has been changed, display message
       if ( _OrdersTotal > pre_OrdersTotal ) 
           Alert( "The amount of positions increased! There were - ", pre_OrdersTotal, 
                                                            ", there are now - ", _OrdersTotal );
    
       if ( _OrdersTotal < pre_OrdersTotal )
           Alert( "The amount of positions decreased! There were - ", pre_OrdersTotal, 
                                                            ", there are now - ", _OrdersTotal );
    
       // Memorize the amount of positions
       pre_OrdersTotal = _OrdersTotal;
      
   
  }
  
  
  
  
  
//+------------------------------------------------------------------+
//| Expert special function                                             |
//+------------------------------------------------------------------+
void enterTrade()
  {
   
   if((iMA(NULL,0,50,0,MODE_EMA,PRICE_CLOSE,0)<Ask))                                                                          // Here is your open buy rule
   {
      
      res1 = OrderSend(Symbol(), OP_BUY, Lots, NormalizeDouble(Ask, Digits), Slippage, NormalizeDouble(Ask-Difference*Point, Digits), NormalizeDouble(Ask+Difference*Point, Digits), NULL, 0, 0, Green);                    // Enter a buy trade
      if(res1 == false){ Alert(GetLastError());} else{ RecordedPrice = Ask; RecordedDirection = "Buy"; }
      
      
      res2 = OrderSend(Symbol(), OP_SELLSTOP, Lots*2, NormalizeDouble(Ask-Difference*Point, Digits), Slippage, NormalizeDouble(Ask, Digits), NormalizeDouble(Ask-Difference*Point*2, Digits), NULL, 0, 0, Red);                    // Enter a buy trade
      if(res2 == false){ Alert(GetLastError());} else{  }
      
   }
   else if((iMA(NULL,0,50,0,MODE_EMA,PRICE_CLOSE,0)>Bid))                                                                          // Here is your open Sell rule
   {
      
      res3 = OrderSend(Symbol(), OP_SELL, Lots, NormalizeDouble(Bid, Digits), Slippage, NormalizeDouble(Bid+Difference*Point, Digits), NormalizeDouble(Bid-Difference*Point, Digits), NULL, 0, 0, Red);                    // Enter a buy trade
      if(res3 == false){ Alert(GetLastError());} else{  RecordedPrice = Bid; RecordedDirection = "Sell";  }
      
      res4 = OrderSend(Symbol(), OP_BUYSTOP, Lots*2, NormalizeDouble(Bid+Difference*Point, Digits), Slippage, NormalizeDouble(Bid, Digits), NormalizeDouble(Bid+Difference*Point*2, Digits), NULL, 0, 0, Green);                    // Enter a buy trade
      if(res4 == false){ Alert(GetLastError());} else{  }                                                                      // Give alert if error
       
   }
                              
  }
  


  
  

bool isOrderExist(const int _ticket)
 {
    if(OrderSelect(_ticket,SELECT_BY_TICKET)){
       return(OrderCloseTime()==0);
    }else{
       int error=GetLastError();
       return(error!=4108 && error!=4051);
    }
 }


void CheckTrades()
{
      if(OrdersTotalOpen(Symbol(),OP_BUY)>0 && OrdersTotalOpen(Symbol(),OP_SELLSTOP)==0)
      {
            res2 = OrderSend(Symbol(), OP_SELLSTOP, Lots*2, NormalizeDouble(Ask-Difference*Point, Digits), Slippage, NormalizeDouble(Ask, Digits), NormalizeDouble(Ask-Difference*Point*2, Digits), NULL, 0, 0, Red);                    // Enter a buy trade
            if(res2 == false){ Alert(GetLastError());} else{  }
      }
      else if(OrdersTotalOpen(Symbol(),OP_SELL)>0 && OrdersTotalOpen(Symbol(),OP_BUYSTOP)==0)
      {
            res4 = OrderSend(Symbol(), OP_BUYSTOP, Lots*2, NormalizeDouble(Bid+Difference*Point, Digits), Slippage, NormalizeDouble(Bid, Digits), NormalizeDouble(Bid+Difference*Point*2, Digits), NULL, 0, 0, Green);                    // Enter a buy trade
            if(res4 == false){ Alert(GetLastError());} else{  }   
      }
      else if(OrdersTotalOpen(Symbol(),OP_BUY)==0 && OrdersTotalOpen(Symbol(),OP_SELLSTOP)>0)
      {
            CloseAll(Symbol());
            enterTrade();
      }
      else if(OrdersTotalOpen(Symbol(),OP_SELL)==0 && OrdersTotalOpen(Symbol(),OP_BUYSTOP)>0)
      {
            CloseAll(Symbol());
            enterTrade();
      }
      
}


int OrdersTotalOpen(string pair,int type)
{
      int cc=0;
      for(int i=0; i<OrdersTotal(); i++)
      {
           if(OrderSelect(i,SELECT_BY_POS) && 
              (OrderSymbol()==pair || pair=="") && 
              OrderType()==type )
           {
               //if(OrderComment()!=com) continue;
               cc++;    
           }
      }
      return(cc);
}


void CloseAll(string tc)
{
 for(int i=OrdersTotal()-1;i>=0;i--)
 {
    int t = OrderSelect(i, SELECT_BY_POS);
    if ( tc==OrderSymbol())
    {
        bool result = false;
        if ( OrderType() == OP_BUY )    result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
        if ( OrderType() == OP_SELL )   result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
        if ( OrderType()==OP_BUYSTOP)   if(OrderDelete(OrderTicket())){}                                      
        if ( OrderType()==OP_SELLSTOP)  if(OrderDelete(OrderTicket())){}
        if ( OrderType()==OP_BUYLIMIT)  if(OrderDelete(OrderTicket())){}                                      
        if ( OrderType()==OP_SELLLIMIT) if(OrderDelete(OrderTicket())){}
    }    
 }
  return; 
}
//+------------------------------------------------------------------+
 
Joel Protusada:

Pls double check. I haven't tested it.

 

If you are trying to make a martingale, you should try this one.

//+------------------------------------------------------------------+
//|                                                   exampleEA2.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict



extern double Lots =0.01;
extern double Difference =300;
extern int TrailingStop=0;
extern int Slippage=3;
double Trade_Balance = 1000;
double RecordedPrice;
string RecordedDirection;
bool res1;
bool res2;
bool res3;
bool res4;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Comment("Balance: ", Trade_Balance);
   enterTrade();
//---
   return(INIT_SUCCEEDED);
  }
  
  
  
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
  
  
  
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
      //if(RecordedDirection == "Buy")
      //{
         //int takeProfit = RecordedPrice+Difference*Point;
         //int stopLoss = RecordedPrice-Difference*Point;
      //}
      
       CheckTrades();
      
       static bool first = true;
       static int pre_OrdersTotal = 0;
       int _OrdersTotal = OrdersTotal();
       Alert(_OrdersTotal);
    
       // If this is the first launch of the Expert, we don't know the amount of orders on the previous tick.
       // So just remeber it, mark that the first launch has been happened, and exit.
       if ( first )
       {
           pre_OrdersTotal = _OrdersTotal;
           first = false;
       }
    
       // Compare the amount of positions on the previous tick with the current amount
       // If it has been changed, display message
       if ( _OrdersTotal > pre_OrdersTotal ) 
           Alert( "The amount of positions increased! There were - ", pre_OrdersTotal, 
                                                            ", there are now - ", _OrdersTotal );
    
       if ( _OrdersTotal < pre_OrdersTotal )
           Alert( "The amount of positions decreased! There were - ", pre_OrdersTotal, 
                                                            ", there are now - ", _OrdersTotal );
    
       // Memorize the amount of positions
       pre_OrdersTotal = _OrdersTotal;
      
   
  }
  
  
  
  
  
//+------------------------------------------------------------------+
//| Expert special function                                             |
//+------------------------------------------------------------------+
void enterTrade()
  {
   
   if((iMA(NULL,0,50,0,MODE_EMA,PRICE_CLOSE,0)<Ask))                                                                          // Here is your open buy rule
   {
      
      res1 = OrderSend(Symbol(), OP_BUY, Lots, NormalizeDouble(Ask, Digits), Slippage, NormalizeDouble(Ask-Difference*Point, Digits), NormalizeDouble(Ask+Difference*Point, Digits), NULL, 0, 0, Green);                    // Enter a buy trade
      if(res1 == false){ Alert(GetLastError());} else{ RecordedPrice = Ask; RecordedDirection = "Buy"; }
      
      
      res2 = OrderSend(Symbol(), OP_SELLSTOP, Lots*2, NormalizeDouble(Ask-Difference*Point, Digits), Slippage, NormalizeDouble(Ask, Digits), NormalizeDouble(Ask-Difference*Point*2, Digits), NULL, 0, 0, Red);                    // Enter a buy trade
      if(res2 == false){ Alert(GetLastError());} else{  }
      
   }
   else if((iMA(NULL,0,50,0,MODE_EMA,PRICE_CLOSE,0)>Bid))                                                                          // Here is your open Sell rule
   {
      
      res3 = OrderSend(Symbol(), OP_SELL, Lots, NormalizeDouble(Bid, Digits), Slippage, NormalizeDouble(Bid+Difference*Point, Digits), NormalizeDouble(Bid-Difference*Point, Digits), NULL, 0, 0, Red);                    // Enter a buy trade
      if(res3 == false){ Alert(GetLastError());} else{  RecordedPrice = Bid; RecordedDirection = "Sell";  }
      
      res4 = OrderSend(Symbol(), OP_BUYSTOP, Lots*2, NormalizeDouble(Bid+Difference*Point, Digits), Slippage, NormalizeDouble(Bid, Digits), NormalizeDouble(Bid+Difference*Point*2, Digits), NULL, 0, 0, Green);                    // Enter a buy trade
      if(res4 == false){ Alert(GetLastError());} else{  }                                                                      // Give alert if error
       
   }
                              
  }
  


  
  

bool isOrderExist(const int _ticket)
 {
    if(OrderSelect(_ticket,SELECT_BY_TICKET)){
       return(OrderCloseTime()==0);
    }else{
       int error=GetLastError();
       return(error!=4108 && error!=4051);
    }
 }


void CheckTrades()
{
      if(OrdersTotalOpen(Symbol(),OP_BUY)>0 && OrdersTotalOpen(Symbol(),OP_SELLSTOP)==0)
      {
            res2 = OrderSend(Symbol(), OP_SELLSTOP,OrdersTotalLS(Symbol(),OP_BUY)*2 , NormalizeDouble(Ask-Difference*Point, Digits), Slippage, NormalizeDouble(Ask, Digits), NormalizeDouble(Ask-Difference*Point*2, Digits), NULL, 0, 0, Red);                    // Enter a buy trade
            if(res2 == false){ Alert(GetLastError());} else{  }
      }
      else if(OrdersTotalOpen(Symbol(),OP_SELL)>0 && OrdersTotalOpen(Symbol(),OP_BUYSTOP)==0)
      {
            res4 = OrderSend(Symbol(), OP_BUYSTOP, OrdersTotalLS(Symbol(),OP_SELL)*2, NormalizeDouble(Bid+Difference*Point, Digits), Slippage, NormalizeDouble(Bid, Digits), NormalizeDouble(Bid+Difference*Point*2, Digits), NULL, 0, 0, Green);                    // Enter a buy trade
            if(res4 == false){ Alert(GetLastError());} else{  }   
      }
      else if(OrdersTotalOpen(Symbol(),OP_BUY)==0 && OrdersTotalOpen(Symbol(),OP_SELLSTOP)>0)
      {
            CloseAll(Symbol());
            enterTrade();
      }
      else if(OrdersTotalOpen(Symbol(),OP_SELL)==0 && OrdersTotalOpen(Symbol(),OP_BUYSTOP)>0)
      {
            CloseAll(Symbol());
            enterTrade();
      }
      
}


int OrdersTotalOpen(string pair,int type)
{
      int cc=0;
      for(int i=0; i<OrdersTotal(); i++)
      {
           if(OrderSelect(i,SELECT_BY_POS) && 
              (OrderSymbol()==pair || pair=="") && 
              OrderType()==type )
           {
               //if(OrderComment()!=com) continue;
               cc++;    
           }
      }
      return(cc);
}


void CloseAll(string tc)
{
 for(int i=OrdersTotal()-1;i>=0;i--)
 {
    int t = OrderSelect(i, SELECT_BY_POS);
    if ( tc==OrderSymbol())
    {
        bool result = false;
        if ( OrderType() == OP_BUY )    result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
        if ( OrderType() == OP_SELL )   result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
        if ( OrderType()==OP_BUYSTOP)   if(OrderDelete(OrderTicket())){}                                      
        if ( OrderType()==OP_SELLSTOP)  if(OrderDelete(OrderTicket())){}
        if ( OrderType()==OP_BUYLIMIT)  if(OrderDelete(OrderTicket())){}                                      
        if ( OrderType()==OP_SELLLIMIT) if(OrderDelete(OrderTicket())){}
    }    
 }
  return; 
}


double OrdersTotalLS(string pair,int type)
{
      double cc=0;
      for(int i=0; i<OrdersTotal(); i++)
      {
           if(OrderSelect(i,SELECT_BY_POS) && 
              OrderSymbol()==pair && 
              OrderType()==type )
           {
               cc+=OrderLots();    
           }
      }
      return(cc);
}
//+------------------------------------------------------------------+


 
Joel Protusada:

If you are trying to make a martingale, you should try this one.

Thanks for the help, I'll test it now
 
Joel Protusada:

If you are trying to make a martingale, you should try this one.

The check_trade() function you wrote is brilliant in checking if a trade hit stop loss or tp for the buystop and sellstop pending trades. Thanks again.

I did a little change to the strategy i'm testing. instead of creating a buy trade with a sell stop  pending and when buy hit stop loss, sell stop should trigger, followed by creating another buy stop. The change i made is creating a buy trade and buy limit trade, once the buy trade hit stop loss, the buy limit should trigger and create another buy limit at the stop loss of the first buy limit and so on.

The problem i have is changing the check_trade() function to know when the buy hit stop loss and the buy limit is triggered so it can create another buy limit trade and so on like that. The strategy i'm working on is to trade gbp pairs because it is very easy for gbp pairs to hit 10 pips in any direction. I have a plan to recover loss if it continue to hit stop loss which is to change the direction of the trades but i want to solve the check_trade() function first, to know if the trade hit stop loss or not.


Thanks a lot in advance.

 
William Roeder:
  1. Don't try to use any price or server related functions in OnInit (or on load,) as there may be no connection/chart yet:
    1. Terminal starts.
    2. Indicators/EAs are loaded. Static and globally declared variables are initialized. (Do not depend on a specific order.)
    3. OnInit is called.
    4. For indicators OnCalculate is called with any existing history.
    5. Human may have to enter password, connection to server begins.
    6. New history is received, OnCalculate called again.
    7. New tick is received, OnCalculate/OnTick is called. Now TickValue, TimeCurrent, account information and prices are valid.

  2. You have no code that does that. OnTick only updates pre_OrdersTotal and does some Alerts.

  3. OrderSend does not return a boolean. Your test will never be true.
Thanks for your observations. i'm new to the mql4 programming language. i'll change the ordersend to -1 to signal error. Also i'll also move the entertrade function to inside the ontick function. thanks again.
Reason: