//Equity trail is made from Don Steinitz equity trail robot, however adapt to equity trail.
//CashEquityTrail_v1.mq4  091003

#property copyright "NoCopyright © 2009, finimej"
#property link      ""

#include <stdlib.mqh>

extern double PercentageEquityTakeProfit = 3.0;  //take profits is 3% of account equity
extern double PercentageEquityStopLoss = 10.0;    //stoploss is 10% of account equity
extern double PercentageEquityTrigger = 1.0; //trail stop start at 
extern double PercentageEquityTrail = 0.5; //trailstep is 0.5% of the account equity.

extern string to = "---Text Object Settings---";
extern int StatusTxtSize = 10;
extern color StatusColor = White;
extern int CommentTxtSize = 10;
extern color CommentColor = White;
extern int ProfitTxtSize = 10;
extern color ProfitColor = White;
extern int DrawDownTxtSize = 10;
extern color DrawDownColor = White;
extern string db = "--- Debug file settings---";
extern bool Debug = FALSE;
extern bool Debug_LiveTrade = FALSE;
extern string Trade_Log = "_SET_TradeLog";
extern bool Debug_BackTestTrade = FALSE;
extern string BT_Trade_Log = "_SET_BTTradeLog";
string g_name_244;
string gs_dummy_252;
string gs_260 = "SET11_";
int gi_268;
int gi_272;
int gi_276;
int gi_280;
int gi_284;
int gi_288;
int gi_292;
int gi_296;
int gi_300;
int gi_304;
string gs_308;
string gs_316;
string gs_324;
string gs_332;
string gs_340;
string gs_348;
string gs_356;
string gs_364;
string gs_372;
string gs_380;
string g.StartingEquity;
string g.NewStartingEquity;
string g.HighEquity;
string g.LowEquity;
string g.Attached;
string g.LockedProfit;
double gd.LargestDrawDownEquity;
double gd.HighestEquityDiff;
double d.StartingEquity;
double d.NewStartingEquity;
double d.LowEquity = 0.0;
double d.HighEquity;
double d.Attached = -10.0;
double d.LockedProfit = 0.0;
int i.Slippage = 5;
int gi_508 = 5;
int gi_512 = 1000;

int init() {
   int NrOpenOrders; 
   if (Debug == TRUE) SetupLogFiles();
      DeleteExistingLabels();
      SetupLabels();
      ClearLabels();
      GetGlobalVars();
      if (d.Attached < 0.0) {
         d.StartingEquity = AccountBalance();
         SaveStartingEquity(d.StartingEquity);
         d.Attached = 10.0;
         SaveAttached(d.Attached);
      }
      NrOpenOrders = CalculateCurrentOrders();
      if (NrOpenOrders == 0) ResetVars(d.StartingEquity);
   
   return (0);
}

int deinit() {
   if (Debug == TRUE) CloseLogFiles();
   ClearLabels();
   DeleteExistingLabels();
   return (0);
}

void ResetVars(double ad_0) {
   d.StartingEquity = ad_0;
   SaveStartingEquity(d.StartingEquity);
   d.NewStartingEquity = ad_0;
   SaveNewStartingEquity(d.NewStartingEquity);
   d.LowEquity = d.StartingEquity;
   SaveLowEquity(d.LowEquity);
   d.HighEquity = d.StartingEquity;
   SaveHighEquity(d.HighEquity);
   d.LockedProfit = 0;
   SaveLockedProfit(d.LockedProfit);
}

int start() {
   int l_ticket_8;
   int NrOpenOrders = 0;
   int li_4 = 1;
   if (gi_272 < 10) {
      SetupLabels();
      ClearLabels();
      DeleteExistingLabels();
      SetupLabels();
   }

   if (IsTradeAllowed() == FALSE) return (0);
   NrOpenOrders = CalculateCurrentOrders();
   if (NrOpenOrders == 0) {
      if (d.StartingEquity != d.NewStartingEquity) ResetVars(d.NewStartingEquity);
      OutputComment1ToChart("No trades to manage.");
      return (0);
   }
   OutputComment1ToChart("Managing " + NrOpenOrders + " Trades.");
   RefreshRates();
   TrackEquity();
   CheckForClose();
   return (0);
}

void CheckForClose() {
   double ld.CurrentEquityDiff = 0;
   double ld.EquityTakeProfit = 0;
   double ld.EquityTakeProfitMoney = 0;
   double ld.EquitySLmoney = 0;
   double ld.EquityStopLoss = 0;
   double ld.EquityTrailTrigger = 0;
   double ld.EquityTrail = 0;
   
   double ld.CurrtAccountEquity = AccountEquity();
   gd.LargestDrawDownEquity = d.StartingEquity - d.LowEquity;
   
   ld.CurrentEquityDiff = ld.CurrtAccountEquity - d.StartingEquity;
   gd.HighestEquityDiff = d.HighEquity - d.StartingEquity;
   if (PercentageEquityTakeProfit > 0.0) {
      ld.EquityTakeProfitMoney = d.StartingEquity * PercentageEquityTakeProfit / 100.0;
      ld.EquityTakeProfit = d.StartingEquity + ld.EquityTakeProfitMoney;
   }
   if (PercentageEquityStopLoss > 0.0) {
      ld.EquitySLmoney = d.StartingEquity * PercentageEquityStopLoss / 100.0;
      ld.EquityStopLoss = d.StartingEquity - ld.EquitySLmoney;
   }
   
   ld.EquityTrailTrigger = d.StartingEquity * PercentageEquityTrigger / 100.0;
   
   if (PercentageEquityTrail > 0.0) ld.EquityTrail = d.StartingEquity * PercentageEquityTrail / 100.0;
   
   OutputEquityToChart("Starting Equity : " + DoubleToStr(d.StartingEquity, 2) + "  Current Equity : " + DoubleToStr(ld.CurrtAccountEquity, 2));
   
   if (ld.CurrentEquityDiff > 0.0) OutputProfitToChart(" Current Profit : " + DoubleToStr(ld.CurrentEquityDiff, 2), 32768);
   
   else OutputProfitToChart(" Current Loss : " + DoubleToStr(ld.CurrentEquityDiff, 2), 255);
   
   OutputDrawDownToChart(" Max Profit : " + DoubleToStr(gd.HighestEquityDiff, 2) + "  Max Drawdown : " + DoubleToStr(gd.LargestDrawDownEquity, 2));
   
   if (PercentageEquityTakeProfit > 0.0) {
      if (ld.CurrtAccountEquity >= ld.EquityTakeProfit) {
         OutputProfitTargetToChart("Taking profit at " + DoubleToStr(PercentageEquityTakeProfit, 2) + "% profit = $" + DoubleToStr(ld.CurrentEquityDiff, 2), 32768);
         CloseAllTrades("Take Profit Reached", ld.CurrtAccountEquity);
      } else OutputProfitTargetToChart("Waiting for profit of " + DoubleToStr(PercentageEquityTakeProfit, 2) + "% profit = $" + DoubleToStr(ld.EquityTakeProfitMoney, 2), ProfitColor);
   } else OutputProfitTargetToChart("Equity TakeProfit not used", ProfitColor);
   
   if (PercentageEquityStopLoss > 0.0) {
      if (ld.CurrtAccountEquity <= ld.EquityStopLoss) {
         OutputLossTargetToChart("Taking loss at " + DoubleToStr(PercentageEquityStopLoss, 2) + "% loss = $" + DoubleToStr(ld.CurrentEquityDiff, 2), 255);
         CloseAllTrades("StopLoss Reached", ld.CurrtAccountEquity);
      } else OutputLossTargetToChart("Waiting for loss of " + DoubleToStr(PercentageEquityStopLoss, 2) + "% loss = $" + DoubleToStr(ld.EquitySLmoney, 2), ProfitColor);
   } else OutputLossTargetToChart("Equity StopLoss not used", ProfitColor);
   
   if (PercentageEquityTrail > 0.0) {
      OutputTrailToChart("Equity Trailing Stop starting at $" + DoubleToStr(ld.EquityTrailTrigger, 2));
      OutputTrail2ToChart(" and trailing by $" + DoubleToStr(ld.EquityTrail, 2));
      if (d.LockedProfit > 0.0 && ld.CurrentEquityDiff <= d.LockedProfit) {
         d.LockedProfit = 0;
         SaveLockedProfit(d.LockedProfit);
         OutputTrailToChart("Equity trailing stop hit. Closing trades.");
         CloseAllTrades("Trailing Stop Reached", ld.CurrentEquityDiff);
         return;
      }
   
      if (ld.CurrentEquityDiff >= ld.EquityTrailTrigger) {
         if (ld.CurrentEquityDiff - ld.EquityTrail > d.LockedProfit) {
            d.LockedProfit = ld.CurrentEquityDiff - ld.EquityTrail;
            SaveLockedProfit(d.LockedProfit);
         }
      }
   
      if (d.LockedProfit > 0.0) {
         OutputLockedProfitToChart("Locked profits = " + DoubleToStr(d.LockedProfit, 2));
         return;
      }
      OutputLockedProfitToChart("No locked profits yet");
      return;
   }
   OutputTrailToChart("Equity Trailing Stop not used");
}

void CloseAllTrades(string ld.msg, double ResetEquityDiff) {
   int li.ticket;
   int li.TotalOrders = OrdersTotal();
   OutputComment1ToChart("Closing all trades");
   for (int j = li.TotalOrders - 1; j >= 0; j--) {
      OrderSelect(j, SELECT_BY_POS);
      li.ticket = CloseOrder(OrderSymbol(), OrderTicket(), OrderLots(), OrderType());
      if (li.ticket == 0) {
         Sleep(3000);
         j++;
      } else
         if (Debug == TRUE) WriteTradeExit(ld.msg, OrderTicket(), OrderType(), OrderOpenPrice(), OrderLots());
   }
   ResetVars(ResetEquityDiff);
}

int CloseOrder(string ls.Symbol, int li.Ticket, double ld.lots, int li.OrderType) {
   int li.OrderCloseTicket;
   int li.Errors;
   double ld.MarketPrice;
   bool lb.IsAllOrderClosed = FALSE;
   if (li.OrderType == 0) ld.MarketPrice = MarketInfo(ls.Symbol, MODE_BID);
   if (li.OrderType == 1) ld.MarketPrice = MarketInfo(ls.Symbol, MODE_ASK);
   int li.Digits = MarketInfo(ls.Symbol, MODE_DIGITS);
   if (li.Digits > 0) ld.MarketPrice = NormalizeDouble(ld.MarketPrice, li.Digits);

   int li.ClosedOrders = 0;
   while (!lb.IsAllOrderClosed) {
      if (IsTradeAllowed() == TRUE) {
         li.OrderCloseTicket = OrderClose(li.Ticket, ld.lots, ld.MarketPrice, i.Slippage, Violet);
         li.Errors = GetLastError();
      } else li.ClosedOrders++;
      if (li.OrderCloseTicket == 1) lb.IsAllOrderClosed = TRUE;
      li.Errors = GetLastError();
      switch (li.Errors) {
      case 0/* NO_ERROR */:
         lb.IsAllOrderClosed = TRUE;
         break;
      case 4/* SERVER_BUSY */:
      case 6/* NO_CONNECTION */:
      case 129/* INVALID_PRICE */:
      case 136/* OFF_QUOTES */:
      case 137/* BROKER_BUSY */:
      case 146/* TRADE_CONTEXT_BUSY */:
      case 128/* TRADE_TIMEOUT */:
         li.ClosedOrders++;
         break;
      case 135/* PRICE_CHANGED */:
      case 138/* REQUOTE */:
         RefreshRates();
         continue;
         break;
      default:
         lb.IsAllOrderClosed = TRUE;
      }
      if (li.ClosedOrders > gi_508) lb.IsAllOrderClosed = TRUE;
      if (!lb.IsAllOrderClosed) {
         Sleep(gi_512);
         RefreshRates();
      }
   }
   if (li.OrderCloseTicket == 1 || li.Errors == 0/* NO_ERROR */) return (1);
   Print(" Error closing order : (", li.Errors, ") " + ErrorDescription(li.Errors));
   return (0);
}

string tf2txt(int li.period) {
   switch (li.period) {
   case 1:
      return ("M1");
   case 5:
      return ("M5");
   case 15:
      return ("M15");
   case 30:
      return ("M30");
   case 60:
      return ("H1");
   case 240:
      return ("H4");
   case 1440:
      return ("D1");
   case 10080:
      return ("W1");
   case 43200:
      return ("MN");
   }
   return ("??");
}

int CalculateCurrentOrders() {
   int li.buyorders = 0;
   int li.sellorders = 0;
   int li.totalOpenorders = 0;
   int li.totalorders = OrdersTotal();
   for (int j = 0; j < li.totalorders; j++) {
      OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
      if (OrderType() == OP_BUY) li.buyorders++;
      if (OrderType() == OP_SELL) li.sellorders++;
   }
   li.totalOpenorders = li.buyorders + li.sellorders;
   return (li.totalOpenorders);
}

void TrackEquity() {
   double ld.AccountEquity = AccountEquity();
   if (ld.AccountEquity < d.LowEquity || d.LowEquity < 1.0) {
      d.LowEquity = ld.AccountEquity;  //get the lowest equity and save it to global variable
      SaveLowEquity(d.LowEquity);
   }
   if (ld.AccountEquity > d.HighEquity) {
      d.HighEquity = ld.AccountEquity;  //get the highest equity and save it to the global variable
      SaveHighEquity(d.HighEquity);
   }
}

void ClearLabels() {
   string ls_0 = " ";
   OutputLabelToChart(gs_308, gi_268, StatusTxtSize, StatusColor, ls_0);
   OutputLabelToChart(gs_316, gi_272, CommentTxtSize, CommentColor, ls_0);
   OutputLabelToChart(gs_324, gi_276, CommentTxtSize, CommentColor, ls_0);
   OutputLabelToChart(gs_332, gi_280, ProfitTxtSize, ProfitColor, ls_0);
   OutputLabelToChart(gs_340, gi_284, DrawDownTxtSize, DrawDownColor, ls_0);
   OutputLabelToChart(gs_348, gi_288, ProfitTxtSize, ProfitColor, ls_0);
   OutputLabelToChart(gs_356, gi_292, ProfitTxtSize, ProfitColor, ls_0);
   OutputLabelToChart(gs_364, gi_296, ProfitTxtSize, ProfitColor, ls_0);
   OutputLabelToChart(gs_372, gi_300, ProfitTxtSize, ProfitColor, ls_0);
   OutputLabelToChart(gs_380, gi_304, ProfitTxtSize, ProfitColor, ls_0);
}

void DeleteExistingLabels() {
   string l_name_4;
   int l_objs_total_0 = ObjectsTotal(OBJ_LABEL);
   string ls_12 = gs_260 + Symbol() + tf2txt(Period());
   if (l_objs_total_0 > 0) {
      for (int l_objs_total_20 = l_objs_total_0; l_objs_total_20 >= 0; l_objs_total_20--) {
         l_name_4 = ObjectName(l_objs_total_20);
         if (StringFind(l_name_4, ls_12 + "Status", 0) >= 0) ObjectDelete(l_name_4);
         else {
            if (StringFind(l_name_4, ls_12 + "Comment1", 0) >= 0) ObjectDelete(l_name_4);
            else {
               if (StringFind(l_name_4, ls_12 + "Equity", 0) >= 0) ObjectDelete(l_name_4);
               else {
                  if (StringFind(l_name_4, ls_12 + "Profit", 0) >= 0) ObjectDelete(l_name_4);
                  else {
                     if (StringFind(l_name_4, ls_12 + "Loss", 0) >= 0) ObjectDelete(l_name_4);
                     else {
                        if (StringFind(l_name_4, ls_12 + "DrawDown", 0) >= 0) ObjectDelete(l_name_4);
                        else {
                           if (StringFind(l_name_4, ls_12 + "Trail", 0) >= 0) ObjectDelete(l_name_4);
                           else
                              if (StringFind(l_name_4, ls_12 + "Locked", 0) >= 0) ObjectDelete(l_name_4);
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

void SetupLabels() {
   string ls_0 = gs_260 + Symbol() + tf2txt(Period());
   gi_268 = 12;
   gi_272 = gi_268 + StatusTxtSize + 4;
   gi_276 = gi_272 + CommentTxtSize + 4;
   gi_280 = gi_276 + CommentTxtSize + 4;
   gi_284 = gi_280 + ProfitTxtSize + 4;
   gi_288 = gi_284 + ProfitTxtSize + 4;
   gi_292 = gi_288 + ProfitTxtSize + 4;
   gi_296 = gi_292 + ProfitTxtSize + 4;
   gi_300 = gi_296 + ProfitTxtSize + 4;
   gi_304 = gi_300 + ProfitTxtSize + 4;
   gs_308 = ls_0 + "Status";
   gs_316 = ls_0 + "Comment1";
   gs_324 = ls_0 + "Equity";
   gs_332 = ls_0 + "Profit";
   gs_340 = ls_0 + "DrawDown";
   gs_348 = ls_0 + "ProfitTarget";
   gs_356 = ls_0 + "LossTarget";
   gs_364 = ls_0 + "Locked";
   gs_372 = ls_0 + "Trail";
   gs_380 = ls_0 + "Trail2";
}

void OutputLabelToChart(string a_name_0, int a_y_8, int a_fontsize_12, color a_color_16, string a_text_20) {
   if (ObjectFind(a_name_0) != 0) {
      ObjectCreate(a_name_0, OBJ_LABEL, 0, 0, 0);
      ObjectSet(a_name_0, OBJPROP_CORNER, 0);
      ObjectSet(a_name_0, OBJPROP_XDISTANCE, 20);
      ObjectSet(a_name_0, OBJPROP_YDISTANCE, a_y_8);
   }
   ObjectSetText(a_name_0, a_text_20, a_fontsize_12, "Arial Bold", a_color_16);
}

void OutputComment1ToChart(string ld.msg) {
   OutputLabelToChart(gs_316, gi_272, CommentTxtSize, CommentColor, ld.msg);
}

void OutputEquityToChart(string ld.msg) {
   OutputLabelToChart(gs_324, gi_276, CommentTxtSize, CommentColor, ld.msg);
}

void OutputProfitToChart(string ld.msg, int ai_8) {
   OutputLabelToChart(gs_332, gi_280, ProfitTxtSize, ai_8, ld.msg);
}

void OutputDrawDownToChart(string ld.msg) {
   OutputLabelToChart(gs_340, gi_284, DrawDownTxtSize, DrawDownColor, ld.msg);
}

void OutputProfitTargetToChart(string ld.msg, int ai_8) {
   OutputLabelToChart(gs_348, gi_288, ProfitTxtSize, ai_8, ld.msg);
}

void OutputLossTargetToChart(string ld.msg, int ai_8) {
   OutputLabelToChart(gs_356, gi_292, ProfitTxtSize, ai_8, ld.msg);
}

void OutputLockedProfitToChart(string ld.msg) {
   OutputLabelToChart(gs_364, gi_296, ProfitTxtSize, ProfitColor, ld.msg);
}

void OutputTrailToChart(string ld.msg) {
   OutputLabelToChart(gs_372, gi_300, ProfitTxtSize, ProfitColor, ld.msg);
}

void OutputTrail2ToChart(string ld.msg) {
   OutputLabelToChart(gs_380, gi_304, ProfitTxtSize, ProfitColor, ld.msg);
}

void GetGlobalVars() {
   NameGlobalVars();
   InitGlobalVars();
   GetGlobalVarValues();
}

void GetGlobalVarValues() {
   d.StartingEquity = GlobalVariableGet(g.StartingEquity);
   d.NewStartingEquity = GlobalVariableGet(g.NewStartingEquity);
   d.HighEquity = GlobalVariableGet(g.HighEquity);
   d.LowEquity = GlobalVariableGet(g.LowEquity);
   d.Attached = GlobalVariableGet(g.Attached);
   d.LockedProfit = GlobalVariableGet(g.LockedProfit);
}

void InitGlobalVars() {
   if (!GlobalVariableCheck(g.StartingEquity)) GlobalVariableSet(g.StartingEquity, 0);
   if (!GlobalVariableCheck(g.NewStartingEquity)) GlobalVariableSet(g.NewStartingEquity, 0);
   if (!GlobalVariableCheck(g.HighEquity)) GlobalVariableSet(g.HighEquity, 0);
   if (!GlobalVariableCheck(g.LowEquity)) GlobalVariableSet(g.LowEquity, 0);
   if (!GlobalVariableCheck(g.Attached)) GlobalVariableSet(g.Attached, -10.0);
   if (!GlobalVariableCheck(g.LockedProfit)) GlobalVariableSet(g.LockedProfit, 0);
}

void NameGlobalVars() {
   string ls_0 = gs_260 + Symbol() + tf2txt(Period());
   g.StartingEquity = ls_0 + "_StartingEquity";
   g.NewStartingEquity = ls_0 + "_NewStartingEquity";
   g.HighEquity = ls_0 + "_HighEquity";
   g.LowEquity = ls_0 + "_LowEquity";
   g.Attached = ls_0 + "_Attached";
   g.LockedProfit = ls_0 + "_LockedProfit";
}

void SaveStartingEquity(double ad_0) {
   GlobalVariableSet(g.StartingEquity, ad_0);
}

void SaveNewStartingEquity(double ad_0) {
   GlobalVariableSet(g.NewStartingEquity, ad_0);
}

void SaveHighEquity(double ad_0) {
   GlobalVariableSet(g.HighEquity, ad_0);
}

void SaveLowEquity(double ad_0) {
   GlobalVariableSet(g.LowEquity, ad_0);
}

void SaveAttached(double ad_0) {
   GlobalVariableSet(g.Attached, ad_0);
}

void SaveLockedProfit(double ad_0) {
   GlobalVariableSet(g.LockedProfit, ad_0);
}

void CloseLogFiles() {
   int l_global_var_0;
   if (Debug_BackTestTrade == TRUE) {
      if (GlobalVariableCheck("BTMyHandleTrade") == TRUE) {
         l_global_var_0 = GlobalVariableGet("BTMyHandleTrade");
         FileFlush(l_global_var_0);
         FileClose(l_global_var_0);
         GlobalVariableDel("BTMyHandleTrade");
      }
   }
}

void SetupLogFiles() {
   int l_error_8;
   int l_file_12;
   string l_name_0 = Symbol() + " " + BT_Trade_Log + ".txt";
   if (Debug_BackTestTrade == TRUE) {
      GlobalVariableSet("BTMyHandleTrade", 0);
      if (GlobalVariableCheck("BTMyHandleTrade") == FALSE) {
         l_error_8 = GetLastError();
         Print("Error creating Global Variable BTMyHandleTrade: (" + l_error_8 + ") " + ErrorDescription(l_error_8));
         return;
      }
      l_file_12 = FileOpen(l_name_0, FILE_CSV|FILE_WRITE, "\t");
      GlobalVariableSet("BTMyHandleTrade", l_file_12);
   }
   g_name_244 = AccountNumber() + " " + Symbol() + Trade_Log + "_" + Month() + "-" + Day() + ".txt";
}


void WriteExit(int li.period, string as_4, int ai_12, double ad_16) {
   if (Debug_BackTestTrade == TRUE) {
      BTWrite_Trade("-----------------------------------------------------------------");
      BTWrite_Trade(" " + Symbol() + " #" + li.period + " " + as_4);
      if (ad_16 > 0.1) BTWrite_Prices(ai_12, ad_16);
   }
   if (Debug_LiveTrade == TRUE) {
      Write_Trade("-----------------------------------------------------------------");
      Write_Trade(" " + Symbol() + " #" + li.period + " " + as_4);
      if (ad_16 > 0.1) Write_Prices(ai_12, ad_16);
   }
}

void Write_Trade(string ld.msg) {
   int l_file_8;
   if (Debug_LiveTrade == TRUE) {
      l_file_8 = FileOpen(g_name_244, FILE_CSV|FILE_WRITE|FILE_READ, "/t");
      FileSeek(l_file_8, 0, SEEK_END);
      FileWrite(l_file_8, TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS) + ld.msg);
      FileClose(l_file_8);
   }
}

void BTWrite_Trade(string ld.msg) {
   int l_global_var_8;
   if (Debug_BackTestTrade == TRUE) {
      if (GlobalVariableCheck("BTMyHandleTrade")) {
         l_global_var_8 = GlobalVariableGet("BTMyHandleTrade");
         FileWrite(l_global_var_8, TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS) + ld.msg);
      }
   }
}

void BTWrite_Prices(int ai_unused_0, double ad_unused_4) {
   if (Debug_BackTestTrade == TRUE) {
      BTWrite_Trade("  PRICES");
      BTWrite_Trade("  High Profit : " + DoubleToStr(gd.HighestEquityDiff, 0));
      BTWrite_Trade("  DrawDown : " + DoubleToStr(gd.LargestDrawDownEquity, 0));
   }
}

void Write_Prices(int ai_unused_0, double ad_unused_4) {
   if (Debug_LiveTrade == TRUE) {
      Write_Trade("  PRICES");
      Write_Trade("  High Profit : " + DoubleToStr(gd.HighestEquityDiff, 0));
      Write_Trade("  DrawDown    : " + DoubleToStr(gd.LargestDrawDownEquity, 0));
   }
}

void WriteTradeExit(string ld.msg, int ai_8, int ai_12, double ad_16, double ad_24) {
   string l_dbl2str_32 = DoubleToStr(ad_24, 2);
   string l_dbl2str_40 = DoubleToStr(Bid, Digits);
   string l_dbl2str_48 = DoubleToStr(Ask, Digits);
   if (ai_12 == 0) {
      WriteExit(ai_8, ld.msg, 0, ad_16);
      if (Debug_LiveTrade == TRUE) Write_Trade(" " + Symbol() + " #" + ai_8 + " CLOSE BUY ORDER " + l_dbl2str_32 + " LOTS AT " + l_dbl2str_40 + ".");
      if (Debug_BackTestTrade == TRUE) BTWrite_Trade(" " + Symbol() + " #" + ai_8 + " CLOSE BUY ORDER " + l_dbl2str_32 + " LOTS AT " + l_dbl2str_40 + ".");
   }
   if (ai_12 == 1) {
      WriteExit(ai_8, ld.msg, 1, ad_16);
      if (Debug_LiveTrade == TRUE) Write_Trade(" " + Symbol() + " #" + ai_8 + " CLOSE SELL ORDER " + l_dbl2str_32 + " LOTS AT " + l_dbl2str_48 + ".");
      if (Debug_BackTestTrade == TRUE) BTWrite_Trade(" " + Symbol() + " #" + ai_8 + " CLOSE SELL ORDER " + l_dbl2str_32 + " LOTS AT " + l_dbl2str_48 + ".");
   }
}