forked from rosh/MQL5Book
152 lines
4.8 KiB
MQL5
152 lines
4.8 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| SyncBarsBySpy.mq5 |
| |
//| Copyright (c) 2022, MetaQuotes Ltd. |
| |
//| https://www.mql5.com |
| |
//| NB: Visual and nonvisual modes produce different results! |
| |
//+------------------------------------------------------------------+
| |
#include "..\..\Include\TickModel.mqh"
| |
| |
input string OtherSymbol = "USDJPY";
| |
| |
#define TICKSPY 0xFEED // 65261
| |
| |
const int Message = TICKSPY;
| |
int handle;
| |
| |
//+------------------------------------------------------------------+
| |
//| Expert initialization function |
| |
//+------------------------------------------------------------------+
| |
int OnInit()
| |
{
| |
if(_Symbol == OtherSymbol)
| |
{
| |
Alert("Please specify a symbol other than the work symbol of the chart!");
| |
return INIT_PARAMETERS_INCORRECT;
| |
}
| |
if(!SymbolSelect(OtherSymbol, true))
| |
{
| |
Alert("Wrong other symbol: ", OtherSymbol);
| |
return INIT_PARAMETERS_INCORRECT;
| |
}
| |
// run this indicator to report us every tick on OtherSymbol via chart events
| |
handle = iCustom(OtherSymbol, _Period, "MQL5Book/p5/EventTickSpy",
| |
"", Message, ChartID());
| |
return handle != INVALID_HANDLE ? INIT_SUCCEEDED : INIT_FAILED;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Finalization handler |
| |
//+------------------------------------------------------------------+
| |
void OnDeinit(const int)
| |
{
| |
IndicatorRelease(handle);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Helper class to collect bar timing statistics |
| |
//+------------------------------------------------------------------+
| |
class BarTimeStatistics
| |
{
| |
public:
| |
int total;
| |
int late;
| |
| |
BarTimeStatistics(): total(0), late(0) { }
| |
| |
~BarTimeStatistics()
| |
{
| |
PrintFormat("%d bars on %s was late among %d total bars on %s (%2.1f%%)",
| |
late, OtherSymbol, total, _Symbol, late * 100.0 / total);
| |
}
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| Chart event handler |
| |
//+------------------------------------------------------------------+
| |
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
| |
{
| |
if(id == CHARTEVENT_CUSTOM + Message)
| |
{
| |
OnSymbolTick(sparam);
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Custom multisymbol tick event handler |
| |
//+------------------------------------------------------------------+
| |
void OnSymbolTick(const string symbol)
| |
{
| |
// timestamp of this _Symbol latest known bar
| |
static datetime lastBarTime = 0;
| |
static bool synchonized = false;
| |
static BarTimeStatistics stats;
| |
| |
const datetime currentTime = iTime(_Symbol, _Period, 0);
| |
| |
if(symbol == _Symbol)
| |
{
| |
// if not initialize yet or bar changes
| |
if(lastBarTime != currentTime)
| |
{
| |
stats.total++;
| |
lastBarTime = currentTime;
| |
PrintFormat("Last bar on %s is %s", _Symbol, TimeToString(lastBarTime));
| |
synchonized = false;
| |
}
| |
}
| |
| |
static bool late = false;
| |
| |
// wait until bar times are equal on both symbols
| |
if(currentTime != iTime(OtherSymbol, _Period, 0))
| |
{
| |
if(symbol == OtherSymbol)
| |
{
| |
late = true;
| |
Print(OtherSymbol, " bar delayed...");
| |
}
| |
return; // wait for next tick or chart event
| |
}
| |
| |
if(late)
| |
{
| |
stats.late++;
| |
late = false;
| |
}
| |
| |
// we are here after sync is done
| |
| |
if(!synchonized)
| |
{
| |
// use TimeTradeServer() because TimeCurrent() doesn't change without ticks
| |
Print("Bars are in sync at ", TimeToString(TimeTradeServer(), TIME_DATE | TIME_SECONDS));
| |
// prevent the message output until next unsynced state
| |
synchonized = true;
| |
}
| |
| |
// here do your synced job
| |
// ...
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Expert tick function |
| |
//+------------------------------------------------------------------+
| |
void OnTick()
| |
{
| |
if(MQLInfoInteger(MQL_TESTER))
| |
{
| |
const TICK_MODEL model = getTickModel();
| |
if(model != TICK_MODEL_OPEN_PRICES)
| |
{
| |
static bool shownOnce = false;
| |
if(!shownOnce)
| |
{
| |
Print("This EA is intended to run in \"Open Prices\" mode");
| |
shownOnce = true;
| |
}
| |
}
| |
}
| |
| |
OnSymbolTick(_Symbol);
| |
}
| |
//+------------------------------------------------------------------+
|