i-SignalOfTrade
Download scriptThis 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.
//+----------------------------------------------------------------------------+
//| 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