The position size is not optimized for 2% of account

 

Hi everyone, I started learning mql4 3 days ago and decided to try building my first EA.
But I've run into some problems that exceed my current ability.

The Idea is that after 2 successive bear candles on the 1 hour timeframe, the EA will take a trade and risk 2% of MyAccountBAlance. The stoploss is 2 pips above the previous candle high High[1] and the take profit is 2 times risk.

The problems are
1) The position size is not optimized for 2% of account
2) The takeprofit does not change after the first trade. (Other trades after the first trade use the same takeprofit price as the first trade)
3) Sometimes, the stoploss is bigger than what its supposed to be.

Please, can someone help me fix these issues? Sorry if the code is not easily readable, I'll improve that with experience.
Also any tips are welcome.
Thanks in Advance.


extern double             takeprofitprice = 0;
extern int                magicNB      = 555555;
extern int                Slippage;
extern double             MaxRiskPerTrade = 2; // % of balance to risk in one trade.
extern ENUM_TIMEFRAMES    Timeframe  = PERIOD_H1 ;
extern double             MyAccountBAlance = 10000;
extern string             Alerts     = "============ Notifications ============";
extern bool               Email      = true;
extern bool               Phone      = true;
string                    the_symbol = "HKDJPY";
int                       openOrderID;
double                    lotsize;
bool                      closeorder;
double                    StopLoss;
double                    stoplossinpips;
bool                      selectthisorder;
double                    stoplossinpipsfortp;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   
   Alert("Starting Strategy");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
      Alert("You have removed the EA");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
      // check if there is already a trade
      if(!CheckIfOpenOrdersByMagicNB(magicNB))//if no open orders try to enter new position
      {
         if(NewCandle())
            if((Open[2] >= Close[2]) && ((Open[1] > Close[1])))
            {
               if (Symbol() == the_symbol)
               {
                  Slippage = 1;
               }
            
               else 
               {
                  Slippage = 10;
               }
            
               //to calculate stoploss 2
               if (Symbol() == the_symbol)
               {
                  StopLoss = High[1] + (2 * Point);
               }
            
               else
               {
                  StopLoss = High[1] + (20 * Point);
               }
            
               // to calculate stoplossinpips 3
               if (Symbol() == the_symbol)
               {
                  stoplossinpips = (((High[1] + (2* Point))- Close[1]) / Point);
               }
               else
               {
                  stoplossinpips = (((High[1] + (20* Point))- Close[1]) / (Point * 10));
               }
               mytakeprofit();
               lotsize = CalculateLotSize(stoplossinpips);
               openOrderID = OrderSend(Symbol(),OP_SELL,lotsize,Bid,Slippage,0,mytakeprofit(),NULL,magicNB);
               if(openOrderID < 0) Alert("order rejected. Order error: " + GetLastError());
               if(Email)
               {
                  SendMail("Open ", Symbol() + " "+ "stoploss is " + stoplossinpips);
               }
               if(Phone)
               {
                  SendNotification(Symbol() +  "Sell. " + " Stoploss is " + stoplossinpips);
               }
            
               
               
               
            }
      }
      
      
  }
//+------------------------------------------------------------------+
 
//+-----------------------------------------------------------------------
 bool CheckIfOpenOrdersByMagicNB(int magicNB)
{
   int openOrders = OrdersTotal();
   
   for(int i = 0; i < openOrders; i++)
   {
      if(OrderSelect(i,SELECT_BY_POS)==true)
      {
         if(OrderMagicNumber() == magicNB) 
         {
            return true;
         }  
      }
   }
   return false; 
}
//+-------------------------------------------------------------------------

// We define the function to calculate the position size and return the lot to order.
// The only parameter is stop-loss, it will return a double.
double CalculateLotSize(double SL)
{          // Calculate the position size.
  
   double LotSize = 0;
   // We get the value of a tick.
   double nTickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   // If the digits are 3 or 5, we normalize multiplying by 10.
   if ((Digits == 3) || (Digits == 5))
   {
      nTickValue = nTickValue * 10;
   }
   else if (Symbol() == the_symbol)
      {
         nTickValue = nTickValue * 1;
      }
   // We apply the formula to calculate the position size and assign the value to the variable.
   LotSize = (MyAccountBAlance * MaxRiskPerTrade / 100) / (SL * nTickValue);
   return LotSize;
}
//+-----------------------------------------------------------------------

double mytakeprofit()
   {
      if (takeprofitprice == 0)
      {
         if (Symbol() == the_symbol)
         {
            if (Symbol() == the_symbol)
               {
                  stoplossinpipsfortp = (((High[1] + (2* Point))- Close[1]) / Point);
               }
               
            takeprofitprice =  Close[1] - ((stoplossinpipsfortp * 2) * Point);
         }
         
         else if(Symbol() != the_symbol)
         {
            stoplossinpipsfortp = (((High[1] + (20* Point))- Close[1]) / (Point * 10));
            takeprofitprice =  Close[1] - ((stoplossinpipsfortp * 20) * Point);
         }
         return takeprofitprice;
      }
      else
      {
         return takeprofitprice;
      }
   }
   
//+-----------------------------------------------------------------------------------
bool NewCandle()
   {
      static datetime time = 0;
      
      if(time != iTime(NULL,Timeframe,0))
         {
            time = iTime(NULL,Timeframe,0);
            return true;
         }
      
      return false;
   }
   
//+---------------------------------------
Documentation on MQL5: Constants, Enumerations and Structures / Chart Constants / Chart Timeframes
Documentation on MQL5: Constants, Enumerations and Structures / Chart Constants / Chart Timeframes
  • www.mql5.com
Chart Timeframes - Chart Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

Risk depends on your initial stop loss, lot size, and the value of the symbol. It does not depend on margin and leverage. No SL means you have infinite risk. Never risk more than a small percentage of your trading funds, certainly less than 2% per trade, 6% total.

  1. You place the stop where it needs to be — where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.

  2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)

  3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
              MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum (2017.10.10)
              Is there an universal solution for Tick value? - Currency Pairs - General - MQL5 programming forum (2018.02.11)
              Lot value calculation off by a factor of 100 - MQL5 programming forum (2019.07.19)

  4. You must normalize lots properly and check against min and max.

  5. You must also check FreeMargin to avoid stop out

Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.