Visual Orders

Author: Dmitry Yakovlev, Russia,Omsk, WM R865705290089
Visual Orders

Overview of Functional Logic

This script is designed as a visual tool for MetaTrader 4 to enhance the user experience by providing real-time data visualization directly on the trading chart. Rather than acting as an automated trading robot, it functions as a comprehensive dashboard that tracks active trades, historical performance, and account statistics.

Core Functionalities

1. Real-Time Account Dashboard

The script automatically generates a live information display on the upper portion of your chart. This includes:

  • Dynamic Time & Market Data: It displays the current server time alongside the account leverage and the current market spread.
  • Equity Tracking: It monitors and displays your current account equity.
  • Profit Analysis: The script calculates your total profit, separating "positive" (winning) and "negative" (losing) components. This is displayed using dynamic color coding (e.g., Blue for profits, Crimson for losses, and Yellow for neutral positions) so you can instantly gauge your performance.
  • Customizable Display Modes: Users can choose how this profit information is positioned—either floating near the current price or fixed at a specific distance above the chart.

2. Trade Visualization (Active and Historical)

One of the primary features of this script is its ability to "draw" your trades onto the chart. It transforms abstract numbers into visual geometry:

  • Trade Lines: For every active trade or past historical order, the script draws a trend line connecting the entry point to the current price (or the closing price).
  • Entry and Exit Markers: It places specific arrow symbols at the exact moments of entry and exit. This allows you to see exactly where your trades started and ended relative to price action.
  • Visual Distinction: The script uses different colors and styles to differentiate between Buy (typically Blue) and Sell (typically Red) positions, and applies distinct colors based on whether a trade is currently in profit or loss.
  • Toggleable Views: You can choose to see only your current "Live" trades, only your "History," or both simultaneously.

3. Automated Cleanup

To ensure the trading chart remains clean and performant, the script includes an automated management system. Every time the price updates or the window refreshes, it identifies old visual objects (lines and arrows) from previous calculations and removes them. This prevents the chart from becoming cluttered with "ghost" lines and ensures that only the most relevant data is visible at any given moment.

Summary for the User

In short, this script turns your trading terminal into a more informative workspace. It takes the technical data of your account—profits, losses, entry prices, and history—and paints them directly onto your candles. This allows you to see the "story" of your trading activity visually, making it much easier to analyze your strategy without having to constantly check separate tabs or menus.

Orders Execution
Checks for the total of open ordersChecks for the total of closed orders
16 Views
2 Downloads
0 Favorites
Visual Orders
//
//  VisualOrders.mq4 
//  Dmitry Yakovlev 
//  dmitry_yakovlev@rambler.ru
//  Íà ïèâî WebMoney R865705290089
//------------------------------------------------------------------
#property copyright "Dmitry Yakovlev, Russia,Omsk, WM R865705290089"
#property link      "dmitry_yakovlev@rambler.ru"

#property indicator_chart_window

extern string  _ModeProf="Profit 1-close to price,2-above chart";
extern int     ModeProf=2;
extern string  _orders="Show deals on the chart:";
extern bool    CurOrders=true;
extern bool    HistOrders=true;
extern int     lblSize=1;
extern string    _donate1="For beer :-) WebMoney";
extern string    _donate2="R865705290089";

double prev_profit=0, cur_prof5=0, prev_prof5=0;
int wh=0;
int init()
{
   string tmp,prefix;
   int i,total;
   if(lblSize<1) lblSize=1;
   if(lblSize>4) lblSize=4;

   prefix="time_order_trades_";total=OrdersTotal();
   for(i=0;i<total+5;i++)
   {
      tmp=prefix+DoubleToStr(i,0);
      ObjectDelete(tmp);
      ObjectDelete(tmp+"O");
      ObjectDelete(tmp+"C");
      ObjectDelete(tmp+"OA");
      ObjectDelete(tmp+"CA");
   }
   prefix="time_order_hist_";total=OrdersHistoryTotal();
   for(i=0;i<total+5;i++)
   {
      tmp=prefix+DoubleToStr(i,0);
      ObjectDelete(tmp);
      ObjectDelete(tmp+"O");
      ObjectDelete(tmp+"C");
      ObjectDelete(tmp+"OA");
      ObjectDelete(tmp+"CA");
   }
   
    ObjectCreate("curtime", OBJ_LABEL,0,0,0);
    ObjectSet("curtime", OBJPROP_CORNER,0);
    ObjectSet("curtime", OBJPROP_XDISTANCE,250);
    ObjectSet("curtime", OBJPROP_YDISTANCE,0);

    if(ModeProf==1)
    {
      ObjectCreate("profit2", OBJ_TEXT,0,0,0);
      ObjectCreate("Account", OBJ_TEXT,0,0,0);
    }
    else if(ModeProf==2)
    {
      ObjectCreate("Account", OBJ_LABEL,0,0,0);
      ObjectSet("Account", OBJPROP_CORNER,0);
      ObjectSet("Account", OBJPROP_XDISTANCE,250);
      ObjectSet("Account", OBJPROP_YDISTANCE,20);

      ObjectCreate("profit2", OBJ_LABEL,0,0,0);
      ObjectSet("profit2", OBJPROP_CORNER,0);
      ObjectSet("profit2", OBJPROP_XDISTANCE,320);
      ObjectSet("profit2", OBJPROP_YDISTANCE,20);
    }
}
int deinit()
{
   string tmp,prefix;
   int i,total;

   prefix="time_order_trades_";total=OrdersTotal();
   for(i=0;i<total+5;i++)
   {
      tmp=prefix+DoubleToStr(i,0);
      ObjectDelete(tmp);
      ObjectDelete(tmp+"O");
      ObjectDelete(tmp+"C");
      ObjectDelete(tmp+"OA");
      ObjectDelete(tmp+"CA");
   }
   prefix="time_order_hist_";total=OrdersHistoryTotal();
   for(i=0;i<total+5;i++)
   {
      tmp=prefix+DoubleToStr(i,0);
      ObjectDelete(tmp);
      ObjectDelete(tmp+"O");
      ObjectDelete(tmp+"C");
      ObjectDelete(tmp+"OA");
      ObjectDelete(tmp+"CA");
   }

   ObjectDelete("curtime");   
   ObjectDelete("profit");
   ObjectDelete("profit2");
   ObjectDelete("Account");

   ObjectDelete("time_TP");
   ObjectDelete("time_SL");
   ObjectDelete("time_mar");
   ObjectDelete("time_per");
   ObjectDelete("time_lot");
   ObjectDelete("time_lot100");
   ObjectDelete("time_vv1");
   ObjectDelete("time_vv2");
   ObjectDelete("time_sr1");
   ObjectDelete("time_sr2");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
double Trunc(double v=0)
{
   return(StrToDouble(DoubleToStr(v,0)));
}

double TakeProfit=0, StopLoss=0;
int start()
{
   datetime t1,t2,t3,t4;
   double TickValue=MarketInfo(Symbol(), MODE_TICKVALUE);
   int spread=MarketInfo(Symbol(), MODE_SPREAD);
   
   ObjectSetText("curtime", TimeToStr(TimeCurrent(),TIME_SECONDS)+" Ïëå÷î:"+DoubleToStr(AccountLeverage(),0)+" Ñïðýä:"+DoubleToStr(spread,0), 12, "Arial", Gainsboro);
	int i;
   double sell_profit=0, buy_profit=0, tot_profit=0, 
          sell_points=0, buy_points=0, tot_points=0, prev_points=0, 
          plus_profit=0, minus_profit=0;
   for(i=0;i<OrdersTotal();i++)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
   {
      if(OrderSymbol()==Symbol() && OrderType()==OP_SELL) { sell_profit+=OrderProfit(); sell_points+=Ask-OrderOpenPrice();}
      if(OrderSymbol()==Symbol() && OrderType()==OP_BUY) { buy_profit+=OrderProfit(); buy_points+=Bid-OrderOpenPrice();}
      
      if(OrderSymbol()==Symbol() ) 
         if(OrderProfit()>0) 
            plus_profit+=OrderProfit();
         else
            minus_profit+=OrderProfit();
   }
   tot_profit=sell_profit+buy_profit;
   tot_points=buy_points-sell_points;
   cur_prof5=Trunc(tot_points/5)*5;
   prev_prof5=Trunc(prev_points/5)*5;

   ObjectSetText("Account", DoubleToStr(AccountEquity(),2), 12, "Arial", Gainsboro);

   //if(tot_profit>0) ObjectSetText("profit2", DoubleToStr(plus_profit,2)+"+"+DoubleToStr(minus_profit,2)+"=+"+DoubleToStr(tot_profit,2)+" (+"+DoubleToStr(tot_points/Point,0)+")", 12, "Arial", Lime);
   //else if(tot_profit<0) ObjectSetText("profit2", DoubleToStr(plus_profit,2)+""+DoubleToStr(minus_profit,2)+"="+DoubleToStr(tot_profit,2)+" ("+DoubleToStr(tot_points/Point,0)+")", 12, "Arial", OrangeRed);
   //else if(tot_profit==0) ObjectSetText("profit2","0", 12, "Arial", Yellow);
   if(tot_profit>0) ObjectSetText("profit2", DoubleToStr(plus_profit,2)+"+"+DoubleToStr(minus_profit,2)+"=+"+DoubleToStr(tot_profit,2), 8, "Arial", Blue);
   else if(tot_profit<0) ObjectSetText("profit2", DoubleToStr(plus_profit,2)+""+DoubleToStr(minus_profit,2)+"="+DoubleToStr(tot_profit,2), 8, "Arial", Crimson);
   else if(tot_profit==0) ObjectSetText("profit2","0", 12, "Arial", Yellow);
   
   if(ModeProf==1)
   {
      ObjectSet("profit2", OBJPROP_TIME1, Time[0]+Period()*60*2);
      ObjectSet("Account", OBJPROP_TIME1, Time[0]+Period()*60*2);
      double hh=High[iHighest(NULL,0,MODE_HIGH,5,0)], ll=Low[iLowest(NULL,0,MODE_LOW,3,0)];
      ObjectSet("profit2", OBJPROP_PRICE1, hh+Point*9);
      ObjectSet("Account", OBJPROP_PRICE1, hh+Point*6);
   }
   
   prev_profit=tot_profit;
   prev_points=tot_points;
   
   
   // <---orders
      if(HistOrders==true) ShowOrders(MODE_HISTORY);
      if(CurOrders==true) ShowOrders(MODE_TRADES);
   // --- orders >
   
}


//+------------------------------------------------------------------+
double CalcLot(int lp=25,int sl=100)
{
   double lots;

   double mm=0.01;
   /*if(mini_forex==0)
   {
      lots=NormalizeDouble(AccountFreeMargin()*LotsPercent/100/1000,1);
      if(StopOgr==1)
      {
         mm=((AccountFreeMargin()*LotsPercent/100)/(0.1*StopLoss)*0.01);
         if(mm<lots) lots=NormalizeDouble(mm,1);
      }
      if(lots<0.1) lots=0.1;
   }
   if(mini_forex==1)
   {*/
      lots=NormalizeDouble(AccountFreeMargin()*lp/100/1000,2);
      mm=((AccountFreeMargin()*lp/100)/(0.1*sl)*0.01);
      if(mm<lots) lots=NormalizeDouble(mm,2);
      if(lots<0.01) lots=0;//0.01;
   //}

   return(lots);
}

void ShowOrders(int mode=MODE_TRADES)
{
   int i=0; string tmp=""; color clr2=0,clr1=Blue; string prefix="time_order_trades_"; int total=0;
   double CT, CP;
   
   if(mode==MODE_TRADES) {prefix="time_order_trades_";total=OrdersTotal();}
   if(mode==MODE_HISTORY) {prefix="time_order_hist_";total=OrdersHistoryTotal();}
   
   //<--- òîðãóåìûå îðäåðà
   // óäàëÿåì ñòàðûå ëèíèè
   for(i=0;i<total+5;i++)
   {
      tmp=prefix+DoubleToStr(i,0);
      ObjectDelete(tmp);
      ObjectDelete(tmp+"O");
      ObjectDelete(tmp+"C");
      ObjectDelete(tmp+"OA");
      ObjectDelete(tmp+"CA");
   }
   // äîáàâëÿåì íîâûå
   for(i=0;i<total;i++)
   {
      if(OrderSelect(i,SELECT_BY_POS,mode)==true)
      {
         if(OrderSymbol()==Symbol() && (OrderType()==OP_BUY || OrderType()==OP_SELL))
         {
            tmp=prefix+DoubleToStr(i,0);
            clr2=White; if(OrderProfit()>=0) clr2=Blue; else clr2=Red;
            if(OrderType()==OP_BUY) {CP=Bid;clr1=Blue;}
            if(OrderType()==OP_SELL) {CP=Ask;clr1=Red;}
            if(mode==MODE_TRADES)  {CT=Time[0];}
            if(mode==MODE_HISTORY) {CT=OrderCloseTime();CP=OrderClosePrice();}
            
            ObjectCreate(tmp, OBJ_TREND, 0, OrderOpenTime(), OrderOpenPrice(), CT, CP);
            ObjectSet(tmp, OBJPROP_COLOR, clr2);
            ObjectSet(tmp, OBJPROP_RAY, 0);
            ObjectSet(tmp, OBJPROP_WIDTH,1);
            ObjectSet(tmp, OBJPROP_STYLE, STYLE_DASHDOTDOT);
            
            ObjectCreate(tmp+"OA", OBJ_ARROW, 0, OrderOpenTime()-Period()*60, OrderOpenPrice());
            ObjectSet(tmp+"OA", OBJPROP_COLOR, clr1);
            ObjectSet(tmp+"OA", OBJPROP_ARROWCODE, 1);
            if(mode==MODE_TRADES) 
            {
               ObjectCreate(tmp+"O", OBJ_ARROW, 0, OrderOpenTime()-Period()*60, OrderOpenPrice());
               ObjectSet(tmp+"O", OBJPROP_COLOR, clr1);
               ObjectSet(tmp+"O", OBJPROP_WIDTH, lblSize);
               ObjectSet(tmp+"O", OBJPROP_ARROWCODE, 5);
            }

            ObjectCreate(tmp+"CA", OBJ_ARROW, 0, CT+Period()*60, CP);
            ObjectSet(tmp+"CA", OBJPROP_COLOR, clr2);
            ObjectSet(tmp+"CA", OBJPROP_ARROWCODE, 3);
            if(mode==MODE_TRADES) 
            {
               
               ObjectCreate(tmp+"C", OBJ_ARROW, 0, CT+Period()*60, CP);
               ObjectSet(tmp+"C", OBJPROP_COLOR, clr2);
               ObjectSet(tmp+"C", OBJPROP_WIDTH, lblSize);
               ObjectSet(tmp+"C", OBJPROP_ARROWCODE, 6);
               
               //ObjectCreate(tmp+"C", OBJ_TEXT, 0, CT+(Period()*5)*60, CP+2.5*Point);
               //ObjectSetText(tmp+"C", DoubleToStr(CP,Digits), 10+lblSize, "Arial Bold", clr2);
            }
         }
      }
   }
   //---òîðãóåìûå îðäåðà>
}

int Trend(int i=0, int ExPeriod=24)
{
   double negative = 0;
   double positive = 0;
   int k = i + ExPeriod;
   while(k > i)
   {
      if(Open[k] < Close[k])
         positive += (Close[k] - Open[k]);
      if(Open[k] > Close[k]) 
         negative += (Open[k] - Close[k]);
      k--;
   }
   if(positive > negative) 
       return(+1);
   if(positive < negative) 
       return(-1);
   if(positive == negative) 
       return(0);
}

Comments