orderblockdetector.mq5
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «orderblockdetector.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
OrderBlockDetector — это пользовательский индикатор для MetaTrader 5, предназначенный для обнаружения и визуализации ордер-блоков на графике цен. Индикатор определяет свечные пивоты (локальные максимумы и минимумы), отслеживает пробой структуры и выявляет последнюю противоположную свечу перед импульсным движением, которое нарушает рыночную структуру.
Обнаруженные ордер-блоки отображаются в виде прямоугольных зон на графике. Зоны могут продлеваться в реальном времени до тех пор, пока цена не вернётся и не митигирует их. Индикатор поддерживает настройку цветов, стилей отрисовки, заливки и отображения меток с ценами зон.
Индикатор работает на закрытых барах для стабильности расчётов. Количество одновременно отслеживаемых ордер-блоков ограничивается настраиваемым параметром — при превышении лимита самые старые блоки удаляются. Доступны параметры минимального размера зоны, минимального процента тела свечи для импульса и расстояния пробоя уровня.
Настройки программы
| Настройка | Описание |
|---|---|
| InpSwingLookback | Количество баров с каждой стороны для подтверждения свечного пивота |
| InpMinBreakPoints | Минимальное расстояние пробоя за уровнем пивота (в очках) |
| InpMinImpulseBodyPercent | Минимальный процент тела свечи от её диапазона для признания импульсной |
| InpMaxSearchBarsForOB | Максимальное количество баров для поиска свечи ордер-блока назад от точки пробоя |
| InpUseBodyOnly | Использовать только тело свечи для определения границ зоны, вместо полного диапазона с тенями |
| InpMinZoneSizePoints | Минимальный размер зоны для отрисовки (в очках) |
| InpMaxOBsToTrack | Максимальное количество ордер-блоков, сохраняемых на графике (самые старые удаляются первыми) |
| InpExtendUntilMitigated | Продлевать прямоугольник зоны в реальном времени до момента, пока цена не митигирует ордер-блок |
| InpExtendBars | Фиксированное продление зоны (в барах), используется только если не включено продление до митигации |
| InpRequireFullCloseForMitigation | Требовать полное закрытие свечи внутри зоны для митигации, а не просто касание |
| InpHideMitigatedOBs | Удалять прямоугольник ордер-блока после его митигации вместо изменения цвета |
| InpBullishOBColor | Цвет бычьего ордер-блока |
| InpBearishOBColor | Цвет медвежьего ордер-блока |
| InpMitigatedColor | Цвет прямоугольника ордер-блока после его митигации |
| InpFillBox | Заливать прямоугольник ордер-блока |
| InpBoxStyle | Стиль границы прямоугольника ордер-блока |
| InpBoxWidth | Толщина границы прямоугольника ордер-блока |
| InpShowLabels | Отображать метку с ценой зоны ордер-блока |
Поиск по коду файла
#property version "1.00"
#property description "Detects order blocks — the last opposing candle before an impulsive move "
#property description "that breaks market structure — and draws them as zones that extend live "
#property description "until price returns and mitigates them."
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
#property strict
input group "=== Structure Detection ==="
input int InpSwingLookback = 5; // Swing Lookback (bars on each side to confirm a pivot)
input int InpMinBreakPoints = 30; // Minimum Break Distance Beyond Swing Level (points)
input double InpMinImpulseBodyPercent = 50.0; // Minimum Body-to-Range % for a Valid Impulse Candle
input int InpMaxSearchBarsForOB = 10; // Max Bars Searched Back for the Order-Block Candle
input group "=== Order Block Zone ==="
input bool InpUseBodyOnly = false; // Use Candle Body Only (instead of full wick range)
input int InpMinZoneSizePoints = 30; // Minimum Zone Size to Draw (points)
input int InpMaxOBsToTrack = 30; // Maximum Order Blocks Kept on Chart (oldest removed first)
input group "=== Mitigation Behavior ==="
input bool InpExtendUntilMitigated = true; // Extend Box Live Until Price Mitigates It
input int InpExtendBars = 40; // Fixed Extension (bars) — used only if not extending until mitigated
input bool InpRequireFullCloseForMitigation = false; // Require a Close Through the Zone (not just a touch)
input bool InpHideMitigatedOBs = false; // Delete a Block's Box Once Mitigated (instead of graying it out)
input group "=== Colors & Style ==="
input color InpBullishOBColor = clrLime; // Bullish Order Block Color
input color InpBearishOBColor = clrRed; // Bearish Order Block Color
input color InpMitigatedColor = clrDimGray; // Color Once a Block Has Been Mitigated
input bool InpFillBox = true; // Fill the Order Block Box
input ENUM_LINE_STYLE InpBoxStyle = STYLE_SOLID; // Box Border Style
input int InpBoxWidth = 1; // Box Border Width
input bool InpShowLabels = true; // Show a Label With the Zone Price
string g_Prefix = "OB_";
int g_ObFormIndex[]; // bar index of the order-block candle itself
double g_ObTop[];
double g_ObBottom[];
bool g_ObBullish[];
bool g_ObMitigated[];
string g_ObName[];
int g_ObCount = 0;
double g_PendingHighPrice = 0.0;
int g_PendingHighIndex = -1;
bool g_PendingHighValid = false;
double g_PendingLowPrice = 0.0;
int g_PendingLowIndex = -1;
bool g_PendingLowValid = false;
int g_LastConfirmedPivotIndex = -1; // last bar index already checked for a new swing pivot
int g_LastProcessedIndex = -1; // last closed bar index already checked for breaks/mitigation
int OnInit()
{
// код доступен только после оплаты
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, g_Prefix);
ChartRedraw(0);
}
void ResetState()
{
ObjectsDeleteAll(0, g_Prefix);
g_ObCount = 0;
ArrayResize(g_ObFormIndex, 0);
ArrayResize(g_ObTop, 0);
ArrayResize(g_ObBottom, 0);
ArrayResize(g_ObBullish, 0);
ArrayResize(g_ObMitigated, 0);
ArrayResize(g_ObName, 0);
g_PendingHighValid = false;
g_PendingLowValid = false;
g_LastConfirmedPivotIndex = InpSwingLookback - 1;
g_LastProcessedIndex = -1;
}
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[])
{
// код доступен только после оплаты
}
if(rates_total < 2 * InpSwingLookback + 3)
return(0);
if(prev_calculated == 0)
ResetState();
int confirmIndex = rates_total - 1 - InpSwingLookback;
for(int i = g_LastConfirmedPivotIndex + 1; i <= confirmIndex; i++)
{
if(i - InpSwingLookback < 0)
continue;
if(IsSwingHigh(i, high))
{
g_PendingHighPrice = high[i];
g_PendingHighIndex = i;
g_PendingHighValid = true;
}
if(IsSwingLow(i, low))
{
g_PendingLowPrice = low[i];
g_PendingLowIndex = i;
g_PendingLowValid = true;
}
}
if(confirmIndex > g_LastConfirmedPivotIndex)
g_LastConfirmedPivotIndex = confirmIndex;
int lastClosedIndex = rates_total - 2;
for(int j = g_LastProcessedIndex + 1; j <= lastClosedIndex; j++)
{
for(int L = 0; L < g_ObCount; L++)
{
if(g_ObMitigated[L])
continue;
if(g_ObFormIndex[L] >= j)
continue; // the block must already exist before the bar being checked
CheckMitigation(L, j, time, high, low, close);
}
if(g_PendingHighValid && (close[j] - g_PendingHighPrice) >= InpMinBreakPoints * _Point)
{
if(BodyPercent(j, open, high, low, close) >= InpMinImpulseBodyPercent)
{
int searchFloor = MathMax(g_PendingHighIndex, j - InpMaxSearchBarsForOB);
int obIdx = FindLastDownCandle(j, searchFloor, open, close);
if(obIdx != -1)
TryAddOrderBlock(obIdx, j, time, open, high, low, close, true);
}
g_PendingHighValid = false; // the level is broken either way — consumed
}
if(g_PendingLowValid && (g_PendingLowPrice - close[j]) >= InpMinBreakPoints * _Point)
{
if(BodyPercent(j, open, high, low, close) >= InpMinImpulseBodyPercenПоказано первые 50% кода (символов: 9448)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.