← К каталогу
Исходный код · ID 3186

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 и перейдите к оплате.

Стоимость полного кода
1 651,80₽ ≈ $20.19