Download MetaTrader 5

Please fix this EA .. Orders Limt

To add comments, please log in or register
Amjad Muhaisen
45
Amjad Muhaisen  

Hello,

im having problem with my EA,
it opens more than one trade at one time,
i need to fix that, and let the EA, only open another trade when the first one hit the TP or SL, after that its ok to open another trade,

and i want to set a fixed lot, it always keep changes the lots ...

here is the code,


extern double Maximum_Loss_Per_Trade = 2;  // Percent of capital to risk 
extern int barsToAnalyze = 55; 
extern int donchianReversal = 20;
double TargetAsPercentOfATR = 0;
extern double StopLossAsPercentOfATR = 200;

string SYSTEM_NAME = "amjadepp 2";
bool NEW_BAR = false;                         // Flag of a new bar
static datetime newTime;
static double targetPoint;
int magicNumber = 234888;

double atrFirstBatchOrder;
double priceFirstOpenOrder;
int openTrades;
string directionInPlay;
bool isClosingOrders;


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


int init()
{
     newTime = Time[0];  
     return(0);
     isClosingOrders = false;
     directionInPlay = "None";
}

int deinit()
{
   return(0);
}

int start()
{
    //if (ThereIsAlreadyATrade())
    //    return;
          
    /*Only enter new trades when there is a new bar*/
    //AnalyzeNewBar();       
           
    //if (NEW_BAR == true)   
    //{ 
        AnalyzeExitSituation();
        Print("openTrades: " + openTrades);
        if (!ThereIsAlreadyFourTrades())
        {
            if (!isClosingOrders)
                AnalyzeOrderEntry(); 
        }        
    //}                    
      
    return;         
}
 
 
 
bool ThereIsAlreadyFourTrades()
{
    RefreshRates();
    int originalOpenTrades = openTrades;
    openTrades = 0;
    int totalOrders = OrdersTotal();
    int i = 0;
    datetime oldestTradeDateTime = TimeCurrent();
    atrFirstBatchOrder = iATR(NULL,1440, 20, 1);
        
    while ((openTrades < 4) && (i < totalOrders))
    {
         if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES ) == true) // If there is the next one
         {                                       
              if (OrderSymbol() == Symbol() && OrderMagicNumber() == magicNumber)
              {
                  if (OrderOpenTime() < oldestTradeDateTime) 
                  {
                      oldestTradeDateTime = OrderOpenTime();
                      atrFirstBatchOrder = StrToDouble(OrderComment());
                      priceFirstOpenOrder = OrderOpenPrice();
                      if (OrderType() == OP_BUY)
                          directionInPlay = "Up";
                      else 
                          directionInPlay = "Down";
                   }
                  
                   openTrades++;     
              }                  
         }
         i++;
    }
    //Print("openTrades: " + openTrades);
    //if (openTrades == originalOpenTrades - 1)
    //    openTrades = originalOpenTrades;
    
    if (openTrades == 0)
    {
        isClosingOrders = false;
        directionInPlay = "None";
    }
            
    return (openTrades == 4);
}

 
 
 void AnalyzeNewBar()                           // Funct. detecting ..
 {                                             // .. a new bar
     //static datetime newTime = 0;                 // Time of the current bar
     NEW_BAR = false;                             // No new bar
     if(newTime != Time[0])                       // Compare time
     {
         newTime = Time[0];                      // Now time is so
         NEW_BAR = true;                          // A new bar detected         
     }
 }
 


bool AnalyzeOrderEntry()
{
    RefreshRates();
    
    double ATR = atrFirstBatchOrder;
    
    double stopLossDistance = ATR * StopLossAsPercentOfATR/100.00 ;
    double currentSpread = Ask - Bid;
    double lots;
    double stopLoss;
    int ticket;
    double pipRange = GetPipRange();
    double TP; 
            
    //Long trade
    if( BullishMomentum(barsToAnalyze) )
    {
        //CloseBearTrades();
        stopLoss = Ask - stopLossDistance; 
        if (TargetAsPercentOfATR == 0)
            TP = 0;
        else
            TP = Ask + ATR * TargetAsPercentOfATR/100.00 ;
        
        lots = GetPositionSize(stopLossDistance, Maximum_Loss_Per_Trade/100.00);
                
        if (lots > 0)
        {
            ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 2, stopLoss, TP, DoubleToStr(ATR, 4), magicNumber); 
            if (ticket < 0)
            {
                Print("Long OrderSend failed with error #", GetLastError());
                openTrades++;
                return (false);
            }
            else
            {
                updateStopLosses(stopLoss, TP, ticket);
                openTrades++;
                priceFirstOpenOrder = Ask;
                directionInPlay = "Up";
                //Print("openTrades: " + openTrades);
                return(true);
            }             
         }
     }
     
     if( BearishMomentum(barsToAnalyze) )
     {  
         //CloseBullTrades();
         stopLoss = Bid + stopLossDistance; 
         if (TargetAsPercentOfATR == 0)
             TP = 0;
         else
             TP = Bid - ATR * TargetAsPercentOfATR/100.00; 
             
         lots = GetPositionSize(stopLossDistance, Maximum_Loss_Per_Trade/100.00);
             
         if (lots > 0)
         {
             ticket = OrderSend(Symbol(),OP_SELL, lots, Bid, 2, stopLoss, TP, DoubleToStr(ATR, 4), magicNumber); 
             if(ticket < 0)
             {
                 Print("Short OrderSend failed with error #", GetLastError());
                 return (false);
             }
             else
             {
                 updateStopLosses(stopLoss, TP, ticket);
                 openTrades++;
                 priceFirstOpenOrder = Bid;
                 directionInPlay = "Down";
                 return (true);
             }             
         }                      
    }
    return (false);
}



void AnalyzeExitSituation()
{
    //Close trades if there is not follow through
    bool isHighestDonchian = false;
    bool isLowestDonchian = false;
    double highest = High[1];
    double lowest = Low[1];
    
    for (int i = 2; i <= donchianReversal; i++)
    {
        if (High[i] > highest)
            highest = High[i];    
        
        if (Low[i] < lowest)
            lowest = Low[i];
    } 
    
    if (Bid > highest)
        isHighestDonchian = true;
    if (Bid < lowest)
        isLowestDonchian = true;
    
    //-------------------------------//
    
    int totalOrders = OrdersTotal();

    i = 0;
    while (i < totalOrders)
    {
         if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES ) == true) // If there is the next one
         {                                                    
              if (OrderSymbol() == Symbol() && OrderMagicNumber() == magicNumber)
              {
                  if (OrderType() == OP_BUY)
                  {
                      if (isLowestDonchian)
                      {
                          isClosingOrders = true;
                          OrderClose(OrderTicket(), OrderLots(), Bid, 3);
                      }                           
                  }
                      
                  if (OrderType() == OP_SELL)
                  {
                      if (isHighestDonchian)
                      {
                          isClosingOrders = true;
                          OrderClose(OrderTicket(), OrderLots(), Ask, 3);  
                      }                         
                  }                  
              }                  
         }
         i++;
    }
}

bool BullishMomentum(int bars)
{
    double currentPrice = Ask;
    
    if (openTrades == 0)
    { 
        //Print("openTrades: " + openTrades + "  if");
        
        int i = 0;
        bool isHighest = true;
        while (i <= bars && isHighest == true)
        {
            if (currentPrice < High[i])
                isHighest = false;
        
            i++;
        }
        return (isHighest);
    }
    else
    {
        //Print("openTrades: " + openTrades + "  else");
        if (directionInPlay == "Down")
            return (false);
            
        double priceToBeat = priceFirstOpenOrder + 0.5 * atrFirstBatchOrder * openTrades; 
        //Print("priceFirstOpenOrder: " + priceFirstOpenOrder);
        //Print("atrFirstBatchOrder: " + atrFirstBatchOrder);
        //Print("openTrades: " + openTrades);
        //Print("priceToBeat: " + priceToBeat);
          
        if (currentPrice > priceToBeat)
            return (true);
        else
            return (false);
    }
}

bool BearishMomentum(int bars)
{
    double currentPrice = Bid;
    
    if (openTrades == 0)
    {
        int i = 0;
        bool isLowest = true;
        while (i <= bars && isLowest == true)
        {
            if (currentPrice > Low[i])
                isLowest = false;
        
            i++;
        }
        return (isLowest);
    }
    else
    {
        if (directionInPlay == "Up")
            return (false);
            
        double priceToBeat = priceFirstOpenOrder - 0.5 * atrFirstBatchOrder * openTrades; 
        if (currentPrice < priceToBeat)
            return (true);
        else
            return (false);
    }
}


void updateStopLosses(double stopLoss, double target, int exceptOrderTicket)
{
    int totalOrders = OrdersTotal();

    int i = 0;
    while (i < totalOrders)
    {
         if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES ) == true) // If there is the next one
         {                                       
              if (OrderSymbol() == Symbol() && OrderMagicNumber() == magicNumber)
              {
                  if (OrderTicket() != exceptOrderTicket)
                      OrderModify(OrderTicket(), OrderOpenPrice(), stopLoss, target, 0);                  
              }                  
         }
         i++;
    }
}

double GetPositionSize(double stopLossDistance, double risk)
{
    //Analize taking into account the MAXIMUM_LOST_PER_TRADE parameter
    double accountBalance = AccountBalance();
    double maximumLoss = accountBalance * risk;
    double accountFreeMargin = AccountFreeMargin();                  // Free margin
    double oneLotPrice = MarketInfo(Symbol(),MODE_MARGINREQUIRED);   // Price of 1 lot    
    double minimumLotSize = MarketInfo(Symbol(), MODE_MINLOT);
    double lotChangeStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    
    double pipValue = GetPipValue(Symbol()); 
    
    double lotsizeUnits = maximumLoss / ((1/GetPipRange()) * (stopLossDistance * pipValue));
    //Print ("units to play: " + lotsizeUnits);
        
    double lotsizeValue = (lotsizeUnits / 100000) * oneLotPrice;
    //Print ("valor de la jugada: " + lotsizeValue);

    //Round Lot size
    double lotsToPlay = MathFloor(lotsizeValue / oneLotPrice / lotChangeStep) * lotChangeStep;// For opening
    
    if (lotsToPlay < minimumLotSize)
        lotsToPlay = minimumLotSize; // Not less than minimal
        
    if (lotsToPlay * oneLotPrice > accountFreeMargin) // Lot larger than free margin
    {
         Print("Not enough margin to enter new trade. Account free margin: " + accountFreeMargin);
         return (0);                                 
    }  
    
    return (lotsToPlay);
}


double GetPipRange()
{
    if (StringFind(Symbol(), "JPY", 0) > 0)
        return (0.01);
    else
        return (0.0001);
}

double GetPipValue(string symbol)
{
    double tickSize = 0.0001;
    if (StringFind(symbol, "JPY", 0) != -1)
       tickSize = 0.01;
     
    //Case 1 - USD is in the second part of the pair    
    if (StringFind(symbol, "USD", 0) == 3)
    {
        return (0.0001);
    }
    
    //Case 2 - USD is in the first half of the name
    if (StringFind(symbol, "USD", 0) == 0)
    {
         return (   tickSize / MarketInfo(symbol, MODE_BID)   );   
    }   
    
    //Case 3 - USD doesnt appear in the name of the pair
    if (StringFind(symbol, "USD", 0) == -1)
    {
        string matchingUSDpair = GetMatchingUSDPair(symbol);
        
        //3.1 - the matching pair contains USD in the first position
        if (   StringFind(matchingUSDpair, "USD", 0) == 0  )
        {
            return (   tickSize / MarketInfo(matchingUSDpair, MODE_BID)   );   
        }
        else //3.2 - the matching pair containd USD in the second half of the name
        {
            return ( tickSize * MarketInfo(matchingUSDpair, MODE_BID)/ MarketInfo(symbol, MODE_BID) );
        }       
    }
}
 
string GetMatchingUSDPair(string symbol)
{
    string matchingPair;
    string usdPairs[13] = { "EURUSD", "GBPUSD", "USDJPY", "USDCHF", "USDCAD", "AUDUSD", "NZDUSD", "USDSGD", "USDNOK", "USDDKK", "USDSEK", "USDHKD", "USDMXN" };
    
    //Get last 3 characters of symbol entered as parameter    
    string baseCurrency = StringSubstr(symbol, 3, 3);
    
    bool found = false;
    int i = 0;
    
    while ((found == false) && (i < 13) )
    {
        if (usdPairs[i] == baseCurrency + "USD" || usdPairs[i] == "USD" + baseCurrency )
        {
            matchingPair = usdPairs[i];
            found = true;
        }
        i++;
    }
    
    return (matchingPair);
} 
Alain Verleyen
Moderator
31183
Alain Verleyen  

Hi,

If you can't find what you need in the Codebase or the Market, then you can create a request in Jobs Service.

To add comments, please log in or register