//+------------------------------------------------------------------+
//|                                   AccountEquityAnalyzer v1.00    |
//|                                   Copyright © 2007, Project1972  |
//|        Property of  http://www.forex-tsd.com ELITE section ONLY  |
//| You are NOT ALLOWED to distribute this tool in any public forum  |
//+------------------------------------------------------------------+
//|                      This indicator is based on:                 |
//|                                                  i-BalEq_v1.mq4  |
//|                                          Ким Игорь В. aka KimIV  |
//|                                             http://www.kimiv.ru  |
//+------------------------------------------------------------------+
//|                                  Account Equity Analyzer v2.00   |
//|              Fixed Run Hight CPU + Redesign + Fixed Wrong Draw   |
//|                                    by Cmkm-2011[thhudu@yahoo.com]|
//+------------------------------------------------------------------+
//|                                   Account Equity Analyzer v2.3   |
//|                      I have update   main code from i-BalEq2.mq4 | 
//+          ---------------------------------------------------------------+
//|                                                           i-BalEq2.mq4  |
//|  01.10.2006  Draw balance and equity on Chart.                          |
//|                                                 Ким Игорь В. aka KimIV  |
//|                                                    http://www.kimiv.ru  |
//|  23.06.2007  Added TickValue,  spread and swap..                        |
//|                           Fix update orders faster      =Xupypr=        |
//+           --------------------------------------------------------------+
//|  3-5-2012              + Draw much accurate + remove % risk      |
//|                                    by Cmkm-2012[thhudu@yahoo.com]|
//+------------------------------------------------------------------+
//|                                     Account Equity Analyzer v3.0 |
//|              add Draw Orders   [ JTrades.mq4 (copyright "Jagui")]|
//|                   Cmkm add show order time + loss/win order color|                                
//|                                    by Cmkm-2012[thhudu@yahoo.com]|
//+------------------------------------------------------------------+
//|     Account Equity Analyzer v4.0+Draw Orders+Virtual Balance.mq4 |
//|                                                                  |
//|       Add Virtual Room -Turn your Real Balance to Virtual Balance|
//|Practice how many time you want with the "Balance level" you like | 
//|                                       [psychological steady Tool]|
//|                                    by Cmkm-2012[thhudu@yahoo.com]|
//+------------------------------------------------------------------+
//|     Account Equity Analyzer v4.1+Draw Orders+Virtual Balance.mq4 |
//|                                  Up wrong formula version to net |
//+------------------------------------------------------------------+
#property copyright "Cmkm-2012[thhudu@yahoo.com]"
#property link  "All my indicators: http://www.forexfactory.com/showthread.php?t=325434"

#property indicator_separate_window
#property indicator_buffers 3

#property indicator_color1 Yellow
#property indicator_width1 2
#property indicator_color2 DodgerBlue
#property indicator_width2 1
#property indicator_color3 LightBlue
#property indicator_width3 2
// +------------------------------------------------------------------+
extern double Deposit =100;
extern string ________Virtual.Room_________="All.Your.Balance = 0 ==>MT4.Balance";
extern string ______________All.Your.Balance="= MT4.Balance + Balance.At.Home"; 

extern double  All.Your.Balance =0;
extern double  Balance.At.Home=0;
extern int  Switch.To.Virtual.Balance =100;


extern string _=".";

bool   CurSymbolOnly = false;

//
double dBuf0[], dBuf1[], dBuf2[];
double Balance,Equity,DW,StartingTime;
string MaxBL,MaxEQ;

//------- 
int    oob[];      // 
int    oty[];      // 
double olo[];      // 
string osy[];      // 
double oop[];      // 
int    ocb[];      // 
double ocp[];      // 
double osw[];      // 
double opr[];      //

//+-----------Draw Orders------------------+
     extern bool _______________Draw.Orders= true;
     extern bool show.Order.History.Time =true;
     extern double Time.Distance=0.7;
     extern color WinOder=Lime;
     extern color LossOder=Red;
bool showEntryArrows = true;
bool showExitLevels = true;
bool showEntryLevels = false;
bool showOpenCloseLines = true;
bool show.Order.Time = true;
     
int size=9;
color longColor = DeepSkyBlue;
color shortColor = MediumOrchid;
color closeColor = White;
int openCloseLineThickness = 2;
int lineStyle_1_Solid_2_Dotted = 1;
int minDistance = 8;
int maxDistance = 400;

int lastRunningTime = 0;
int pauseSec = 3;
int winding_long = 233;
int winding_short = 234;
int atr_period = 90;
double short_atr_factor = 1.5;

double ExtMapBuffer1[], priceValue, atr;
int i, current_winding, shift;
string name;
color currentColor;
//+------------------------------------------------------------------+
void init()
  {   IndicatorShortName("Account Equity Analyzer V4.0 | ");
   IndicatorDigits(2);
//----
   SetIndexBuffer(0, dBuf0);
   SetIndexLabel (0, "Balance");
   SetIndexStyle (0, DRAW_LINE);
//----
   SetIndexBuffer(1, dBuf1);
   SetIndexLabel (1, "Equity");
   SetIndexStyle (1, DRAW_LINE);
//----
   SetIndexBuffer(2, dBuf2);
   SetIndexLabel (2, "Deposit");
   SetIndexStyle (2, DRAW_LINE);
    

//+-----------Draw Orders-----------
  SetIndexBuffer(0, ExtMapBuffer1);

  if (lineStyle_1_Solid_2_Dotted == 1) lineStyle_1_Solid_2_Dotted = STYLE_SOLID;
  else lineStyle_1_Solid_2_Dotted = STYLE_DOT;
  if (lineStyle_1_Solid_2_Dotted == STYLE_DOT) {
    openCloseLineThickness = 1;
  }
//+------
   return (0);
  }
//+-----------------------------------------
void deinit()
{
 ObjectDelete("B_object");
 ObjectDelete("E_object");
 ObjectDelete("Deposit");

//+-----------Draw Orders-----------
  for (i = 0; i < OrdersHistoryTotal(); i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol() == Symbol()) {
        ObjectDelete(StringConcatenate("arrow", OrderTicket()));
        ObjectDelete(StringConcatenate("open1", OrderTicket()));
        ObjectDelete(StringConcatenate("open2", OrderTicket()));
        ObjectDelete(StringConcatenate("close1", OrderTicket()));
        ObjectDelete(StringConcatenate("close2", OrderTicket()));
        ObjectDelete(StringConcatenate("line", OrderTicket()));
        ObjectDelete(StringConcatenate("time1", OrderTicket()));
      }
    }
  }
  for (i = 0; i < OrdersTotal(); i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol() == Symbol()) {
        ObjectDelete(StringConcatenate("arrow", OrderTicket()));
        ObjectDelete(StringConcatenate("open1", OrderTicket()));
        ObjectDelete(StringConcatenate("open2", OrderTicket()));
        ObjectDelete(StringConcatenate("time1", OrderTicket()));
      }
    }
  }
 return(0);
}
//+----------------------Sum Account Profit--------------------------+
 
  double Prof(string sy="", int op=-1, int mn=-1, datetime dt=0)
  {
  double p=0;
  int    i, k=OrdersHistoryTotal();
  if     (sy=="0") sy=Symbol();
  for    (i=0; i<k; i++) {
  if     (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
  if     ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
  if     (OrderType()==OP_BUY || OrderType()==OP_SELL) {
  if     (mn<0 || OrderMagicNumber()==mn) {
  if     (dt<OrderCloseTime()) {
         p+=OrderProfit()+OrderCommission()+OrderSwap();
  } } } } } }
  return (p);
  }      
//+------------------------------------------------------------------+
void start()
  {
 double b,e,p,s,t;
 int    i,j,k;
 

 double MT4.Balance=AccountBalance();
 if (All.Your.Balance==0)
    {All.Your.Balance=MT4.Balance;
     Balance.At.Home=0;  }

  double Real=All.Your.Balance;
  int Virtual=Switch.To.Virtual.Balance;
  if (Virtual==0||Real==AccountBalance()){Virtual=Real;}
  

//----
 ReadDeals();
 if (oob[0]<0) return;
 k=ArraySize(oob);
//----
 for (i=Bars;i>=oob[0];i--)
   {
     dBuf0[i]=EMPTY_VALUE;
     dBuf1[i]=EMPTY_VALUE;
   }
   
b= MT4.Balance+Balance.At.Home;

   for (i=oob[0];i>=0;i--)
    {
e=0; 
  for (j=0;j<k;j++)
  {
   if (i==ocb[j] && ocp[j]!=0) 
       b+=osw[j]+opr[j];
   else if (i<=oob[j] && i>=ocb[j])
   {
    p=MarketInfo(osy[j],MODE_POINT);
    s=p*MarketInfo(osy[j],MODE_SPREAD);
    t=NormalizeDouble(TickValue(osy[j],i),2);
    if (t==0) t=10;
    if (p==0) if (StringFind(osy[j],"JPY")<0) p=0.0001; else p=0.01;
    if (oty[j]==OP_BUY) e+=(iClose(osy[j],0,i)-oop[j])/p*olo[j]*t;
    else e+=(oop[j]-iClose(osy[j],0,i)-s)/p*olo[j]*t;
    if (osw[j]!=0) e+=(oob[j]-i)*(osw[j]/(oob[j]-ocb[j]));
   }
  }
//----
      dBuf2[i] = Deposit;
      if (Prof()<=0){   
              dBuf0[i] = (b+MathAbs(Prof()))  *Virtual/Real;
              dBuf1[i] = (b+MathAbs(Prof())+e)*Virtual/Real;  }  //If Profit History > 0 : Draw begin from Balance + (n Order) -> so we need to subtract (n Order)
             else { 
                dBuf0[i] = (b-MathAbs(Prof()))  *Virtual/Real;
                dBuf1[i] = (b-MathAbs(Prof())+e)*Virtual/Real; } //If Profit History < 0 : Draw begin from Balance - (n Order) -> so we need to plus (n Order)
     }

//---------------------  

MaxBL="Balance = $ "+DoubleToStr(((AccountBalance()+Balance.At.Home)*Virtual/Real),1);
MaxEQ="Equity     = $ "+DoubleToStr((AccountEquity()+Balance.At.Home)*Virtual/Real,1);

setLabel("B_object",MaxBL,Yellow,0,5,15,false,12,"Arial");
setLabel("E_object",MaxEQ,DodgerBlue,0,5,33,false,12,"Arial");   
setLabel("Deposit","Deposit  = $ "+ DoubleToStr(Deposit,0),LightBlue,0,5,51,false,12,"Arial");
 


//+-----------Draw Orders-----------
if (_______________Draw.Orders==true) {
   string Font="Comic Sans MS";
   int day,hour,mi,se;
   	

          
  double min_distance = minDistance * Point;
  double max_distance = maxDistance * Point;
  if (TimeLocal() > lastRunningTime + pauseSec) {
    for (i = 0; i < OrdersHistoryTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
        if (OrderSymbol() == Symbol()) {
          shift = iBarShift(NULL, 0, OrderOpenTime(), false);
          atr = iATR(NULL, 0, atr_period, shift);
          
          if (OrderType() == OP_BUY) {
            currentColor = longColor;
            current_winding = winding_long;
            priceValue = Low[shift] - MathMin(MathMax(atr, min_distance), max_distance);
          }
          if (OrderType() == OP_SELL) {
            currentColor = shortColor;
            current_winding = winding_short;
            priceValue = High[shift] + MathMin(MathMax(atr * short_atr_factor, min_distance), max_distance);
          }
          if (OrderType() == OP_BUY || OrderType() == OP_SELL) {
          
          //--Time color
          int Tcolor;
            if(OrderProfit() >  0){ Tcolor=DeepSkyBlue;}
            if(OrderProfit() <  0){ Tcolor=MediumOrchid;}
          //-------
            if (showEntryArrows) {
              name = StringConcatenate("arrow", OrderTicket());
              ObjectDelete(name);
              ObjectCreate(name, OBJ_ARROW, 0, OrderOpenTime(), priceValue);
              ObjectSet(name, OBJPROP_ARROWCODE, current_winding);
              ObjectSet(name, OBJPROP_COLOR, currentColor);
              ObjectSet(name, OBJPROP_WIDTH, 0.5);
            }
          //-------
            if (showEntryLevels) {
              name = StringConcatenate("open1", OrderTicket());
              ObjectDelete(name);
              ObjectCreate(name, OBJ_ARROW, 0, OrderOpenTime(), OrderOpenPrice());
              ObjectSet(name, OBJPROP_ARROWCODE, 1);
              ObjectSet(name, OBJPROP_COLOR, currentColor);
            }
          //-------
            if (show.Order.History.Time) {
              name = StringConcatenate("time1", OrderTicket());
              double priceValueTime;
              if (OrderType() == OP_SELL) 
                  {priceValueTime = priceValue+Time.Distance;} 
              else{priceValueTime = priceValue-Time.Distance;}
              ObjectCreate(name, OBJ_TEXT, 0, OrderOpenTime()+ Period()*60*5, priceValueTime);

              //--time
              se=OrderCloseTime()-OrderOpenTime();//seconds
              day=se/3600/24;
              hour=se/3600;
              mi=se/60;
                 if(se>=60&&se<60*60 ) {ObjectSetText(name,mi+"  Minute  ", size, Font, Tcolor);}
                 if(se>=60*60&& se<60*60*24 ) {ObjectSetText(name,hour+"  Hours  ", size, Font, Tcolor);}
                 if(se>=60*60*24 ) {ObjectSetText(name,day+"  Day  ", size, Font, Tcolor);}
                 if(se<60) {ObjectSetText(name,se+"  Seconds  ", size, Font, Tcolor);}

            }
          //-------
            if (showExitLevels) {
              name = StringConcatenate("close2", OrderTicket());
              ObjectDelete(name);
              ObjectCreate(name, OBJ_ARROW, 0, OrderCloseTime(), OrderClosePrice());
              ObjectSet(name, OBJPROP_ARROWCODE, 251);//3,34
              ObjectSet(name, OBJPROP_COLOR, closeColor);

            }
          //-------
            if (showOpenCloseLines) {
              name = StringConcatenate("line", OrderTicket());
              ObjectDelete(name);
              ObjectCreate(name, OBJ_TREND, 0, OrderOpenTime(), OrderOpenPrice(), OrderCloseTime(), OrderClosePrice());
            if(OrderProfit() >  0)ObjectSet(name, OBJPROP_COLOR, Lime);
            if(OrderProfit() <  0)ObjectSet(name, OBJPROP_COLOR, Red);
              ObjectSet(name, OBJPROP_RAY, false);
              ObjectSet(name, OBJPROP_STYLE, lineStyle_1_Solid_2_Dotted);
              ObjectSet(name, OBJPROP_WIDTH, openCloseLineThickness);
            }
          }
        }
      }
    }
    
    for (i = 0; i < OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
        if (OrderSymbol() == Symbol()) {
          shift = iBarShift(NULL, 0, OrderOpenTime(), false);
          atr = iATR(NULL, 0, atr_period, shift);
          
                    //--Time color

            if(OrderProfit() >  0){ Tcolor=Lime;}
            if(OrderProfit() <  0){ Tcolor=Red;}
            //----
          if (OrderType() == OP_BUY) {
            currentColor = longColor;
            current_winding = winding_long;
            priceValue = Low[shift] - MathMin(MathMax(atr, min_distance), max_distance);
          }
          if (OrderType() == OP_SELL) {
            currentColor = shortColor;
            current_winding = winding_short;
            priceValue = High[shift] + MathMin(MathMax(atr * short_atr_factor, min_distance), max_distance);
          }
          if (OrderType() == OP_BUY || OrderType() == OP_SELL) {
          //-------
            if (showEntryArrows) {
              name = StringConcatenate("arrow", OrderTicket());
              ObjectDelete(name);
              ObjectCreate(name, OBJ_ARROW, 0, OrderOpenTime(), priceValue);
              ObjectSet(name, OBJPROP_ARROWCODE, current_winding);
              ObjectSet(name, OBJPROP_COLOR, currentColor);
              ObjectSet(name, OBJPROP_WIDTH, 0.5);
            }
          //-------
            if (showEntryLevels) {
              name = StringConcatenate("open1", OrderTicket());
              ObjectDelete(name);
              ObjectCreate(name, OBJ_ARROW, 0, OrderOpenTime(), OrderOpenPrice());
              ObjectSet(name, OBJPROP_ARROWCODE, 1);
              ObjectSet(name, OBJPROP_COLOR, currentColor);
           }
          //-------
            if (show.Order.Time) {
              name = StringConcatenate("time1", OrderTicket());
              if (OrderType() == OP_SELL) 
                  {priceValueTime = priceValue+Time.Distance;} 
              else{priceValueTime = priceValue-Time.Distance;}
              ObjectCreate(name, OBJ_TEXT, 0, OrderOpenTime()+ Period()*60*5, priceValueTime);
              //--time
              se=TimeCurrent()-OrderOpenTime();//seconds
              day=se/3600/24;
              hour=se/3600;
              mi=se/60;
                 if(se>=60&&se<60*60 ) {ObjectSetText(name,mi+"  Minute  ", size, Font, Tcolor);}
                 if(se>=60*60&& se<60*60*24 ) {ObjectSetText(name,hour+"  Hours  ", size, Font, Tcolor);}
                 if(se>=60*60*24 ) {ObjectSetText(name,day+"  Day  ", size, Font, Tcolor);}
                 if(se<60) {ObjectSetText(name,se+"  Seconds  ", size, Font, Tcolor);}
             
           }
          }
        }
      }
    }
    
    WindowRedraw();
  }}
  //+-----------Draw Orders-----------
  }
//+------------------------------------------------------------------+
void setLabel(string name, string text, color col, int corner,
            int x, int y, bool back = false, int fontsize = 12, 
            string fontname = "MS Sans Serif") {
   if (ObjectFind(name)==-1){
      // aaa
      ObjectCreate(name, OBJ_LABEL, WindowOnDropped(),1, 0, 0);
      ObjectSetText(name, text, fontsize, fontname, col);
      ObjectSet(name, OBJPROP_CORNER, corner);
      ObjectSet(name, OBJPROP_BACK,back);
      ObjectSet(name, OBJPROP_XDISTANCE, x);
      ObjectSet(name, OBJPROP_YDISTANCE, y);          
   }else{
      ObjectSetText(name, text, fontsize, fontname, col);
      ObjectSet(name, OBJPROP_CORNER, corner);
      ObjectSet(name, OBJPROP_BACK,back);
      ObjectSet(name, OBJPROP_XDISTANCE, x);
      ObjectSet(name, OBJPROP_YDISTANCE, y); 
   }  
}

//+-------TickValue----------------------------------------------+
double TickValue(string symbol, int bar)
{
 double value=MarketInfo(symbol,MODE_TICKVALUE);
 if (StringLen(symbol)!=6) return(value);
 double size=MarketInfo(symbol,MODE_LOTSIZE)*MarketInfo(symbol,MODE_TICKSIZE);
 if (StringSubstr(symbol,3,3)=="USD") return(value);
 else if (StringSubstr(symbol,0,3)=="USD") value=size/iClose(symbol,0,bar);
 else
 {
  string BQ=StringSubstr(symbol,0,3)+"USD";
  if (iClose(BQ,0,0)==0) BQ="USD"+StringSubstr(symbol,0,3);
  if (iClose(BQ,0,0)==0) return(value);
  if (StringSubstr(BQ,0,3)=="USD") value=size/iClose(BQ,0,bar)/iClose(symbol,0,bar);
  else value=size*iClose(BQ,0,bar)/iClose(symbol,0,bar);
 } 
 return(value);
}
//+----------------------------------------------------------------+


//+---------ReadDeals-------------------------------------------------+
void ReadDeals()
{
 ArrayResize(oob,0);
 ArrayResize(oty,0);
 ArrayResize(olo,0);
 ArrayResize(osy,0);
 ArrayResize(oop,0);
 ArrayResize(ocb,0);
 ArrayResize(ocp,0);
 ArrayResize(osw,0);
 ArrayResize(opr,0);
 
 int h=OrdersHistoryTotal(),i,k;

 for (i=0;i<h;i++)
 {
  if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
  {
   if (!CurSymbolOnly || OrderSymbol()==Symbol())
   {
    if (OrderType()==OP_BUY || OrderType()==OP_SELL)
    {
     k=ArraySize(oob);
     ArrayResize(oob,k+1);
     ArrayResize(oty,k+1);
     ArrayResize(olo,k+1);
     ArrayResize(osy,k+1);
     ArrayResize(oop,k+1);
     ArrayResize(ocb,k+1);
     ArrayResize(ocp,k+1);
     ArrayResize(osw,k+1);
     ArrayResize(opr,k+1);
     oob[k]=iBarShift(NULL,0,OrderOpenTime());  // номер бара открытия
     oty[k]=OrderType();                        // тип
     olo[k]=OrderLots();                        // лот
     osy[k]=OrderSymbol();                      // инструмент
     oop[k]=OrderOpenPrice();                   // цена открытия
     ocb[k]=iBarShift(NULL,0,OrderCloseTime()); // номер бара закрытия
     ocp[k]=OrderClosePrice();                  // цена закрытия
     osw[k]=OrderSwap();                        // своп
     opr[k]=OrderProfit();                      // прибыль
    }
   }
  }
 }
 h=OrdersTotal();
 for (i=0;i<h;i++)
 {
  if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
  {
   if (!CurSymbolOnly || OrderSymbol()==Symbol())
   {
    if (OrderType()==OP_BUY || OrderType()==OP_SELL)
    {
     k=ArraySize(oob);
     ArrayResize(oob,k+1);
     ArrayResize(oty,k+1);
     ArrayResize(olo,k+1);
     ArrayResize(osy,k+1);
     ArrayResize(oop,k+1);
     ArrayResize(ocb,k+1);
     ArrayResize(ocp,k+1);
     ArrayResize(osw,k+1);
     ArrayResize(opr,k+1);
     oob[k]=iBarShift(NULL,0,OrderOpenTime()); // номер бара открытия
     oty[k]=OrderType();                       // тип
     olo[k]=OrderLots();                       // лот
     osy[k]=OrderSymbol();                     // инструмент
     oop[k]=OrderOpenPrice();                  // цена открытия
     ocb[k]=0;                                 // номер бара закрытия
     ocp[k]=0;                                 // цена закрытия
     osw[k]=OrderSwap();                       // своп
     opr[k]=OrderProfit();                     // прибыль
    }
   }
  }
 }
}