i-SignalOfTrade

Download script
Author: ��� ����� �. aka KimIV
i-SignalOfTrade

This script functions as an automated monitoring and notification system for your trading activity. Instead of being a strategy that makes trades for you, it acts as a specialized "watchdog" that tracks every movement, change, or completion of your trade orders in real-time and alerts you accordingly.

Core Functionality

The logic is designed to identify four specific types of events within your trading account:

  • New Activity Detection: The script identifies when a new trade is opened (such as a Buy or Sell) or when a new pending order (like a Limit or Stop order) is placed. It immediately gathers the details—including the price, volume, stop-loss, and take-profit levels—and sends you a notification.
  • Pending Order Execution: A key feature of this logic is its ability to recognize when a pending order "triggers" into an active trade. It tracks these transitions specifically so you can see exactly when a limit or stop order was filled.
  • Modification Tracking: If you manually change the parameters of an existing trade—such as adjusting the Stop-Loss level, moving the Take-Profit target, or changing the opening price—the script detects this discrepancy against its internal memory and notifies you of the specific change (e.g., "SL moved from X to Y").
  • Closure and Deletion: The script monitors for the end of a trade's lifecycle. It alerts you when a position is closed (providing the final profit/loss figures) or when a pending order is deleted by the user or the system.

User Customization & Output Options

The script is highly configurable, allowing you to decide exactly what information is displayed and how you receive it:

  • Data Transparency: You can toggle specific data points on or off within the alerts, including your Account Number, Server name, Date/Time, Expert Name, Ticket numbers, Magic Numbers, and specific Trade Comments.
  • Notification Channels: The logic supports multiple ways to stay informed. Depending on your settings, it can trigger a pop-up alert window on your screen, play an audible sound file, write a comment directly onto your trading chart, send an email, or record the event in the platform's internal log.
  • Financial Context: For active trades (Buy/Sell), the system automatically includes your current Account Balance and Free Margin in the notifications, giving you a complete financial snapshot at the moment of the trade event.

How it Works Internally

The script maintains an internal "memory" of your trading environment. Every time it runs, it compares the current state of your open orders against its stored data. If it finds a difference—such as a new ticket appearing, a price changing, or an order disappearing—it generates a descriptive text string and pushes that information to your chosen notification channels instantly.

Orders Execution
Checks for the total of open orders
Miscellaneous
It plays sound alerts
10 Views
0 Downloads
0 Favorites
i-SignalOfTrade
//+----------------------------------------------------------------------------+
//|                                                       i-SignalOfTrade.mq4  |
//|                                                    Êèì Èãîðü Â. aka KimIV  |
//|                                                       http://www.kimiv.ru  |
//|                                                                            |
//|  05.12.2007  Ñèãíàëèçàòîð âûïîëíåíèÿ òîðãîâûõ îïåðàöèé.                    |
//|  13.05.2008  Ñèãíàëèçàöèÿ ñðàáàòûâàíèÿ îòëîæåííîãî îðäåðà.                 |
//|  29.12.2008  Èñïðàâëåíà îøèáêà ñèãíàëèçàöèè óäàëåíèÿ îðäåðà.               |
//+----------------------------------------------------------------------------+
#property copyright "Êèì Èãîðü Â. aka KimIV"
#property link      "http://www.kimiv.ru"
#property indicator_chart_window

//------- Âíåøíèå ïàðàìåòðû èíäèêàòîðà ----------------------------------------+
extern string _P_WhatOutput    = "---------- ×òî âûâîäèòü";
extern bool   OutAccountNumber = True;      // Âûâîäèòü íîìåð ñ÷¸òà
extern bool   OutAccountServer = True;      // Âûâîäèòü èìÿ àêòèâíîãî ñåðâåðà
extern bool   OutNameExpert    = True;      // Âûâîäèòü èìÿ ýêñïåðòà
extern bool   OutDateTime      = True;      // Âûâîäèòü äàòó è âðåìÿ
extern bool   UseTimeLocal     = True;      // Èñïîëüçîâàòü ëîêàëüíîå âðåìÿ
extern bool   OutTicket        = False;     // Âûâîäèòü òèêåò
extern bool   OutMagic         = True;      // Âûâîäèòü ìàãèê
extern bool   OutComment       = True;      // Âûâîäèòü êîììåíòàðèé
extern string _P_WhereOutput = "---------- Êóäà âûâîäèòü";
extern bool   UseAlert    = True;           // Èñïîëüçîâàòü äèàëîãîâîå îêíî
extern bool   UseComment  = True;           // Âûâîäèòü êîììåíòàðèé
extern bool   UsePrint    = False;          // Çàïèñûâàòü â æóðíàë
extern bool   UseSendMail = False;          // Èñïîëüçîâàòü ïåðåäà÷ó ñîîáùåíèé
extern bool   UseSound    = True;           // Èñïîëüçîâàòü çâóê
extern string sotFileName = "expert.wav";   // Íàèìåíîâàíèå çâóêîâîãî ôàéëà

//------- Ãëîáàëüíûå ïåðåìåííûå èíäèêàòîðà ------------------------------------+
int    sotOTI[];             // òèêåò   OrderTicket()
int    sotOTY[];             // òèï     OrderType()
double sotOOP[];             // öåíà    OrderOpenPrice()
double sotOSL[];             // ñòîï    OrderStopLoss()
double sotOTP[];             // òåéê    OrderTakeProfit()
bool   sotFirstRun=True;     // Ôëàã ïåðâîãî ïðîãîíà


//+----------------------------------------------------------------------------+
//|                                                                            |
//|  ÏÐÅÄÎÏÐÅÄÅ˨ÍÍÛÅ ÔÓÍÊÖÈÈ                                                  |
//|                                                                            |
//+----------------------------------------------------------------------------+
//|  Custom indicator initialization function                                  |
//+----------------------------------------------------------------------------+
void init() {
  sotFirstRun=True;     // Ôëàã ïåðâîãî ïðîãîíà
  Comment("");
}

//+----------------------------------------------------------------------------+
//|  Custom indicator deinitialization function                                |
//+----------------------------------------------------------------------------+
void deinit() { Comment(""); }

//+----------------------------------------------------------------------------+
//|  Custom indicator iteration function                                       |
//+----------------------------------------------------------------------------+
void start() {
  double p;                  // Ðàçìåð ïóíêòà â âàëþòå êîòèðîâêè
  int    d;                  // Êîëè÷åñòâî öèôð ïîñëå äåñÿòè÷íîé òî÷êè â öåíå
  int    i;                  // Ñ÷¸ò÷èê îïåðàöèé
  int    in;                 // Èíäåêñ ýëåìåíòà ìàññèâà îïåðàöèé
  int    k=OrdersTotal();    // Êîëè÷åñòâî òåêóùèõ îïåðàöèé
  int    ot;                 // Òèï îïåðàöèè OrderType()
  int    oti[];              // Ìàññèâ íîâûõ òèêåòîâ
  string sh="";              // Ñòðîêà çàãîëîâêà ïî÷òîâîãî ñîîáùåíèÿ
  string st;                 // Ñòðîêà òåëà ïî÷òîâîãî ñîîáùåíèÿ

  if (sotFirstRun) { MemCurrOP(); sotFirstRun=False; }
  if (OutAccountNumber) sh=DoubleToStr(AccountNumber(), 0)+" ";
  if (OutAccountServer) sh=sh+AccountServer();
  if (StringLen(sh)>0) sh=sh+"\n";
  if (OutDateTime) {
    if (UseTimeLocal) sh=sh+TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES)+" ";
    else sh=sh+TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS)+" ";
  }
  if (OutNameExpert) sh=sh+WindowExpertName()+" ";
  if (StringLen(sh)>0) sh=sh+"\n";
  
  // Îòêðûòèå/Óñòàíîâêà íîâûõ, ìîäèôèêàöèÿ ñóùåñòâóþùèõ
  ArrayResize(oti, k);
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      oti[i]=OrderTicket();
      d=MarketInfo(OrderSymbol(), MODE_DIGITS);
      p=MarketInfo(OrderSymbol(), MODE_POINT);
      in=ArraySearchInt(sotOTI, oti[i]);

      // îïåðàöèÿ ÍÅ íàéäåíà, çíà÷èò íîâàÿ
      if (in<0) {
        ot=OrderType();
        if (ot==OP_BUY || ot==OP_SELL) st="Open ";
        if (ot==OP_BUYLIMIT || ot==OP_BUYSTOP
        ||  ot==OP_SELLLIMIT || ot==OP_SELLSTOP) st="Set ";
        if (OutTicket) st=st+DoubleToStr(OrderTicket(), 0)+" ";
        st=st+GetNameOP(ot)+" "
             +DoubleToStr(OrderLots(), 2)+" "
             +OrderSymbol()
             +" PR="+DoubleToStr(OrderOpenPrice(), d)
             +" SL="+DoubleToStr(OrderStopLoss(), d)
             +" TP="+DoubleToStr(OrderTakeProfit(), d)
             +"\n"
             +IIFs(OutMagic, "Magic="+DoubleToStr(OrderMagicNumber(), 0), "")
             +IIFs(OutMagic && OutComment, " ", "")
             +IIFs(OutComment, "Comment=\""+OrderComment()+"\"", "")
             +IIFs(OutMagic || OutComment, "\n", "");
        if (ot==OP_BUY || ot==OP_SELL) {
          st=st+"Balance="+DoubleToStr(AccountBalance(), 2)
               +" FreeMargin="+DoubleToStr(AccountFreeMargin(), 2);
        }
        if (StringLen(sh)>0) st=sh+st;
        Signal(st);

      // îïåðàöèÿ íàéäåíà, çíà÷èò ñóùåñòâîâàëà ðàíåå è âîçìîæíî èçìåíåíà
      } else {
        // ñðàáàòûâàíèå îòëîæåííîãî îðäåðà
        ot=OrderType();
        if (ot!=sotOTY[in] && (ot==OP_BUY || ot==OP_SELL)) {
          st="Open ";
          if (OutTicket) st=st+DoubleToStr(OrderTicket(), 0)+" ";
          st=st+GetNameOP(ot)+" by "+GetNameOP(sotOTY[in])+" "
               +DoubleToStr(OrderLots(), 2)+" "
               +OrderSymbol()
               +" PR="+DoubleToStr(OrderOpenPrice(), d)
               +" SL="+DoubleToStr(OrderStopLoss(), d)
               +" TP="+DoubleToStr(OrderTakeProfit(), d)
               +"\n"
               +IIFs(OutMagic, "Magic="+DoubleToStr(OrderMagicNumber(), 0), "")
               +IIFs(OutMagic && OutComment, " ", "")
               +IIFs(OutComment, "Comment=\""+OrderComment()+"\"", "")
               +IIFs(OutMagic || OutComment, "\n", "");
          if (ot==OP_BUY || ot==OP_SELL) {
            st=st+"Balance="+DoubleToStr(AccountBalance(), 2)
                 +" FreeMargin="+DoubleToStr(AccountFreeMargin(), 2);
          }
          if (StringLen(sh)>0) st=sh+st;
          Signal(st);
        }
        // ìîäèôèêàöèÿ îðäåðà èëè ïîçèöèè
        if ((MathAbs(OrderOpenPrice()-sotOOP[in])>=p)
        ||  (MathAbs(OrderStopLoss()-sotOSL[in])>=p)
        ||  (MathAbs(OrderTakeProfit()-sotOTP[in])>=p)) {
          st="Modify ";
          if (OutTicket) st=st+DoubleToStr(OrderTicket(), 0)+" ";
          st=st+GetNameOP(OrderType())+" "
            +DoubleToStr(OrderLots(), 2)+" "
            +OrderSymbol();
          // èçìåíèëàñü öåíà îòêðûòèÿ
          if (MathAbs(OrderOpenPrice()-sotOOP[in])>=p) {
            st=st+" PR="+DoubleToStr(sotOOP[in], d)+"->"+DoubleToStr(OrderOpenPrice(), d);
          }
          // èçìåíèëñÿ óðîâåíü ñòîïà
          if (MathAbs(OrderStopLoss()-sotOSL[in])>=p) {
            st=st+" SL="+DoubleToStr(sotOSL[in], d)+"->"+DoubleToStr(OrderStopLoss(), d);
          }
          // èçìåíèëñÿ óðîâåíü òåéêà
          if (MathAbs(OrderTakeProfit()-sotOTP[in])>=p) {
            st=st+" TP="+DoubleToStr(sotOTP[in], d)+"->"+DoubleToStr(OrderTakeProfit(), d);
          }
          st=st+IIFs(OutMagic || OutComment, "\n", "")
               +IIFs(OutMagic, "Magic="+DoubleToStr(OrderMagicNumber(), 0), "")
               +IIFs(OutMagic && OutComment, " ", "")
               +IIFs(OutComment, "Comment=\""+OrderComment()+"\"", "")
               +IIFs(OutMagic || OutComment, "\n", "");
          if (StringLen(sh)>0) st=sh+st;
          Signal(st);
        }
      }
    }
  }

  // Çàêðûòèå ïîçèöèé / Óäàëåíèå îðäåðîâ
  k=ArraySize(sotOTI);
  for (i=0; i<k; i++) {
    if (ArraySearchInt(oti, sotOTI[i])<0) {
      ot=sotOTY[i];
      if (ot==OP_BUY || ot==OP_SELL) st="Close ";
      if (ot==OP_BUYLIMIT || ot==OP_BUYSTOP
      ||  ot==OP_SELLLIMIT || ot==OP_SELLSTOP) st="Delete ";
      if (OutTicket) st=st+DoubleToStr(sotOTI[i], 0)+" ";
      if (OrderSelect(sotOTI[i], SELECT_BY_TICKET)) {
        d=MarketInfo(OrderSymbol(), MODE_DIGITS);
        st=st+GetNameOP(ot)+" "
             +DoubleToStr(OrderLots(), 2)+" "
             +OrderSymbol()
             +" PR="+DoubleToStr(OrderClosePrice(), d)
             ;
        if (ot==OP_BUY || ot==OP_SELL) {
          st=st+" Profit="+DoubleToStr(OrderProfit()+OrderSwap(), 2)
               +"\n"
               +IIFs(OutMagic, "Magic="+DoubleToStr(OrderMagicNumber(), 0), "")
               +IIFs(OutMagic && OutComment, " ", "")
               +IIFs(OutComment, "Comment=\""+OrderComment()+"\"", "")
               +IIFs(OutMagic || OutComment, "\n", "")
               +"Balance="+DoubleToStr(AccountBalance(), 2)
               +" FreeMargin="+DoubleToStr(AccountFreeMargin(), 2);
        }
        if (StringLen(sh)>0) st=sh+st;
        Signal(st);
      }
    }
  }

  MemCurrOP();
}


//+----------------------------------------------------------------------------+
//|                                                                            |
//|  ÏÎËÜÇÎÂÀÒÅËÜÑÊÈÅ ÔÓÍÊÖÈÈ                                                  |
//|                                                                            |
//+----------------------------------------------------------------------------+
//|  Âûïîëíÿåò ïîèñê ýëåìåíòà ìàññèâà ïî çíà÷åíèþ                              |
//|  è âîçâðàùàåò èíäåêñ íàéäåííîãî ýëåìåíòà èëè -1                            |
//|  Ïàðàìåòðû:                                                                |
//|    m - ìàññèâ ýëåìåíòîâ                                                    |
//|    e - çíà÷åíèå ýëåìåíòà                                                   |
//+----------------------------------------------------------------------------+
int ArraySearchInt(int& m[], int e) {
  for (int i=0; i<ArraySize(m); i++) {
    if (m[i]==e) return(i);
  }
  return(-1);
}

//+----------------------------------------------------------------------------+
//|  Âîçâðàùàåò íàèìåíîâàíèå òîðãîâîé îïåðàöèè                                 |
//|  Ïàðàìåòðû:                                                                |
//|    op - èäåíòèôèêàòîð òîðãîâîé îïåðàöèè                                    |
//+----------------------------------------------------------------------------+
string GetNameOP(int op) {
	switch (op) {
		case OP_BUY      : return("Buy");
		case OP_SELL     : return("Sell");
		case OP_BUYLIMIT : return("BuyLimit");
		case OP_SELLLIMIT: return("SellLimit");
		case OP_BUYSTOP  : return("BuyStop");
		case OP_SELLSTOP : return("SellStop");
		default          : return("Unknown Operation");
	}
}

//+----------------------------------------------------------------------------+
//|  Âîçâðàùàåò îäíî èç äâóõ çíà÷åíèé âçàâèñèìîñòè îò óñëîâèÿ.                 |
//+----------------------------------------------------------------------------+
string IIFs(bool condition, string ifTrue, string ifFalse) {
  if (condition) return(ifTrue); else return(ifFalse);
}

//+----------------------------------------------------------------------------+
//|  Çàïîìèíàåò òåêóùèå îïåðàöèè â ìàññèâå.                                    |
//+----------------------------------------------------------------------------+
void MemCurrOP() {
  int i, k=OrdersTotal();

  ArrayResize(sotOTI, k);
  ArrayResize(sotOTY, k);
  ArrayResize(sotOOP, k);
  ArrayResize(sotOSL, k);
  ArrayResize(sotOTP, k);
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      sotOTI[i]=OrderTicket();
      sotOTY[i]=OrderType();
      sotOOP[i]=OrderOpenPrice();
      sotOSL[i]=OrderStopLoss();
      sotOTP[i]=OrderTakeProfit();
    }
  }
}

//+----------------------------------------------------------------------------+
//|  Ïîäà÷à ñèãíàëà.                                                           |
//|  Ïàðàìåòðû:                                                                |
//|    st - ñòðîêà ñîîáùåíèÿ                                                   |
//+----------------------------------------------------------------------------+
void Signal(string st) {
  if (UseAlert) Alert(st);
  if (UseComment) Comment(st);
  if (UseSendMail) SendMail(WindowExpertName(), st);
  if (UsePrint) Print(st);
  if (UseSound) PlaySound(sotFileName);
}
//+----------------------------------------------------------------------------+

Comments