RenkoLiveChart
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «renkolivechart_v600_indi.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Данный продукт представляет собой пользовательский индикатор для MetaTrader 4, который строит ренко-графики (Renko) на основе исторических и текущих ценовых данных. Индикатор формирует блоки фиксированного размера, записывая их в офлайн-файлы истории (.hst), что позволяет отображать Renko-графики непосредственно в платформе.
В процессе инициализации индикатор обрабатывает исторические свечи для построения ренко-истории, а затем переходит в режим обработки живых тиков, обновляя блоки по текущей цене Bid. Для взаимодействия с окнами графиков используется Windows API (PostMessageW), а для работы с файлами истории — встроенные функции MQL4. Для корректной работы необходимо разрешить вызовы DLL.
Индикатор поддерживает автоматическую адаптацию для брокеров с 3/4/5/6 знаками после запятой, отображение фитилей (максимум/минимум), эмуляцию ренко-графика на линейном окне и выбор офлайн-таймфрейма. Настройка смещения блока позволяет задать начальную точку построения относительно последней свечи.
Настройки программы
| Настройка | Описание |
|---|---|
| RenkoBoxSize | Размер блока Ренко — Устанавливает размер блока Ренко в пунктах (автоматически корректируется для брокеров с 3/4/5/6 знаками) |
| RenkoBoxOffset | Смещение блока Ренко — Задаёт смещение начальной точки первого блока Ренко от цены закрытия последней свечи (должно быть меньше RenkoBoxSize) |
| Offline Timeframe (RenkoTimeFrame) | Таймфрейм офлайн — Определяет офлайн-таймфрейм для построения ренко-графика (допустимые значения: 1, 5, 15, 30, 60, 240, 1440, 10080, 43200) |
| ShowWicks | Показать фитиль — Включает отображение фитилей (максимумов и минимумов) на ренко-блоках |
| EmulateOnLineChart | Эмуляция на линейном графике — Включает эмуляцию ренко-графика на линейном оконном графике с помощью Windows API-сообщений |
| StrangeSymbolName | Необычное имя символа — При активации использует первые 6 символов имени инструмента для формирования имени файла истории |
Поиск по коду файла
#property version "6.00"
#property strict
#property indicator_chart_window
#include <WinUser32.mqh>
#include <stdlib.mqh>
#import "user32.dll"
int RegisterWindowMessageW(string lpString);
#import
input double RenkoBoxSize = 3.0;
input int RenkoBoxOffset = 0;
input int RenkoTimeFrame = 7; // Offline Timeframe
input bool ShowWicks = false;
input bool EmulateOnLineChart = true;
input bool StrangeSymbolName = false;
int HstHandle = -1, LastFPos = 0, MT4InternalMsg = 0;
string sSymbolName;
datetime dtSendTime;
double dSendOpen;
double dSendHigh;
double dSendLow;
double dSendClose;
double dSendVol;
bool bStopAll = false;
int iRcdCnt = 0;
int hwnd = 0;
double BoxPoints, UpWick, DnWick;
double PrevLow, PrevHigh, PrevOpen, PrevClose, CurVolume, CurLow, CurHigh, CurOpen, CurClose;
datetime PrevTime;
int OnInit()
{
// код доступен только после оплаты
}
void OnDeinit(const int reason)
{
if(HstHandle >= 0)
{
FileClose(HstHandle);
HstHandle = -1;
}
Comment("");
return;
}
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(bStopAll) return(0);
if(HstHandle < 0)
{
if(!IsConnected())
{
Print("Waiting for connection...");
return(0);
}
if(!IsDllsAllowed())
{
Print("Error: Dll calls must be allowed!");
bStopAll = true;
return(0);
}
if(MathAbs(RenkoBoxOffset) >= RenkoBoxSize)
{
Print("Error: |RenkoBoxOffset| should be less then RenkoBoxSize!");
bStopAll = true;
return(0);
}
switch(RenkoTimeFrame)
{
case 1:
case 5:
case 15:
case 30:
case 60:
case 240:
case 1440:
case 10080:
case 43200:
case 0:
Print("Error: Invald time frame used for offline renko chart (RenkoTimeFrame)!");
bStopAll = true;
return(0);
}
double BoxSize = RenkoBoxSize;
int BoxOffset = RenkoBoxOffset;
if(Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1))
{
BoxSize = BoxSize * 10;
BoxOffset = BoxOffset * 10;
}
if(Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1))
{
BoxSize = BoxSize * 100;
BoxOffset = BoxOffset * 100;
}
if(StrangeSymbolName) sSymbolName = StringSubstr(Symbol(), 0, 6);
else sSymbolName = Symbol();
BoxPoints = NormalizeDouble(BoxSize * Point, Digits);
PrevLow = NormalizeDouble(BoxOffset * Point + MathFloor(Close[Bars - 1] / BoxPoints) * BoxPoints, Digits);
DnWick = PrevLow;
PrevHigh = PrevLow + BoxPoints;
UpWick = PrevHigh;
PrevOpen = PrevLow;
PrevClose = PrevHigh;
CurVolume = 1;
PrevTime = Time[Bars - 1];
HstHandle = FileOpenHistory(sSymbolName + IntegerToString(RenkoTimeFrame) + ".hst", FILE_BIN | FILE_WRITE | FILE_ANSI);//W1
if(HstHandle < 0)
{
Print("Error: can\'t create / open history file: " + ErrorDescription(GetLastError()) + ": " + sSymbolName + IntegerToString(RenkoTimeFrame) + ".hst");
bStopAll = true;
return(0);
}
else
{
Print("History file opened for write, handle: " + IntegerToString(HstHandle));
FileSeek(HstHandle, 0, SEEK_SET);
}
DoOpenHistoryReadWrite();
FileSeek(HstHandle, 0, SEEK_SET);
int HstUnused[13];
FileWriteInteger(HstHandle, 401, LONG_VALUE); // Version // was 400
FileWriteString(HstHandle, "", 64); // Copyright
FileWriteString(HstHandle, sSymbolName, 12); // Symbol
FileWriteInteger(HstHandle, RenkoTimeFrame, LONG_VALUE); // Period
FileWriteInteger(HstHandle, Digits, LONG_VALUE); // Digits
FileWriteInteger(HstHandle, 0, LONG_VALUE); // Time Sign
FileWriteInteger(HstHandle, 0, LONG_VALUE); // Last Sync
FileWriteArray(HstHandle, HstUnused, 0, 13); // Unused
int i = Bars - 2;
while(i >= 0)
{
CurVolume = CurVolume + Volume[i];
UpWick = MathMax(UpWick, High[i]);
DnWick = MathMin(DnWick, Low[i]);
bool UpTrend = High[i] + Low[i] > High[i + 1] + Low[i + 1];
bool WipeUpWick = false, WipeDownWick = false;
while(UpTrend && (Low[i] < PrevLow - BoxPoints || CompareDoubles(Low[i], PrevLow - BoxPoints)))
{
PrevHigh = PrevHigh - BoxPoints;
PrevLow = PrevLow - BoxPoints;
PrevOpen = PrevHigh;
PrevClose = PrevLow;
dtSendTime = PrevTime;
dSendOpen = PrevOpen;
if(ShowWicks==true && DnWick < PrevLow && Low[i] >= PrevLow - BoxPoints)
{
dSendLow = DnWick;
WipeDownWick = true;
}
else
{
dSendLow = PrevHigh;
}
if(ShowWicks==true && UpWick > PrevHigh && UpWick <= PrevHigh + 2 * BoxPoints)
{
dSendHigh = UpWick;
WipeUpWick = true;
}
else
{
dSendHigh = PrevHigh;
}
dSendClose = PrevClose;
dSendVol = CurVolume;
DoWriteStruct(dtSendTime, dSendOpen, dSendHigh, dSendLow, dSendClose, dSendVol);
if(WipeUpWick) UpWick = 0;
if(WipeDownWick) DnWick = EMPTY_VALUE;
CurVolume = 0;
CurHigh = PrevLow;
CurLow = PrevLow;
if(PrevTime < Time[i]) PrevTime = Time[i];
else PrevTime++;
}
while(High[i] > PrevHigh + BoxPoints || CompareDoubles(High[i], PrevHigh + BoxPoints))
{
PrevHigh = PrevHigh + BoxPoints;
PrevLow = PrevLow + BoxPoints;
PrevOpen = PrevLow;
PrevClose = PrevHigh;
dtSendTime = PrevTime;
dSendOpen = PrevOpen;
if(ShowWicks==true && DnWick < PrevLow && DnWick >= PrevLow - 2 * BoxPoints )
{
dSendLow = DnWick;
WipeDownWick = true;
}
else
{
dSendLow = PrevLow;
}
if(ShowWicks==true && UpWick > PrevHigh && High[i] <= PrevHigh + BoxPoints)
{
dSendHigh = UpWick;
WipeUpWick = true;
}
else
{
dSendHigh = PrevLow;
}
dSendClose = PrevClose;
dSendVol = CurVolume;
DoWriteStruct(dtSendTime, dSendOpen, dSendHigh, dSendLow, dSendClose, dSendVol);
if(WipeUpWick) UpWick = 0;
if(WipeDownWick) DnWick = EMPTY_VALUE;
CurVolume = 0;
CurHigh = PrevHigh;
CurLow = PrevHigh;
if(PrevTime < Time[i]) PrevTime = Time[i];
else PrevTime++;
RefreshRates();
}
Показано первые 50% кода (символов: 9865)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.