Масштаб чарта - страница 2

 
Yevhenii Levchenko #:

Можно устанавливать

что?

 
Nikolai Semko #:

что?

CHART_PRICE_MIN и CHART_PRICE_MAX

Или там о другом речь?

 
Yevhenii Levchenko #:

CHART_PRICE_MIN и CHART_PRICE_MAX

Или там о другом речь?

   

 

а, ну можно использовать CHART_FIXED_MAX и CHART_FIXED_MIN

только как то все стрёмно получается при горизонтальном и вертикальном скролинге   

#property indicator_chart_window
#include <Canvas\iCanvas_CB.mqh> //https://www.mql5.com/ru/code/22164
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[]) {
   return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if(id==CHARTEVENT_CHART_CHANGE) Draw();
}
//+------------------------------------------------------------------+
void Draw() {
   double high[], low[];
   CopyHigh(_Symbol,0,(int)W.Right_bar,W.BarsInWind,high);
   CopyLow(_Symbol,0,(int)W.Right_bar,W.BarsInWind,low);
   int i_prmax = ArrayMaximum(high);
   int i_prmin = ArrayMinimum(low);
   int x1 = (int)Canvas.X((double)W.Left_bar-i_prmax);
   int x2 = (int)Canvas.X((double)W.Left_bar-i_prmin);
   int y1 = (int)Canvas.Y(high[i_prmax]);
   int y2 = (int)Canvas.Y(low[i_prmin]);
   if (x1==x2) return;
   double k = fabs(double(y1-y2)/(x1-x2));
   double center_price =W.Y_max - (W.Y_max-W.Y_min)*((y1+y2)/2.0)/W.Height;
   double newMaxPrice =center_price+(W.Y_max-center_price)*k;
   double newMinPrice =center_price-(center_price-W.Y_min)*k;
   Canvas.Erase(0x00FFFFFF);
   ChartSetInteger(0,CHART_SCALEFIX,true);
   ChartSetDouble(0,CHART_FIXED_MAX,newMaxPrice);
   ChartSetDouble(0,CHART_FIXED_MIN,newMinPrice);
   Canvas.Line(x1,y1,x2,y2,0xFFFF00FF);
   Canvas.Update();
}
//+------------------------------------------------------------------+
 
Nikolai Semko #:

   

Ааа, перепутал...

CHART_FIXED_MAX и CHART_FIXED_MIN можно устанавливать точно - себе индикаторы кодировал по шкале и в них с этими идентификаторами работа идет (фиксируется график предварительно)

 

более менее решил, в функцию в ночи оформлять лень

   int leftBar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR); // самый левый бар чарта (чтобы потом Navigate)

   double dy=....; // рассчёт поскипал - наклон линии в пунктах на бар
   // учёт масштаба
   int scale=(int)ChartGetInteger(0,CHART_SCALE);
   switch(scale) {
      case 0: dy/=2;break;
      case 1: break;
      case 2: dy*=2;break;
      case 3: dy*=4;break;
      case 4: dy*=8;break;
   }
   double barWidth=(double)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)/ChartGetInteger(0,CHART_WIDTH_IN_BARS); // ширина бара в пикселях
   int dpi=TerminalInfoInteger(TERMINAL_SCREEN_DPI);            // разрешение терминала

   ChartSetInteger(0,CHART_SCALE_PT_PER_BAR,1);         // 
   ChartSetDouble(0,CHART_POINTS_PER_BAR,dy/barWidth*dpi/96);  // делаем высота=ширине с учётом dpi

   // Navigate - обязательно или по крайней мере крайне желательно
   ChartNavigate(0,CHART_CURRENT_POS,leftBar);

не уверен что правильно учёл DPI (и надо-ли его учитывать)


и незнаю что терминалу скомандывать по цену выровнил по верху (правильно сдвинул чарт вверх-вниз). 

в результате график может быть выше или ниже. Лёгкое движение мыши и всё встаёт на место.

А вот программно что-то пока никак :-(

Эффект от двойного клика по шкале цены - как сделать то-же программно ??

 
Maxim Kuznetsov #:

Эффект от двойного клика по шкале цены - как сделать то-же программно ??

Убрать фиксацию графика можно попробовать... Или на фиксированном устанавливать по самой максимальной и самой минимальной ценам свеч (которые на чарте), с небольшим смещением

 

И всё-таки оно не работает :-(

Но уже склоняюсь считать что это "необъяснимая особенность", скажем так:

и 

открытие боковой вкладки (Navigator, Ctrl+N) визуально изменяет масштаб, при этом бары той-же ширины и пунктов на бар столько-же..

 
Maxim Kuznetsov #:

И всё-таки оно не работает :-(

Но уже склоняюсь считать что это "необъяснимая особенность", скажем так:

и 

открытие боковой вкладки (Navigator, Ctrl+N) визуально изменяет масштаб, при этом бары той-же ширины и пунктов на бар столько-же..

Так а что нужно? Динамическое изменение шкалы или однократное? 
 
Yevhenii Levchenko #:
Так а что нужно? Динамическое изменение шкалы или однократное? 

указанный выше код правильно работает только при отсутсвии боковых окон. Наличие боковых окон изменяет визуальный масштаб. Если их закрыть - будет 45. А если открыть то нет.

надо изменить масштаб графика чтобы линия визуально была 45 градусов. При переключении ТФ рассчитываю опорную линию points/bar и захотелось чтобы визуально она была 45. 

похоже что дурная затея, тут это невозможно, на простую казалось-бы вещь уходит время и код стремительно и не по делу толстеет.

Из всех вариантов масштабирования подходит только SCALE_PT_PER_BAR, потому-что SCALE_FIX фиксирует верхнюю/нижнюю цену и тогда придётся в динамике, с новыми барами и скролом графика их самому пересчитывать.

но при SCALE_PT_PER_BAR навигация по графику превращается в кошмар - цены прижимаются то к верху экрана, то к низу. Сверху пол-экрана пусто, но цены заскакивают вниз. График то можно поднять/опустить мышкой то нет.

и отсутствует аналог ChartNavigate но не для скролла вправо-влево, а для сдвига графика вверх-вниз.