Ну верхний вариант понятно как - делаем дополнительные 2 буфера.
Сначала выводим буфер сумм трёх первичных буферов, потом буфер двух первичных, потом один из первичных.
Второй вариант не знаю вообще ли возможен (я про 4ку). В МТ5 возможно есть какие-то танцы с бубнами
Всяко линии в таких случаях нагляднее гисты будут
Ну верхний вариант понятно как - делаем дополнительные 2 буфера.
Сначала выводим буфер сумм трёх первичных буферов, потом буфер двух первичных, потом один из первичных.
Второй вариант не знаю вообще ли возможен (я про 4ку). В МТ5 возможно есть какие-то танцы с бубнами
Всяко линии в таких случаях нагляднее гисты будут
Спасибо, я про МТ5. Про разные буферы в одном индикаторном окне я не подумал. Это вариант. Попробую.
Спасибо, я про МТ5. Про разные буферы в одном индикаторном окне я не подумал. Это вариант. Попробую.
Самый длинный столбец должен иметь наименьший индекс буфера, самый короткий - наибольший индекс. В общем - бутерброд...
Самый длинный столбец должен иметь наименьший индекс буфера, самый короткий - наибольший индекс. В общем - бутерброд...
Спасибо, так и сделаю.
Вариант через канвас в первом приближении (реализовано только для макс. увеличения)
Даже собственные буферы для гистограмы по сути не нужны
#property indicator_chart_window #include <Canvas\iCanvas.mqh> // https://www.mql5.com/ru/code/22164 #property indicator_buffers 3 #property indicator_plots 3 //--- plot Ma1 #property indicator_label1 "Ma1" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Ma2 #property indicator_label2 "Ma2" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Ma3 #property indicator_label3 "Ma3" #property indicator_type3 DRAW_LINE #property indicator_color3 clrGreen #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- indicator buffers double Ma1Buffer[]; double Ma2Buffer[]; double Ma3Buffer[]; int MaHandle1,MaHandle2,MaHandle3,RT=0; //////////////////////////////////////////////////////////////////////////////// int OnInit() { //--- indicator buffers mapping ChartSetInteger(0,CHART_SCALE,0,5); SetIndexBuffer(0,Ma1Buffer,INDICATOR_DATA); SetIndexBuffer(1,Ma2Buffer,INDICATOR_DATA); SetIndexBuffer(2,Ma3Buffer,INDICATOR_DATA); MaHandle1=iMA(NULL,0,10,0,MODE_SMA,PRICE_CLOSE); MaHandle2=iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE); MaHandle3=iMA(NULL,0,30,0,MODE_SMA,PRICE_CLOSE); ChartSetInteger(0,CHART_CROSSHAIR_TOOL,0,true); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) {if (reason<2) ChartRedraw(); } //////////////////////////////////////////////////////////////////////////////// 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[]) { int to_copy; if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total; else { to_copy=rates_total-prev_calculated; to_copy++; } if(CopyBuffer(MaHandle1,0,0,to_copy,Ma1Buffer)<=0) Print("Error CopyBuffer1 - ",GetLastError()); if(CopyBuffer(MaHandle2,0,0,to_copy,Ma2Buffer)<=0) Print("Error CopyBuffer2 - ",GetLastError()); if(CopyBuffer(MaHandle3,0,0,to_copy,Ma3Buffer)<=0) Print("Error CopyBuffer3 - ",GetLastError()); if(rates_total==prev_calculated && W.Right_bar<1) { Canvas.FillRectangle((int)Canvas.X(0.0)-11,W.Height-1,(int)Canvas.X(0.0)+11, 0,0); Canvas.FillRectangle((int)Canvas.X(0.0)-11,W.Height-1,(int)Canvas.X(0.0)-5, W.Height-Round(fabs(close[RT-1]-Ma1Buffer[RT-1])/W.dy_pix),0xA0FF0000); Canvas.FillRectangle((int)Canvas.X(0.0)- 3,W.Height-1,(int)Canvas.X(0.0)+3, W.Height-Round(fabs(close[RT-1]-Ma2Buffer[RT-1])/W.dy_pix),0xA00000FF); Canvas.FillRectangle((int)Canvas.X(0.0)+ 5,W.Height-1,(int)Canvas.X(0.0)+11,W.Height-Round(fabs(close[RT-1]-Ma3Buffer[RT-1])/W.dy_pix),0xA000FF00); Canvas.Update(); } RT=rates_total; return(rates_total); } //////////////////////////////////////////////////////////////////////////////// void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id==CHARTEVENT_CHART_CHANGE) { Canvas.Erase(0); for(int i=W.Left_bar;i>=W.Right_bar; i--) { double curPrice=iClose(NULL,0,i); Canvas.FillRectangle((int)Canvas.X((double)i)-11,W.Height-1,(int)Canvas.X((double)i)-5, W.Height-Round(fabs(curPrice-Ma1Buffer[RT-1-i])/W.dy_pix),0xA0FF0000); Canvas.FillRectangle((int)Canvas.X((double)i)- 3,W.Height-1,(int)Canvas.X((double)i)+3, W.Height-Round(fabs(curPrice-Ma2Buffer[RT-1-i])/W.dy_pix),0xA00000FF); Canvas.FillRectangle((int)Canvas.X((double)i)+ 5,W.Height-1,(int)Canvas.X((double)i)+11,W.Height-Round(fabs(curPrice-Ma3Buffer[RT-1-i])/W.dy_pix),0xA000FF00); } Canvas.Update(); } }
желтым маркером выделено то, что непосредственно относится к рисованию трехцветной гистограммы
Вариант через канвас в первом приближении (реализовано только для макс. увеличения)
Даже собственные буферы для гистограмы по сути не нужны
желтым маркером выделено то, что непосредственно относится к рисованию трехцветной гистограммы
А без рисуемых МА? И чтобы в окне данных были значения каждого столбца гистограммы, а не просто трёх скользящих?
А без рисуемых МА? И чтобы в окне данных были значения каждого столбца гистограммы, а не просто трёх скользящих?
Так я машки взял просто с потолка для примера, как основа для расчета. Я же не знаю какие значения нужны в гистограммы выводить.
Если машки не рисовать, то будет еще проще и короче.
А без рисуемых МА? И чтобы в окне данных были значения каждого столбца гистограммы, а не просто трёх скользящих?
Так я машки взял просто с потолка для примера. Я же не знаю какие значения нужны в гистограммы выводить.
Если машки не рисовать, то будет еще проще и короче.
Не проще, не короче не будет. Чтобы в окне данных были значения нужны индикаторные буферы. И не важно чем и как их заполнять. ИМХО.
Не проще, не короче не будет. Чтобы в окне данных были значения нужны индикаторные буферы. И не важно чем и как их заполнять. ИМХО.
Заполнять буферы можете чем угодно. Здесь речь об отображении.
Канвас нужен для реализации того, что физически не возможно стандартными индикаторными примочками реализовать.
А без рисуемых МА? И чтобы в окне данных были значения каждого столбца гистограммы, а не просто трёх скользящих?
Вы это имели ввиду?
#property indicator_chart_window #include <Canvas\iCanvas.mqh> // https://www.mql5.com/ru/code/22164 #property indicator_buffers 3 //--- indicator buffers double Ma1Buffer[]; double Ma2Buffer[]; double Ma3Buffer[]; int MaHandle1,MaHandle2,MaHandle3,RT=0; //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping ChartSetInteger(0,CHART_SCALE,0,5); SetIndexBuffer(0,Ma1Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(1,Ma2Buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,Ma3Buffer,INDICATOR_CALCULATIONS); MaHandle1=iMA(NULL,0,10,0,MODE_SMA,PRICE_CLOSE); MaHandle2=iMA(NULL,0,20,0,MODE_SMA,PRICE_CLOSE); MaHandle3=iMA(NULL,0,30,0,MODE_SMA,PRICE_CLOSE); ChartSetInteger(0,CHART_CROSSHAIR_TOOL,0,true); // GetWindowProperties(W); //--- return(INIT_SUCCEEDED); } void OnDeinit(const int reason) {if (reason<2) ChartRedraw(); } //+------------------------------------------------------------------+ 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[]) { int to_copy; if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total; else { to_copy=rates_total-prev_calculated; to_copy++; } if(CopyBuffer(MaHandle1,0,0,to_copy,Ma1Buffer)<=0) Print("Error CopyBuffer1 - ",GetLastError()); if(CopyBuffer(MaHandle2,0,0,to_copy,Ma2Buffer)<=0) Print("Error CopyBuffer2 - ",GetLastError()); if(CopyBuffer(MaHandle3,0,0,to_copy,Ma3Buffer)<=0) Print("Error CopyBuffer3 - ",GetLastError()); if(rates_total==prev_calculated && W.Right_bar<1) { Canvas.FillRectangle((int)Canvas.X(0.0)-11,W.Height-1,(int)Canvas.X(0.0)+11, 0,0); Canvas.FillRectangle((int)Canvas.X(0.0)-11,W.Height-1,(int)Canvas.X(0.0)-5, W.Height-Round(fabs(Ma1Buffer[RT-1]-W.Y_min)/(5*W.dy_pix)),0xA0FF0000); Canvas.FillRectangle((int)Canvas.X(0.0)- 3,W.Height-1,(int)Canvas.X(0.0)+3, W.Height-Round(fabs(Ma2Buffer[RT-1]-W.Y_min)/(5*W.dy_pix)),0xA00000FF); Canvas.FillRectangle((int)Canvas.X(0.0)+ 5,W.Height-1,(int)Canvas.X(0.0)+11,W.Height-Round(fabs(Ma3Buffer[RT-1]-W.Y_min)/(5*W.dy_pix)),0xA000FF00); Canvas.Update(); } RT=rates_total; return(rates_total); } //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id==CHARTEVENT_CHART_CHANGE) { Canvas.Erase(0); for(int i=W.Left_bar;i>=W.Right_bar; i--) { Canvas.FillRectangle((int)Canvas.X((double)i)-11,W.Height-1,(int)Canvas.X((double)i)-5, W.Height-Round(fabs(Ma1Buffer[RT-1-i]-W.Y_min)/(5*W.dy_pix)),0xA0FF0000); Canvas.FillRectangle((int)Canvas.X((double)i)- 3,W.Height-1,(int)Canvas.X((double)i)+3, W.Height-Round(fabs(Ma2Buffer[RT-1-i]-W.Y_min)/(5*W.dy_pix)),0xA00000FF); Canvas.FillRectangle((int)Canvas.X((double)i)+ 5,W.Height-1,(int)Canvas.X((double)i)+11,W.Height-Round(fabs(Ma3Buffer[RT-1-i]-W.Y_min)/(5*W.dy_pix)),0xA000FF00); } Canvas.Update(); } } //+------------------------------------------------------------------+
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Подскажите, как можно на 1 баре разместить несколько гистограмм для разных буферов рядом друг с другом или накопительно? Примеры на рисунке.