Исходный код
Для реализации алгоритма мы будем использовать функцию CopyTicks с флагом COPY_TICKS_TRADE. Это гарантирует, что мы анализируем только реальные сделки (принты ленты Time & Sales), исключая обычные изменения спрэда. Если вы работаете с синтетическими инструментами, вам может быть полезна статья про Импорт котировок криптовалют из CSV в MT5: Создание Custom Symbol.
//+------------------------------------------------------------------+
//| MicroImbalance.mq5 |
//| Finfluct |
//| https://finfluct.com |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_plots 0
input int InpTicksToAnalyze = 500; // Кол-во принтов для анализа
input double InpImbalanceThreshold = 0.3; // Порог имбаланса (0.0 - 1.0)
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
Comment("");
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
MqlTick ticks[];
int copied = CopyTicks(_Symbol, ticks, COPY_TICKS_TRADE, 0, InpTicksToAnalyze);
if(copied <= 0)
{
Comment("Ожидание тиковых данных...");
return(rates_total);
}
double buy_volume = 0.0;
double sell_volume = 0.0;
for(int i = 0; i < copied; i++)
{
if((ticks[i].flags & TICK_FLAG_BUY) == TICK_FLAG_BUY)
{
buy_volume += (double)ticks[i].volume;
}
else if((ticks[i].flags & TICK_FLAG_SELL) == TICK_FLAG_SELL)
{
sell_volume += (double)ticks[i].volume;
}
}
double total_volume = buy_volume + sell_volume;
double imbalance = 0.0;
if(total_volume > 0)
{
imbalance = (buy_volume - sell_volume) / total_volume;
}
string comment_str = "=== MICROSTRUCTURE IMBALANCE ===\n";
comment_str += "Анализируемое окно принтов: " + IntegerToString(copied) + "\n";
comment_str += "Объем покупок (Ask): " + DoubleToString(buy_volume, 2) + "\n";
comment_str += "Объем продаж (Bid): " + DoubleToString(sell_volume, 2) + "\n";
comment_str += "Текущий имбаланс: " + DoubleToString(imbalance * 100.0, 2) + "%\n";
if(MathAbs(imbalance) >= InpImbalanceThreshold)
{
comment_str += "СТАТУС: АКТИВНЫЙ ИМБАЛАНС (";
if(imbalance > 0) comment_str += "ПОКУПАТЕЛИ)";
else comment_str += "ПРОДАВЦЫ)";
}
else
{
comment_str += "СТАТУС: БАЛАНС СИЛ";
}
Comment(comment_str);
return(rates_total);
} Разбор параметров
InpTicksToAnalyze: Количество последних торговых тиков (принтов) из ленты сделок, которые будут использоваться для расчета имбаланса.InpImbalanceThreshold: Пороговое значение дисбаланса (от 0.0 до 1.0). Например, значение 0.3 означает, что перевес одной из сторон должен составить более 30% от общего объема, чтобы зафиксировать имбаланс.
Как запустить
Для запуска индикатора выполните следующие шаги:
1. Откройте MetaEditor в MT5 (клавиша F4).
2. Создайте новый пользовательский индикатор (Файл -> Новый -> Пользовательский индикатор) и назовите его, например, MicroImbalance.
3. Полностью замените сгенерированный код на представленный выше исходный код и нажмите кнопку ‘Компилировать’.
4. Перетащите индикатор из навигатора MT5 на график нужного инструмента. Обратите внимание, что для точного анализа микроструктуры требуются реальные тиковые данные, поэтому лучше использовать счета с рыночным исполнением (Market Execution) на ликвидных инструментах (фьючерсы, акции или популярные валютные пары).
Если вы хотите расширить функционал и добавить визуальные уровни поддержки/сопротивления на основе зон имбаланса, рекомендуем изучить механизм интерактивного взаимодействия в статье MQL5 Drag-and-Drop: Перетаскивание торговых уровней на графике.
Для глубокого количественного анализа и оценки того, как локальные микроструктурные изменения коррелируют с глобальными макро-показателями страха и волатильности, ознакомьтесь с материалом Расчет корреляции VIX и валют в MT5: Custom Symbol.




