clusterbox_nulldayhistogramm_ad.mq5
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «clusterbox_nulldayhistogramm_ad.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор отображает кластеры тиков в виде гистограммы на графике MetaTrader 5. Он собирает данные о тиках (цена bid/ask, время) в течение торговой сессии и группирует их по ценовым уровням в пределах каждого дня. Количество тиков на каждом ценовом уровне определяет длину соответствующего столбца гистограммы.
Для сохранения данных между сессиями индикатор использует бинарные файлы тиковой истории. Объекты гистограммы отрисовываются на графике в виде трендовых линий. Доступна настройка цвета столбцов и количества отображаемых баров.
Индикатор работает на таймфреймах ниже ежедневного (D1). На таймфреймах D1 и выше он выводит уведомление о неработоспособности и не отображает данные.
Настройки программы
| Настройка | Описание |
|---|---|
| i_levelColor | Цвет гистограммы кластеров тиков. |
| i_indBarsCount | Количество баров для отображения гистограммы кластеров тиков. |
Поиск по коду файла
#property description "Отображение тиковых объемов по дням в виде гистограммы кластеров с шагом 1 пункт.\nОписание доступно на сайте AdvanceTools.net в разделе \"Тиковые объемы.\""
#property strict
#property indicator_chart_window
#property indicator_buffers 1
struct TickStruct // Структура для записи данных об одном тике
{
datetime time;
double bid;
double ask;
};
#define MAX_POINTS_DAY_HEIGHT 20000 // Максимальная высота дня в пунктах - размер массива для хранения количества повторов уровней
input color i_levelColor = clrGray; // Цвет гистограммы объемов
input int i_indBarsCount = 10000; // Количество баров для отображения
bool g_activate; // Признак успешной инициализации индикатора
int g_levelRepeat[MAX_POINTS_DAY_HEIGHT], // Массив для записи количества повторов уровня. Первый элемент - кол-во тиков на уровне g_minDayPrice,
g_levelsCnt, // Текущее количество уровней в дне
g_curDayNumber; // Номер в году для текущего обрабатываемого дня
double g_minDayPrice, // Минимальная цена текущего дня, на которую приходится первый элемент массива количества повторов уровня
g_point;
datetime g_curDayStart; // Время открытия дня, для которого собираются тиковые данные
TickStruct g_ticks[]; // Массив для хранения тиков, поступивших после начала работы индикатора
#define PREFIX "CLSTRBXNDH_" // Префикс имени графических объектов, отображаемых индикатором
int OnInit()
{
// код доступен только после оплаты
}
bool IsTuningParametersCorrect()
{
string name = WindowExpertName();
int period = Period();
if (period == 0)
{
Alert(name, ": фатальная ошибка терминала - период 0 минут. Индикатор отключен.");
return (false);
}
g_point = Point;
if (g_point == 0)
{
Alert(name, ": фатальная ошибка терминала - величина пункта равна нулю. Индикатор отключен.");
return (false);
}
g_curDayStart = 0;
g_curDayNumber = -1;
return (true);
}
bool IsLoadTempTicks()
{
int hTicksFile = FileOpen(Symbol() + "temp.tks", FILE_BIN | FILE_READ | FILE_SHARE_READ | FILE_SHARE_WRITE);
if (hTicksFile < 1)
return true;
int recSize = (int)(FileSize(hTicksFile) / sizeof(TickStruct));
if (ArrayResize(g_ticks, recSize, 1000) < 0)
{
Alert(WindowExpertName(), ": не удалось распределить память для подкачки данных из временного файла тиков. Индикатор отключен.");
FileClose(hTicksFile);
return false;
}
int i = 0;
while (i < recSize)
{
if (FileReadStruct(hTicksFile, g_ticks[i]) == 0)
{
Alert(WindowExpertName(), ": ошибка чтения данных из временного файла. Индикатор отключен.");
return false;
}
i++;
}
FileClose(hTicksFile);
return true;
}
void OnDeinit(const int reason)
{
if (!IsSavedFile()) // Если ни один из подключенных индикаторов не сохранил данные, то их сохранит текущий индикатор
SaveTempTicks(); // Сохранение данных о тиках, накопленных за текущий период работы индикатора
DeleteAllObjects();
}
bool IsSavedFile()
{
int lastTickIndex = ArraySize(g_ticks) - 1;
if (lastTickIndex < 0) // Ни один тик не был получен. Запись данных не требуется
return true;
int hTicksFile = FileOpen(Symbol() + "temp.tks", FILE_BIN | FILE_READ | FILE_SHARE_READ | FILE_SHARE_WRITE);
if (hTicksFile < 1)
return false;
if (!FileSeek(hTicksFile, -sizeof(TickStruct), SEEK_END))
{
FileClose(hTicksFile);
return false;
}
TickStruct tick;
uint readBytes = FileReadStruct(hTicksFile, tick);
FileClose(hTicksFile);
if (readBytes == 0)
return false;
return tick.time >= g_ticks[lastTickIndex].time; // Дата/время последнего записанного в файле тика больше или равна дате/времени..
}
void SaveTempTicks()
{
int hTicksFile = FileOpen(Symbol() + "temp.tks", FILE_BIN | FILE_READ | FILE_WRITE | FILE_SHARE_READ | FILE_SHARE_WRITE);
if (hTicksFile < 1)
return;
int total = ArraySize(g_ticks), i = 0;
while (i < total)
{
if (FileWriteStruct(hTicksFile, g_ticks[i]) == 0)
{
Print("Ошибка сохранения данных во временный файл...");
return;
}
i++;
}
FileClose(hTicksFile);
}
void DeleteAllObjects()
{
for (int i = ObjectsTotal() - 1; i >= 0; i--)
if (StringSubstr(ObjectName(i), 0, StringLen(PREFIX)) == PREFIX)
ObjectDelete(ObjectName(i));
}
void ShowTrendLine(datetime time1, double price1, datetime time2, int index, string toolTip, color clr)
{
string name = PREFIX + "LINE_" + IntegerToString(time1) + IntegerToString(index);
if (ObjectFind(0, name) < 0)
{
ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price1);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, name, OBJPROP_RAY, false);
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
return;
}
ObjectMove(0, name, 0, time1, price1);
ObjectMove(0, name, 1, time2, price1);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
}
int GetRecalcIndex(int& total, const int ratesTotal, const int prevCalculated)
{
total = ratesTotal - 1;
if (i_indBarsCoПоказано первые 50% кода (символов: 10063)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.