MTH Renko Chart Builder Indi
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «!mth renko chart builder indi ver 02.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Данный продукт представляет собой индикатор для MetaTrader 4, который строит ренко-диаграммы в виде офлайн-исторических файлов (.hst). Он обрабатывает исторические данные цен и текущие котировки Bid, формируя ренко-блоки и записывая их в файлы истории, которые MetaTrader может загружать как офлайн-графики.
Индикатор поддерживает одновременную работу двух независимых ренко-диаграмм, каждая из которых имеет собственные параметры размера блока, сдвига, таймфрейма и отображения фитилей. Для обновления окон графиков при формировании новых блоков используются функции Windows API из библиотеки user32.dll.
Настройки включают начальную цену выравнивания, параметры блоков, выбор таймфрейма и максимальное количество обрабатываемых исторических баров. Для корректной работы необходимо разрешение на вызов DLL. Индикатор не содержит торговой логики и не отправляет ордера.
Настройки программы
| Настройка | Описание |
|---|---|
| StartingPrice | Начальная цена — Начальная цена для выравнивания ренко-блоков при построении первой диаграммы. |
| RenkoBoxSize1 | Размер блока 1 — Размер блока ренко для первой диаграммы в пунктах цены. |
| BoxShiftPercent1 | Процент сдвига блока 1 — Процент сдвига блока для первой ренко-диаграммы, определяет долю размера блока, на которую сдвигается нижняя граница при пробитии. |
| What time frame to use for the offline renko chart (RenkoTimeFrame1) | Таймфрейм 1 — Таймфрейм для первой офлайн-ренко-диаграммы (числовое значение: 1 = M1, 5 = M5 и т.д.). |
| RenkoBoxOffset1 | Смещение блока 1 — Смещение блока для первой ренко-диаграммы, задаёт начальное смещение от стартовой цены. |
| ShowWicks1 | Показ фитилей 1 — Отображение фитилей (теней) для первой ренко-диаграммы. При включении показываются максимальные и минимальные цены внутри блока. |
| MaxBars1 | Максимум баров 1 — Максимальное количество исторических баров для обработки при построении первой ренко-диаграммы. |
| Use2ndRenkoChart | Использовать вторую ренко-диаграмму — Включение второй ренко-диаграммы. При активации индикатор строит второй набор ренко-блоков с собственными параметрами. |
| RenkoBoxSize2 | Размер блока 2 — Размер блока ренко для второй диаграммы в пунктах цены. |
| BoxShiftPercent2 | Процент сдвига блока 2 — Процент сдвига блока для второй ренко-диаграммы, определяет долю размера блока, на которую сдвигается нижняя граница при пробитии. |
| What time frame to use for the offline renko chart (RenkoTimeFrame2) | Таймфрейм 2 — Таймфрейм для второй офлайн-ренко-диаграммы (числовое значение: 1 = M1, 5 = M5 и т.д.). |
| RenkoBoxOffset2 | Смещение блока 2 — Смещение блока для второй ренко-диаграммы, задаёт начальное смещение от стартовой цены. |
| ShowWicks2 | Показ фитилей 2 — Отображение фитилей (теней) для второй ренко-диаграммы. При включении показываются максимальные и минимальные цены внутри блока. |
| MaxBars2 | Максимум баров 2 — Максимальное количество исторических баров для обработки при построении второй ренко-диаграммы. |
| EmulateOnLineChart | Эмуляция на текущем графике — Переключатель эмуляции обновления на текущем графике. При включении индикатор отправляет сообщения в окно графика для его обновления. |
| StrangeSymbolName | Сокращённое имя символа — Использование сокращённого имени символа (первые 6 символов) при создании файлов истории для ренко-диаграмм. |
Поиск по коду файла
#property indicator_chart_window
#include <WinUser32.mqh>
#include <stdlib.mqh>
#import "user32.dll"
int RegisterWindowMessageW(string lpString);
int GetWindowTextW(int hWnd,string lpString,int nMaxCount);
int PostMessageW(int hWnd,int Msg,int wParam,int lParam);
#import
extern double StartingPrice = 161.001;
extern double RenkoBoxSize1 = 5.0;
extern double BoxShiftPercent1 = 100;
extern int RenkoTimeFrame1 = 2; // What time frame to use for the offline renko chart
extern int RenkoBoxOffset1 = 0;
extern bool ShowWicks1 = true;
extern int MaxBars1 = 100000;
extern bool Use2ndRenkoChart = false;
extern double RenkoBoxSize2 = 10.0;
extern double BoxShiftPercent2 = 50;
extern int RenkoTimeFrame2 = 3; // What time frame to use for the offline renko chart
extern int RenkoBoxOffset2 = 0;
extern bool ShowWicks2 = true;
extern int MaxBars2 = 10000;
extern bool EmulateOnLineChart= true;
extern bool StrangeSymbolName = false;
int HstHandle1 = -1, LastFPos1 = 0, MT4InternalMsg1 = 0;
int HstHandle2 = -1, LastFPos2 = 0, MT4InternalMsg2 = 0;
string SymbolName;
void UpdateChartWindow() {
static int hwnd1 = 0;
if(hwnd1 == 0) {
hwnd1 = WindowHandle(SymbolName, RenkoTimeFrame1);
if(hwnd1 != 0) Print("Chart window detected");
}
if(EmulateOnLineChart && MT4InternalMsg1 == 0)
MT4InternalMsg1 = RegisterWindowMessageW("MetaTrader4_Internal_Message");
if(hwnd1 != 0) if(PostMessageW(hwnd1, WM_COMMAND, 0x822c, 0) == 0) hwnd1 = 0;
if(hwnd1 != 0 && MT4InternalMsg1 != 0) PostMessageW(hwnd1, MT4InternalMsg1, 2, 1);
static int hwnd2 = 0;
if(hwnd2 == 0) {
hwnd2 = WindowHandle(SymbolName, RenkoTimeFrame2);
if(hwnd2 != 0) Print("Chart window detected");
}
if(EmulateOnLineChart && MT4InternalMsg2 == 0)
MT4InternalMsg2 = RegisterWindowMessageW("MetaTrader4_Internal_Message");
if(hwnd2 != 0) if(PostMessageW(hwnd2, WM_COMMAND, 0x822c, 0) == 0) hwnd2 = 0;
if(hwnd2 != 0 && MT4InternalMsg2 != 0) PostMessageW(hwnd2, MT4InternalMsg2, 2, 1);
return;
}
int start() {
// код доступен только после оплаты
}
static double BoxPoints1, UpWick1, DnWick1;
static double PrevLow1, PrevHigh1, PrevOpen1, PrevClose1, CurVolume1, CurLow1, CurHigh1, CurOpen1, CurClose1;
static datetime PrevTime1;
MqlRates rates;
if(HstHandle1 < 0) {
if(!IsDllsAllowed()) {
Print("Error: Dll calls must be allowed!");
return(-1);
}
if(MathAbs(RenkoBoxOffset1) >= RenkoBoxSize1) {
Print("Error: |RenkoBoxOffset| should be less then RenkoBoxSize1!");
return(-1);
}
int BoxSize1 = RenkoBoxSize1;
int BoxOffset1 = RenkoBoxOffset1;
if(Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1)) {
BoxSize1 = BoxSize1*10;
BoxOffset1 = BoxOffset1*10;
}
if(Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1)) {
BoxSize1 = BoxSize1*100;
BoxOffset1 = BoxOffset1*100;
}
if(StrangeSymbolName) SymbolName = StringSubstr(Symbol(), 0, 6);
else SymbolName = Symbol();
BoxPoints1 = NormalizeDouble(BoxSize1*Point, Digits);
if (Close[Bars-1]>= StartingPrice)
{
PrevLow1 = NormalizeDouble(BoxOffset1*Point + MathFloor((Close[Bars-1]-StartingPrice)/BoxPoints1)*BoxPoints1 + StartingPrice, Digits);
}
if (Close[Bars-1]< StartingPrice)
{
PrevLow1 = NormalizeDouble(BoxOffset1*Point + StartingPrice - MathCeil((StartingPrice-Close[Bars-1])/BoxPoints1)*BoxPoints1 - Point, Digits);
}
DnWick1 = PrevLow1;
PrevHigh1 = PrevLow1 + BoxPoints1;
UpWick1 = PrevHigh1;
PrevOpen1 = PrevLow1;
PrevClose1 = PrevHigh1;
CurVolume1 = 1;
PrevTime1 = Time[Bars-1];
HstHandle1 = FileOpenHistory(SymbolName + (string)RenkoTimeFrame1 + ".hst", FILE_BIN|FILE_WRITE|FILE_ANSI);
FileClose(HstHandle1); HstHandle1 = -1;
HstHandle1 = FileOpenHistory(SymbolName + (string)RenkoTimeFrame1 + ".hst", FILE_BIN|FILE_READ|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);
if(HstHandle1< 0) {
Print("Error: can\'t create / open history file: " + ErrorDescription(GetLastError()) + ": " + SymbolName + RenkoTimeFrame1 + ".hst");
return(-1);
}
int HstUnused1[13];
FileWriteInteger(HstHandle1, 401, LONG_VALUE); // Version
FileWriteString(HstHandle1, "", 64); // Copyright
FileWriteString(HstHandle1, SymbolName, 12); // Symbol
FileWriteInteger(HstHandle1, RenkoTimeFrame1, LONG_VALUE); // Period
FileWriteInteger(HstHandle1, Digits, LONG_VALUE); // Digits
FileWriteInteger(HstHandle1, 0, LONG_VALUE); // Time Sign
FileWriteInteger(HstHandle1, 0, LONG_VALUE); // Last Sync
FileWriteArray(HstHandle1, HstUnused1, 0, 13); // Unused
int i1 = Bars-2;
if (i1>MaxBars1) i1=MaxBars1;
while(i1 >= 0) {
CurVolume1 = CurVolume1 + Volume[i1];
UpWick1 = MathMax(UpWick1, High[i1]);
DnWick1 = MathMin(DnWick1, Low[i1]);
bool UpTrend1 = High[i1]+Low[i1] > High[i1+1]+Low[i1+1];
while(!UpTrend1 && (Low[i1] < PrevLow1-(BoxShiftPercent1/100)*BoxPoints1 || CompareDoubles(Low[i1], PrevLow1-(BoxShiftPercent1/100)*BoxPoints1))) {
PrevHigh1 = PrevHigh1 - (BoxShiftPercent1/100)* BoxPoints1;
PrevLow1 = PrevLow1 - (BoxShiftPercent1/100)*BoxPoints1;
PrevOpen1 = PrevHigh1;
PrevClose1 = PrevLow1;
rates.time = PrevTime1;
rates.open = PrevOpen1;
rates.low = PrevLow1;
if(ShowWicks1 && UpWick1 > PrevHigh1)
rates.high = UpWick1;
else rates.high = PrevHigh1;
rates.close = PrevClose1;
rates.real_volume = (long)CurVolume1;
rates.tick_volume = (long)CurVolume1;
FileWriteStruct(HstHandle1,rates);
UpWick1 = 0;
DnWick1 = EMPTY_VALUE;
CurVolume1 = 0;
CurHigh1 = PrevLow1;
CurLow1 = PrevLow1;
if(PrevTime1 < Time[i1]) PrevTime1 = Time[i1];
else PrevTime1++;
}
while(High[i1] > PrevHigh1+(BoxShiftPercent1/100)*BoxPoints1 || CompareDoubles(High[i1], PrevHigh1+(BoxShiftPercent1/100)*BoxPoints1)) {
PrevHigh1 = PrevHigh1 + (BoxShiftPercent1/100)*BoxPoints1;
PrevLow1 = PrevLow1 + (BoxShiftPercent1/100)*BoxPoints1;
PrevOpen1 = PrevLow1;
PrevClose1 = PrevHigh1;
rates.time = PrevTime1;
rates.open = PrevOpen1;
rates.high = PrevHigh1;
if(ShowWicks1 && DnWick1 < PrevLow1)
rates.low = DnWick1;
else rates.low = PrevLow1;
rates.close = PrevClose1;
rates.real_volume = (long)CurVolume1;
rates.tick_volume = (long)CurVolume1;
FileWriteStruct(HstHandle1,rates);
UpWick1 = 0;
DnWick1 = EMPTY_VALUE;
CurVolume1 = 0;
CurHigh1 = PrevHigh1;
CurLow1 = PrevHigh1;
if(PrevTime1 < Time[i1]) PrevTime1 = Time[i1];
else PrevTime1++;
}
while(UpTrend1 && (Low[i1] < PrevLow1-(BoxShiftPercent1/100)*BoxPoints1 || CompareDoubles(Low[i1], PrevLow1-(BoxShiftPercent1/100)*BoxPoints1))) {
PrevHigh1 = PrevHigh1 - (BoxShiftPercent1/100)*BoxPoints1;
PrevLow1 = PrevLow1 - (BoxShiftPercent1/100)*BoxPoints1;
PrevOpen1 = PrevHigh1;
PrevClose1 = PrevLow1;
rates.time = PrevTime1;
rates.open = PrevOpen1;
rates.low = PrevLow1;
if(ShowWicks1 && UpWick1 > PrevHigh1)
rates.high = UpWick1;
else rates.high = PrevHigh1;
rates.close = PrevClose1;
rates.real_volume = (long)CurVolume1;
rates.tick_volume = (long)CurVolume1;
FileWriteStruct(HstHandle1,rates);
UpWick1 = 0;
DnWick1 = EMPTY_VALUE;
CurVolume1 = 0;
CurHigh1 = PrevLow1;
CurLow1 = PrevLow1;
if(PrevTime1 < Time[i1]) PrevTime1 = Time[i1];
else PrevTime1++;
}
i1--;
}
LastFPos1 = FileTell(HstHandle1); // Remember Last pos in file
if(Close[0] > MathMax(PrevClose1, PrevOpen1)) CurOpen1 = MathMax(PrevClose1, PrevOpen1);
else if (Close[0] < MathMin(PrevClose1, PrevOpen1)) CurOpen1 = MathMin(PrevClose1, PrevOpen1);
else CurOpen1 = Close[0];
CurClose1 = Close[0];
if(UpWick1 > PrevHigh1) CurHigh1 = UpWick1;
if(DnWick1 < PrevLow1) CurLow1 = DnWick1;
rates.time = PrevTime1;
rates.open = CurOpen1;
rates.low = CurLow1;
rates.high = CurHigh1;
rates.close = CurClose1;
rates.real_volume = (long)CurVolume1;
rates.tick_volume = (long)CurVolume1;
FileWriteStruct(HstHandle1,rates);
FileFlush(HstHandle1);
UpdateChartWindow();
return(0);
}
UpWick1 = MathMax(UpWick1, Bid);
DnWick1 = MathMin(DnWick1, Bid);
CurVolume1++;
FileSeek(HstHandle1, LastFPos1, SEEK_SET);
if(Bid > PrevHigh1+(BoxShiftPercent1/100)*BoxPoints1 || CompareDoubles(Bid, PrevHigh1+(BoxShiftPercent1/100)*BoxPoints1)) {
PrevHigh1 = PrevHigh1 + (BoxShiftPercent1/100)*BoxPoints1;
PrevLow1 = PrevLow1 + (BoxShiftPercent1/100)*BoxPoints1;
PrevOpen1 = PrevLow1;
PrevClose1 = PrevHigh1;
rates.time = PrevTime1;
rates.open = PrevOpen1;
rates.high = PrevHigh1;
if(ShowWicks1 && DnWick1 < PrevLow1)
rates.low = DnWick1;
else rates.low = PrevLow1;
rates.close = PrevClose1;
rates.real_volume = (long)CurVolume1;
rates.tick_volume = (long)CurVolume1;
FileWriteStruct(HstHandle1,rates);
FileFlush(HstHandle1);
LastFPos1 = FileTell(HstHandle1); // Remember Last pos in file
if(PrevTime1 < TimeCurrent()) PrevTime1 = TimeCurrent();
else PrevTime1++;
CurVolume1 = 0;
CurHigh1 = PrevHigh1;
CurLow1 = PrevHigh1;
UpWick1 = 0;
DnWick1 = EMPTY_VALUE;
UpdateChartWindow();
}
else if(Bid < PrevLow1-(BoxShiftPercent1/100)*BoxPoints1 || CompareDoubles(Bid,PrevLow1-(BoxShiftPercent1/100)*BoxPoints1)) {
PrevHigh1 = PrevHigh1 - (BoxShiftPercent1/100)*BoxPoints1;
PrevLow1 = PrevLow1 - (BoxShiftPercent1/100)*BoxPoints1;
PrevOpen1 = PrevHigh1;
PrevClose1 = PrevLow1;
rates.time = PrevTime1;
rates.open = PrevOpen1;
rates.low = PrevLow1;
if(ShowWicks1 && UpWick1> PrevHigh1)
rates.high = UpWick1;
else rates.high = PrevHigh1;
rates.close = PrevClose1;
rates.real_volume = (long)CurVolume1;
rates.tick_volume = (long)CurVolume1;
FileWriteStruct(HstHandle1,rates);
FileFlush(HstHandle1);
LastFPos1 = FileTell(HstHandle1); // Remember Last pos in file
if(PrevTime1 < TimeCurrent()) PrevTime1 = TimeCurrent();
else PrevTime1++;
CurVolume1 = 0;
CurHigh1 = PrevLow1;
CurLow1 = PrevLow1;
UpWick1 = 0;
DnWick1 = EMPTY_VALUE;
UpdateChartWindow();
}
else {
if(Bid > CurHigh1) CurHigh1 Показано первые 50% кода (символов: 16518)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.