#property indicator_chart_window


extern string Comment1 = "Фиксированый лот, которым ведется торговля";
extern double Lots = 0.0;

extern string Comment2 = "Допустимый % риска для депо на сделку для расчета лота";
extern double MaxRisk_Procent = 1;

extern string Comment3 = "Допустимая сумма риска на сделку для расчета лота";
extern double MaxRisk_Amount = 0;

extern string Comment4 = "формат отображения информации об SL/TP рабочих ордеров";
extern bool ShortFormat = true;


double gPriceSL = 0;
string NameLineSL = "Nexter_StopLoss";

string NameLabelSLinfo = "Nexter_SLinfo";
string TextLabelSLinfo = "";


bool bInit = false;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init2()
{
   SetPriceSL (MarketInfo(Symbol(), MODE_BID) - 200 * MarketInfo(Symbol(), MODE_POINT));
   ShowSLinfo ("Инициализация... ", true);
   return(0);
}

int init()
{
   bInit = false;
   return(0);
}

int deinit()
{
   SetPriceSL(0);
   ShowSLinfo ();
   Comment ("");
   bInit = false;
   return (0);
   
}




double CalculateProfit (string sym, double OpenPrice, double ClosePrice, double Sign)
{
   double
      Profit = 0.0
      , TickValue = MarketInfo(sym, MODE_TICKVALUE)
      , TickSize = MarketInfo(sym, MODE_TICKSIZE)
      , LotSize = MarketInfo(sym, MODE_LOTSIZE)
      , ProfitCalcMode = MarketInfo(sym, MODE_PROFITCALCMODE)
      ;
   
   
   switch (ProfitCalcMode)
   {
      case 1:
         {
            Profit = NormalizeDouble(Sign * (ClosePrice - OpenPrice) * LotSize, 2);
            break;
         }
         
      default:
         {
            if (StringSubstr(sym, StringLen(sym) - 3) == "USD") // обратная MODE_PROFITCALCMODE
            {
               Profit = NormalizeDouble(Sign * (ClosePrice - OpenPrice) * LotSize, 2);
            }
            else
               if (StringSubstr(sym, 0, 3) == "USD") // прямая
               {
                  if (ClosePrice > 0.0)
                     Profit = NormalizeDouble(Sign * (ClosePrice - OpenPrice) *  LotSize / ClosePrice, 2);
               }
               else // кросс
               {
                  if (TickSize > 0.0)
                     Profit = NormalizeDouble(Sign * (ClosePrice - OpenPrice) *  TickValue / TickSize, 2);
               }
            break;
         }
   }
   
   
   return (Profit);
}


double CalculateLot (double Profit)
{
   if (Lots > 0)
      return (Lots);

   double MinLot = MarketInfo (Symbol(), MODE_MINLOT);
   double LotStep = MarketInfo (Symbol(), MODE_LOTSTEP);

   if (Profit == 0.0 || LotStep == 0.0)
      return (MinLot);
   
   double _RiskAmount = MaxRisk_Amount;
   if (_RiskAmount <= 0)
   {
      double Depo = AccountBalance();
      if (MaxRisk_Procent > 0 && Depo > 0)
         _RiskAmount = NormalizeDouble(Depo * MaxRisk_Procent / 100, 2);
   }
   
   if (_RiskAmount <= 0)
      return (0);
   
   double MinLotRisk = NormalizeDouble(Profit * MinLot, 2);
   if (MinLotRisk >= _RiskAmount)
      return (MinLot);
   
   double PrevLot = MinLot;
   double CurrLot = MinLot;
      
   int NumOfStep = MathFloor((_RiskAmount - MinLotRisk) / (Profit * LotStep));
   if (NumOfStep > 2)
   {
      PrevLot += LotStep * (NumOfStep - 2);
      CurrLot = PrevLot + LotStep;
   }

   
   while (NormalizeDouble(Profit * CurrLot, 2) <= _RiskAmount)
   {
      PrevLot = CurrLot;
      CurrLot += LotStep;
   }
   
   return (PrevLot);
}



double FindSL ()
{
   if(ObjectFind(NameLineSL) == -1)
   {
      return (0);
   }
   
   return (ObjectGet (NameLineSL, OBJPROP_PRICE1));
}



void ShowSL()
{
   double
      PriceSL = FindSL()
      , SignSL = +1
      , OpenPrice = Ask
      , Profit
      ;
   
   if (PriceSL <= 0.0 || Point == 0.0)
   {
      init2();
      return;
   }   
      
   if (PriceSL > Bid) // продажа
   {
      SignSL = -1;
      OpenPrice = Bid;
   }
   
   Profit = -CalculateProfit (Symbol(), OpenPrice, PriceSL, SignSL);
   int Pips = MathAbs(OpenPrice-PriceSL)/Point;
   
   string sInfo = "";
   double _Lots = CalculateLot (Profit);
   
   if (_Lots > 0)
   {
      Profit = Profit * _Lots;
      
      sInfo = 
         ""
         + "vol. " + DoubleToStr(_Lots, 2) + " lots; "
         + "s/l = " + Pips + " pips, $" + DoubleToStr(Profit, 2);
      
      if (AccountBalance() > 0 && AccountEquity() > 0)
      {
         sInfo = sInfo +
            " (" + DoubleToStr(NormalizeDouble(Profit / AccountBalance() * 100, 2), 2) + "% depo; "
            + DoubleToStr(NormalizeDouble(Profit / AccountEquity() * 100, 2), 2) + "% eq)"
            ;
      
      }
   }

   ShowSLinfo(sInfo);
}


int start()
{
   if (!bInit)
   {
      init2();
      bInit = true;
   }

   ShowSL();
   ShowAllSL();
   return(0);
}


void ShowPriceLine (double Price=0.0, string NameLine = "MyLine", color ColorLine = Red)
{
   if(Price == 0.0 && ObjectFind(NameLine) > -1)
   {
      ObjectDelete(NameLine);
      return;
   }
   
   if (ObjectFind(NameLine) == -1)
      ObjectCreate(NameLine, OBJ_HLINE, 0, 0, Price);
   
   ObjectSet(NameLine, OBJPROP_PRICE1, Price);
   ObjectSet(NameLine, OBJPROP_COLOR, ColorLine);
   ObjectSet(NameLine, OBJPROP_STYLE, STYLE_DASH);
}


void SetPriceSL (double PriceSL)
{
   if (gPriceSL != PriceSL || PriceSL == 0)
   {
      gPriceSL = PriceSL;
      ShowPriceLine (gPriceSL, NameLineSL);
   }      
   
}

void ShowSLinfo (string sText = "", bool bInit = false)
{
   if (ObjectFind(NameLabelSLinfo) > -1 && sText == "")
   {
      ObjectDelete(NameLabelSLinfo);
      return;
   }

   if (ObjectFind(NameLabelSLinfo) == -1 || bInit)
   {
      if (ObjectFind(NameLabelSLinfo) > -1)
         ObjectDelete(NameLabelSLinfo);
   
      ObjectCreate(NameLabelSLinfo, OBJ_LABEL, 0, 0, 0);
      ObjectSetText(NameLabelSLinfo, sText, 15, "Arial", Red);
      ObjectSet(NameLabelSLinfo, OBJPROP_CORNER, 2);
      ObjectSet(NameLabelSLinfo, OBJPROP_XDISTANCE, 0);
      ObjectSet(NameLabelSLinfo, OBJPROP_YDISTANCE, 30);
      TextLabelSLinfo = "-";
   }
   
   if (TextLabelSLinfo != sText)
   {
      TextLabelSLinfo = sText;
      ObjectSetText(NameLabelSLinfo, TextLabelSLinfo);
   }
}


string GetSLTPtext (string Prefix, double SummLoss, double SummProfit, int OrdCnt, int Ord_woSL, int Ord_woTP)

{
   string AllSLinfo = Prefix;
   
   AllSLinfo = AllSLinfo + "s/l = " + DoubleToStr(SummLoss, 2) + "$";
   if (AccountBalance() > 0)
      AllSLinfo = AllSLinfo + " (" + DoubleToStr(NormalizeDouble(SummLoss / AccountBalance() * 100, 2), 2) + "%);";
   
   AllSLinfo = AllSLinfo + ";  t/p = " + DoubleToStr(SummProfit, 2) + "$";
   if (AccountBalance() > 0)
      AllSLinfo = AllSLinfo + " (" + DoubleToStr(NormalizeDouble(SummProfit / AccountBalance() * 100, 2), 2) + "%)";
   
   AllSLinfo = AllSLinfo + ";  Ордеров: " + OrdCnt + ", без S/L: " + Ord_woSL + ", без T/P: " + Ord_woTP;
   
   return (AllSLinfo);
}

#define SYMCOUNT 100

void ShowAllSL ()
{
   int SymCnt = 0;
   string arrSymbols[SYMCOUNT];
   double arrSLprofit[SYMCOUNT], arrTPprofit[SYMCOUNT];
   int arrOrdCnt[SYMCOUNT], arrOrd_woSL[SYMCOUNT], arrOrd_woTP[SYMCOUNT];
   

   double
      SummProfit_All = 0.0
      , SummLoss_All = 0.0
      
      , SummProfit_One = 0.0
      , SummLoss_One = 0.0
      ;
   
   for (int i = 0; i < OrdersTotal(); i++)
   {
      if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES))
         break;
      
      int Sign = 0.0;
      if (OrderType() == OP_BUY)
         Sign = +1;
      else
         if (OrderType() == OP_SELL)
            Sign = -1;
         else
            continue;
      
      int iPos = -1;
      for (int j = 0; j < SymCnt; j++)
      {
         if (OrderSymbol() == arrSymbols[j])
         {
            iPos = j;
            break;
         }
      }
      
      if (iPos == -1)
      {
         iPos = SymCnt;
         SymCnt++;
         arrSymbols[iPos] = OrderSymbol();
         arrSLprofit[iPos] = 0;
         arrTPprofit[iPos] = 0;
         arrOrdCnt[iPos] = 0;
         arrOrd_woSL[iPos] = 0;
         arrOrd_woTP[iPos] = 0;
      }

      arrOrdCnt[iPos]++;

      
      double
         OpenPrice = OrderOpenPrice()
         , SLPrice = OrderStopLoss()
         , TPPrice = OrderTakeProfit()
         , Commission = OrderCommission() + OrderSwap()
         , profit
         ;
      
      if (SLPrice > 0.0)
      {
         profit = Commission + CalculateProfit (OrderSymbol(), OpenPrice, SLPrice, Sign) * OrderLots();
         SummLoss_All += profit;
         arrSLprofit[iPos] += profit;
      }
      else
         arrOrd_woSL[iPos]++;
      
      
      if (TPPrice > 0.0)            
      {
         profit = Commission + CalculateProfit (OrderSymbol(), OpenPrice, TPPrice, Sign) * OrderLots();
         SummProfit_All += profit;
         arrTPprofit[iPos] += profit;
      }
      else
         arrOrd_woTP[iPos]++;
   }

   double allSLprofit = 0, allTPprofit = 0;
   int allOrdCnt = 0, allOrd_woSL = 0, allOrd_woTP = 0;

   
   string Msg = "";
   for (i = 0; i < SymCnt; i++)
   {
      if (!ShortFormat || arrSymbols[i] == Symbol())
         Msg = Msg + "\n" + GetSLTPtext (
               arrSymbols[i] + " :  "
               , arrSLprofit[i]
               , arrTPprofit[i]
               , arrOrdCnt[i]
               , arrOrd_woSL[i]
               , arrOrd_woTP[i]
               );

      allSLprofit += arrSLprofit[i];
      allTPprofit += arrTPprofit[i];
      allOrdCnt += arrOrdCnt[i];
      allOrd_woSL += arrOrd_woSL[i];
      allOrd_woTP += arrOrd_woTP[i];

   }

   Msg = GetSLTPtext (
         "ALL symbols :  "
         , allSLprofit
         , allTPprofit
         , allOrdCnt
         , allOrd_woSL
         , allOrd_woTP
         ) + Msg;

   
   Comment(Msg);
}