//+------------------------------------------------------------------+
//|                                               Total PnL Moti.mq4 |
//+------------------------------------------------------------------+
// This is an indicator; install into ...(MT4)/experts/indicators folder


#property indicator_chart_window

#include <hanover --- function header (np).mqh>

extern  string    OrderTypes                 = "O";
extern  string    AccountBasis               = "E";   // B=balance, E=equity, F=free margin
extern  string    FontName                   = "Lucida Console";
extern  int       FontSize                   = 14;
extern  color     FontColorBullish           = Green;
extern  color     FontColorBearish           = Crimson;
extern  int       TextCorner                 = 0;
extern  int       TextHpos                   = 10;
extern  int       TextVpos                   = 22;
extern  int       TextVspacing               = 22;
extern  string    Visibility                 = "M1,M5,M15,M30,H1,H4,D1,W1,MN";
extern  string    RefreshPeriod              = "T";
extern  bool      PlotBEline                 = true;

string     ccy, sym, IndiName, diag_string, pair[50];
int        dig, tf, tmf, vis, wno, RefreshEveryXMins, bar, np, cnt[50];
double     spr, pnt, tickval, bidp, askp, minlot, lswap, sswap, pips[50], pnl[50], vol[50], sum[50], AcctFreeMgn;
datetime   prev_time;
bool       FirstTime;

//+------------------------------------------------------------------+
int init()  {
//+------------------------------------------------------------------+
  IndiName = "TotalPnL-" + GetHash("0");
  IndicatorShortName(IndiName);

  sym     = Symbol();
  ccy     = Symbol();
  tmf     = Period();
  bidp    = MarketInfo(ccy,MODE_BID);
  askp    = MarketInfo(ccy,MODE_ASK);
  pnt     = MarketInfo(ccy,MODE_POINT);
  dig     = MarketInfo(ccy,MODE_DIGITS);
  spr     = MarketInfo(ccy,MODE_SPREAD);
  tickval = MarketInfo(ccy,MODE_TICKVALUE);
  minlot  = MarketInfo(ccy,MODE_MINLOT);
  lswap   = MarketInfo(ccy,MODE_SWAPLONG);
  sswap   = MarketInfo(ccy,MODE_SWAPSHORT);
  if (dig == 3 || dig == 5) {
    pnt     *= 10;
    spr     /= 10;
    tickval *= 10;
  } 
  
  OrderTypes   = StringUpper(OrderTypes);
  AcctFreeMgn = AccountEquity();
  if (StringFind(StringUpper(AccountBasis),"B") >= 0)    AcctFreeMgn = AccountBalance();
  if (StringFind(StringUpper(AccountBasis),"F") >= 0)    AcctFreeMgn = AccountFreeMargin();

  RefreshEveryXMins = StrToTF(RefreshPeriod);
  prev_time = -9999;
  vis = GetVisibility(Visibility);
  wno = 0;  
  return(0);
}

//+------------------------------------------------------------------+
int deinit()  {
//+------------------------------------------------------------------+
  del_obj();
  return(0);
}

//+------------------------------------------------------------------+
int start()  {
//+------------------------------------------------------------------+
  if (RefreshEveryXMins < 0)  {
    if (FirstTime)  {
      del_obj();
      plot_obj();
    }
    FirstTime = false;      
    return(0);
  }  
  if (RefreshEveryXMins == 0) {
    del_obj();
    plot_obj();    
  } else {
    if (prev_time != iTime(sym,RefreshEveryXMins,0))  {
      del_obj();
      plot_obj();
      prev_time = iTime(sym,RefreshEveryXMins,0);
  } }      
  return(0);
}

//+------------------------------------------------------------------+
void del_obj()  {
//+------------------------------------------------------------------+
  int k=0;
  while (k<ObjectsTotal())   {
    string objname = ObjectName(k);
    if (StringSubstr(objname,0,StringLen(IndiName)) == IndiName)  
      ObjectDelete(objname);
    else
      k++;
  }    
  return(0);
}

//+------------------------------------------------------------------+
void build_arrays()   {
//+------------------------------------------------------------------+
  for (int z=0; z<ArraySize(pair); z++)   {
    if (pair[z]==OrderSymbol() || pair[z]=="")   break;
  }
  pair[z] = OrderSymbol();
  pnl[z] += OrderProfit() + OrderCommission() + OrderSwap();
  vol[z] += OrderLots();
  int    digits = MarketInfo(pair[z],MODE_DIGITS);
  double point  = MarketInfo(pair[z],MODE_POINT);
  if (digits == 3 || digits == 5) {
    point *= 10;
  } 
  if (MathMod(OrderType(),2) == 0)
    pips[z] += (OrderClosePrice() - OrderOpenPrice()) / point;
  else
    pips[z] += (OrderOpenPrice() - OrderClosePrice()) / point;
  sum[z] += OrderOpenPrice() * OrderLots();
  cnt[z] += 1;
  np = MathMax(np,z);  
  return(0);
}

//+------------------------------------------------------------------+
void plot_obj()   {
//+------------------------------------------------------------------+
  ArrayInitializeString(pair,"");
  ArrayInitialize(pips,0.0);
  ArrayInitialize(pnl,0.0);
  ArrayInitialize(vol,0.0);
  ArrayInitialize(sum,0.0);
  ArrayInitialize(cnt,0);

  for (int i=OrdersTotal()-1; i>=0; i--)  {
    OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
    if (StringFind(OrderTypes,OrderStatus(OrderTicket())) < 0)    continue;
    build_arrays();    
  }
  for (i=OrdersHistoryTotal()-1; i>=0; i--)  {
    OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
    if (StringFind(OrderTypes,OrderStatus(OrderTicket())) < 0)    continue;
    build_arrays();    
  }

  double tvol,tpnl,tpips = 0.0;
  int    tcnt      = 0;
  int    vp        = TextVpos;
  color  FontColor = DimGray;
  string text      = "Symbol    #    Lots    Pips       P/L $   Equity   BE Price";
  PlotLabel (IndiName+"header", true, 0, TextCorner, TextHpos, vp, text, FontColor, FontSize, FontName, 0, false, vis);      // Plot text label
  vp += TextVspacing;
  for (i=0; i<=np; i++)   {
    double BE = DivZero(sum[i],vol[i]);
    FontColor = ifint(pnl[i]>=0,FontColorBullish,FontColorBearish);
    text      = StrToStr(pair[i],"L8") + NumberToStr(cnt[i],"3") + NumberToStr(vol[i],"5.2") + NumberToStr(pips[i],"-5.1") + NumberToStr(pnl[i],",-6.2") 
                 + NumberToStr(DivZero(100*pnl[i],AcctFreeMgn),"-4.2'%'") + NumberToStr(BE,"5.5");
    PlotLabel (IndiName+NumberToStr(i,"'-'Z6"), true, 0, TextCorner, TextHpos, vp, text, FontColor, FontSize, FontName, 0, false, vis);      // Plot text label
    vp    += TextVspacing;
    if (PlotBEline && pair[i]==Symbol()) 
      PlotHL (IndiName+"BEline", true, 0, BE, DimGray, 1, STYLE_SOLID, false, vis, "Breakeven");      // Plot horizontal line
    tvol  += vol[i];
    tpips += pips[i];
    tpnl  += pnl[i];
    tcnt  += cnt[i];
  }
  FontColor = ifint(tpnl>=0,FontColorBullish,FontColorBearish);
  text      = "Totals  " + NumberToStr(tcnt,"3") + NumberToStr(tvol,"5.2") + NumberToStr(tpips,"-5.1") + NumberToStr(tpnl,",-6.2") + NumberToStr(DivZero(100*tpnl,AcctFreeMgn),"-4.2'%'");
  PlotLabel (IndiName+"totals", true, 0, TextCorner, TextHpos, vp, text, FontColor, FontSize, FontName, 0, false, vis);      // Plot text label
  
  return(0);
}

//+------------------------------------------------------------------+
#include <hanover --- extensible functions (np).mqh>

