//+------------------------------------------------------------------+
//|                                                LotCalculator.mq4 |
//|                                                  PipRider DotCom |
//|                                                 www.piprider.com |
//+------------------------------------------------------------------+

//--- Risk is based on account equity.  This can be changed to account balance if required.  The 5 lines that need altering are marked.

#include             <WinUser32.mqh>

#property copyright "PipRider DotCom"
#property link      "www.piprider.com"

#property indicator_chart_window
//---- input parameters
extern int       StopDistanceInPips = 30;
extern double    StopLevel;
extern double    Risk = 2.0;
extern color     FontColour = Black;
extern color     StopLineColour = Red;

double           NewStopDistanceInPips;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//----

if(StopDistanceInPips == 0) MessageBox("StopDistanceInPips has been set at zero","Warning",MB_OK);
if(StopLevel == 0) MessageBox("StopLevel has been set at zero","Warning",MB_OK);

//--- let's adjust stop distance for 3/5-digit brokers

int HalfDigits,DoubleDigits;
NewStopDistanceInPips = StopDistanceInPips;
HalfDigits = MathFloor(MarketInfo(Symbol(), MODE_DIGITS) / 2);
DoubleDigits = HalfDigits * 2;
if(DoubleDigits != MarketInfo(Symbol(), MODE_DIGITS))  NewStopDistanceInPips = StopDistanceInPips * 10;


//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectDelete("A");   
   ObjectDelete("B");   
   ObjectDelete("C");   
   ObjectDelete("D");   
   ObjectDelete("StopLine");   

//----
   return(0);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {

//----
         // this prevents zero divide errors if indi is pre-attached to a chart when MT4 loaded
         //--- replace AccountEquity() in the following line with AccountBalance() if required
         if(AccountEquity() == 0) return;  
        
double   StopDistance = NewStopDistanceInPips * Point;
double   StopDistanceFromLevel = 0;
         if(StopLevel < Bid)  StopDistanceFromLevel = Ask - StopLevel; // for long trades
         if(StopLevel > Bid)  StopDistanceFromLevel = StopLevel - Bid; // for short trades

double   MinLotSize=0;
         MinLotSize = MarketInfo(Symbol(),MODE_MINLOT);
double   MaxLotSize=0;
         MaxLotSize = MarketInfo(Symbol(),MODE_MAXLOT);
double   LotStep = 0;
         LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
double   LotsByDistance, LotsByLevel;

string   text1 = "Intended risk is "+DoubleToStr(Risk, 2)+" %";

int      space = 24;

  if(StopDistance != 0)  {
               
         space = 0;
         //--- replace AccountEquity() in the following line with AccountBalance() if required
         LotsByDistance = NormalizeDouble((AccountEquity() * Risk * Point) / (100 * StopDistance * MarketInfo(Symbol(), MODE_TICKVALUE)), 2);
         if(LotsByDistance < MinLotSize)    { LotsByDistance = MinLotSize; }
         if(LotsByDistance > MaxLotSize)    { LotsByDistance = MaxLotSize; }
         LotsByDistance = NormalizeDouble(LotsByDistance / LotStep,0) * LotStep;
         //--- replace AccountEquity() in the following line with AccountBalance() if required
         double   ActualRiskByDistance = (LotsByDistance * 100 * StopDistance * MarketInfo(Symbol(), MODE_TICKVALUE)) / (AccountEquity() * Point);
         string   text2 = "Lots by SL distance of "+DoubleToStr(StopDistanceInPips, 0)+" pips is "+DoubleToStr(LotsByDistance, 2)+". Risk would be "+DoubleToStr(ActualRiskByDistance, 2)+"%";
         SetLabel("B", text2, 7, 10, "System", 10, 0, FontColour);
         }


  if(StopLevel != 0 && StopDistanceFromLevel != 0)  {
         
         //--- replace AccountEquity() in the following line with AccountBalance() if required
         LotsByLevel = NormalizeDouble((AccountEquity() * Risk * Point) / (100 * StopDistanceFromLevel * MarketInfo(Symbol(), MODE_TICKVALUE)), 2);
         if(LotsByLevel < MinLotSize)    { LotsByLevel = MinLotSize; }
         if(LotsByLevel > MaxLotSize)    { LotsByLevel = MaxLotSize; }
         LotsByLevel = NormalizeDouble(LotsByLevel / LotStep,0) * LotStep;
         //--- replace AccountEquity() in the following line with AccountBalance() if required
         double   ActualRiskByLevel = (LotsByLevel * 100 * StopDistanceFromLevel * MarketInfo(Symbol(), MODE_TICKVALUE)) / (AccountEquity() * Point);
         string   text3 = "Lots by SL level of "+DoubleToStr(StopLevel, Digits)+" is "+DoubleToStr(LotsByLevel, 2)+". Risk would be "+DoubleToStr(ActualRiskByLevel, 2)+"%";
         SetLabel("C", text3, 7, 5 + space, "System", 10, 0, FontColour);

//---- let's draw a line at the stoploss value

         ObjectCreate("StopLine", OBJ_HLINE, 0, 0, StopLevel);
         ObjectSet("StopLine", OBJPROP_COLOR, StopLineColour);
         ObjectSet("StopLine", OBJPROP_WIDTH, 1);
         ObjectSet("StopLine", OBJPROP_STYLE, STYLE_DASHDOT);
         }
         
//--- let's position some text on screen

  SetLabel("A", text1, 7, 24, "System", 10, 0, FontColour);// 24 moves Intended risk line
  
//--- if no stop values have been set we'll display some text

  if(StopLevel == 0 && StopDistance == 0)  {
         
         string text4 = "No stoploss values have been set";
         SetLabel("D", text4, 7, 10, "System", 10, 0, FontColour);// 10 moves Lots by SL distance line
         }

//----

   return(0);
  }

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

void SetLabel(string name,string txt,int x,int y,string font,int size,int angle,color clr)
  {
   int idx=0;
   if(ObjectFind(name) == -1)
     {
       ObjectCreate(name, OBJ_LABEL, idx, 0, 0);
       ObjectSetText(name, txt, size, font, clr);
       ObjectSet(name, OBJPROP_XDISTANCE, x);
       ObjectSet(name, OBJPROP_YDISTANCE, y);
       ObjectSet(name, OBJPROP_CORNER, 2);
       ObjectSet(name, OBJPROP_ANGLE, angle);
     }
   else
     {
       ObjectSet(name, OBJPROP_XDISTANCE, x);
       ObjectSet(name, OBJPROP_YDISTANCE, y);
       ObjectSetText(name, txt, size, font, clr);
       ObjectSet(name, OBJPROP_CORNER, 2);
       ObjectSet(name, OBJPROP_ANGLE, angle);
     } 
  }

