MQL5Book/Indicators/p6/SymbolTickSpy.mq5

129 lines
4.6 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:41 +02:00
//+------------------------------------------------------------------+
//| SymbolTickSpy.mq5 |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2022, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property description "Send custom events to specified chart upon receiving new ticks on symbols from a list. "
"Fill MqlTick structures with price/volume data on every tick.\n"
#property indicator_chart_window
#property indicator_plots 0
#define TICKSPY 0xFEED // 65261
input string SymbolList =
"EURUSD,GBPUSD,XAUUSD,USDJPY,USDCHF"; // List of symbols, comma separated (example)
input ushort Message = TICKSPY; // Custom message id
input long Chart = 0; // Receiving chart id (do not edit)
input int Index = 0; // Index in symbol list (do not edit)
string Symbols[];
int Spreads[];
int SelfIndex = -1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
PrintFormat("Starting for chart %lld, msg=0x%X [%s]", Chart, Message, SymbolList);
if(Chart == 0)
{
if(StringLen(SymbolList) > 0)
{
const int n = StringSplit(SymbolList, ',', Symbols);
ArrayResize(Spreads, n);
for(int i = 0; i < n; ++i)
{
if(Symbols[i] != _Symbol)
{
ResetLastError();
// run this indicator on different symbols with different settings,
// specifically we pass ChartID to get notifications back from other symbols
iCustom(Symbols[i], PERIOD_CURRENT, MQLInfoString(MQL_PROGRAM_NAME),
"", Message, ChartID(), i);
if(_LastError != 0)
{
PrintFormat("The symbol '%s' seems incorrect", Symbols[i]);
}
}
else
{
SelfIndex = i;
}
Spreads[i] = 0;
}
}
else
{
Print("SymbolList is empty: tracking current symbol only!");
Print("To monitor other symbols, fill in SymbolList, i.e. 'EURUSD,GBPUSD,XAUUSD,USDJPY'");
}
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int, const double &price[])
{
if(prev_calculated)
{
if(Chart > 0)
{
// send tick notification to requesting chart
EventChartCustom(Chart, Message, Index, 0, NULL);
}
else if(SelfIndex > -1)
{
OnSymbolTick(SelfIndex);
}
}
return rates_total;
}
//+------------------------------------------------------------------+
//| Chart event handler |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_CUSTOM + Message)
{
OnSymbolTick((int)lparam);
}
}
//+------------------------------------------------------------------+
//| Multisymbol tick custom event |
//+------------------------------------------------------------------+
void OnSymbolTick(const int index)
{
const string symbol = Symbols[index];
MqlTick tick;
if(SymbolInfoTick(symbol, tick))
{
Spreads[index] = (int)MathRound((tick.ask - tick.bid)
/ SymbolInfoDouble(symbol, SYMBOL_POINT));
string message = "";
for(int i = 0; i < ArraySize(Spreads); ++i)
{
message += Symbols[i] + "=" + (string)Spreads[i] + "\n";
}
Comment(message);
}
}
//+------------------------------------------------------------------+
//| Finalization handler |
//+------------------------------------------------------------------+
void OnDeinit(const int)
{
Comment("");
}
//+------------------------------------------------------------------+