Скрипт на нескольких графиках

 

Приветствую!

Написал  простой скрипт

 

void OnStart()
  {
  long currChart,prevChart=ChartFirst();
   int i=0,limit=10;

   while(i<limit)
     {
     Print( "current graph =", prevChart);
     doGraphCorrection(prevChart);
      currChart=ChartNext(prevChart);
      
      if(currChart<0) break;
      prevChart=currChart;
      
      i++;
     }
  }
  
  
  void doGraphCorrection(long vChartID)
  {
    int hIndicator;
   double vIndicator;

   double l1L, l1H;
   if(ObjectFind(vChartID,"1H")<0) { MessageBox( "1H not found"); return;}
   l1H = iGetDayValue(2, 1);
   ObjectSetDouble(vChartID,"1H",OBJPROP_PRICE, l1H);
  
  
   if(ObjectFind(vChartID,"1L")<0) { MessageBox( "1L not found"); return;}
   l1L = iGetDayValue(2, 2);
   ObjectSetDouble(vChartID,"1L",OBJPROP_PRICE, l1L);
  
   }
  
  
  double iGetValue(int handle, int buffer_num)
  {
   double MA[1];
   ResetLastError();
   if(CopyBuffer(handle,buffer_num,0,1,MA)<0)
     {
      PrintFormat("Failed to copy data from the indicator, error code %d",GetLastError());
      return(0.0);
     }
   return(MA[0]);
  }
  
  double iGetDayValue(int iDayNum, int iValueType)
  // iValueType {0 - Open, 1 - High, 2 - Low, 3 - Close}
  {
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   int copied=CopyRates(Symbol(),PERIOD_D1,0,iDayNum,rates);
//  if(copied>0)   Print("Скопировано баров: "+copied);
//  else           Print("Не удалось получить исторические данные по символу ",Symbol());
   switch(iValueType)
      {
       case 1: return(rates[iDayNum-1].high);
       case 2: return(rates[iDayNum-1].low);
       default: return(0.0);
      }
   return(0.0);
  }

 Ожидаю от него, что на всех открытых в терминале графиках он переместит линии 1L и 1H на мин, макс. предыдущего дня. 

Ан нет :) - толку что все окна открытых графиков прогоняются через цикл, все равно изменения происходят только там, где стоит фокус, т.е. на активном окне.

Что я не учитываю? 

 
nkaretnikov:

Приветствую!

Написал  простой скрипт

Ан нет :) - толку что все окна открытых графиков прогоняются через цикл, все равно изменения происходят только там, где стоит фокус, т.е. на активном окне.

Что я не учитываю? 

В функции iGetDayValue используется символ текущего графика:

int copied=CopyRates(Symbol(),PERIOD_D1,0,iDayNum,rates);

А нужно указывать другой символ.

 
Ihor Herasko:

В функции iGetDayValue используется символ текущего графика:

int copied=CopyRates(Symbol(),PERIOD_D1,0,iDayNum,rates);

А нужно указывать другой символ.

Спасибо! Все получилось
 

Делаю подобным образом в МТ4 скрипт уменьшения масштаба графика:


#include <WinUser32.mqh>

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int prev = GetParent(WindowHandle(Symbol(), Period()));
   int curr = GetWindow(prev, 0);

   for(int i=0; i<10; i++)
     {
      curr = GetWindow(curr, 2);
      PostMessageA(curr, WM_KEYDOWN, 0x6D, 0); // уменьшение масштаба

      Print("Chart: ",curr);
     }
  }


Дескрипторы окон графиков получаю:



Но сообщение не отправляется, масштаб не уменьшается.

Подскажите, пожалуйста что делаю неверно?

 
Andrey Kornishkin:

Делаю подобным образом в МТ4 скрипт уменьшения масштаба графика:


Дескрипторы окон графиков получаю:


Но сообщение не отправляется, масштаб не уменьшается.

Подскажите, пожалуйста что делаю неверно?

CHART_SCALE – свойство масштаба графика.
//+------------------------------------------------------------------+
//| Получение масштаба графика (от 0 до 5).                          |
//+------------------------------------------------------------------+
int ChartScaleGet(const long chart_ID=0)
  {
//--- подготовим переменную для получения значения свойства
   long result=-1;
//--- сбросим значение ошибки
   ResetLastError();
//--- получим значение свойства
   if(!ChartGetInteger(chart_ID,CHART_SCALE,0,result))
     {
      //--- выведем сообщение об ошибке в журнал "Эксперты"
      Print(__FUNCTION__+", Error Code = ",GetLastError());
     }
//--- вернем значение свойства графика
   return((int)result);
  }
//+------------------------------------------------------------------+
//| Установка масштаба графика (от 0 до 5).                          |
//+------------------------------------------------------------------+
bool ChartScaleSet(const long value,const long chart_ID=0)
  {
//--- сбросим значение ошибки
   ResetLastError();
//--- установим значение свойства
   if(!ChartSetInteger(chart_ID,CHART_SCALE,0,value))
     {
      //--- выведем сообщение об ошибке в журнал "Эксперты"
      Print(__FUNCTION__+", Error Code = ",GetLastError());
      return(false);
     }
//--- успешное выполнение
   return(true);
  }
   long currChart=0,prevChart=ChartFirst();
   int i=0,limit=100;
   static long CurrID;
   while(i<limit) { // у нас наверняка не больше 100 открытых графиков
      currChart=ChartNext(prevChart); // на основании предыдущего получим новый график
      if(ChartSetInteger(currChart,....))
         ...
      if(currChart<0) break;          // достигли конца списка графиков
      prevChart=currChart;// запомним идентификатор текущего графика для ChartNext()
      i++;// не забудем увеличить счетчик
   }
 

благодарствую что подсказали направление, только такой вариант меняет масштаб только на графике куда кинешь и только когда щелкнешь по графику.

   long prev = ChartFirst();
   long curr = 0;

   for(int i=0; i<10; i++)
     {
      curr = ChartNext(prev);
      ChartSetInteger(curr,CHART_SCALE,0);
      prev=curr;        
     }
 
Andrey Kornishkin:

благодарствую что подсказали направление, только такой вариант меняет масштаб только на графике куда кинешь и только когда щелкнешь по графику.

ChartSetInteger(curr,CHART_SCALE,0, Сюда ещё значение надо вписать!!!);
 

Alexey Viktorov:

ChartSetInteger(curr,CHART_SCALE,0,0);


результат тот же.


у меня единственный рабочий образец скрипт - меняет тф на всех графиках:

#import "user32.dll"
int      PostMessageA(int hWnd,int Msg,int wParam,int lParam);
int      GetWindow(int hWnd,int uCmd);
int      GetParent(int hWnd);
#import

#define GW_HWNDFIRST 0
#define GW_HWNDNEXT  2
#define WM_COMMAND  0x0111

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   bool blnContinue = true;
   int intParent = GetParent(WindowHandle(Symbol(), Period()));
   int intChild = GetWindow(intParent, GW_HWNDFIRST);
   int intCmd=35400;

   if(intChild > 0)
     {
      if(intChild != intParent)
         PostMessageA(intChild, WM_COMMAND, intCmd, 0);
     }
   else
      blnContinue = false;

   while(blnContinue)
     {
      intChild = GetWindow(intChild, GW_HWNDNEXT);

      if(intChild > 0)
        {
         if(intChild != intParent)
            PostMessageA(intChild, WM_COMMAND, intCmd, 0);
        }
      else
         blnContinue = false;
     }

// Now do the current window
   PostMessageA(intParent, WM_COMMAND, intCmd, 0);
   return(0);
  }
//+------------------------------------------------------------------+
 
Andrey Kornishkin:

результат тот же.


у меня единственный рабочий образец скрипт - меняет тф на всех графиках:

Это работало далеко до того как кардинально поменяли язык и ввели в него немало новых полезных функций. В том числе и предложенную вам…

А вот бездумное вписывание чего попало туда куда вам указали ни к чему не приведёт. Почитайте документацию, те функции которые из документации скопировал для вас Виталий и может быть поймёте что надо сделать.

Могу только подсказать, что после смены масштаба поставьте принудительное обновление графика

    ChartRedraw(curr);
 
Alexey Viktorov:

А вот бездумное вписывание чего попало туда куда вам указали ни к чему не приведёт. 

Могу только подсказать, что после смены масштаба поставьте принудительное обновление графика


вот такой вариант заработал:


input int scale=2;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   long res=-1;
   long prev = ChartFirst();
   long curr = 0;

   for(int i=0; i<10; i++)
     {
      curr = ChartNext(prev);
      ChartSetInteger(curr,CHART_SCALE,0,scale);
      ChartGetInteger(curr,CHART_SCALE,0,res);
      ChartRedraw(curr);
      Print("Chart: ",curr," ",ChartSymbol(curr)," Scale: ",res);
      if(curr<0)
         break;
      prev=curr;
     }
 
Andrey Kornishkin:


вот такой вариант заработал:


А такой вариант покороче

/********************Script program start function*******************/
void OnStart()
 {
  long currChart = 0;
  while(currChart >= 0 && !IsStopped())
   {
    currChart = ChartNext(currChart);
    ChartSetInteger(currChart, CHART_SCALE, 0, 3);
    ChartRedraw(currChart);
   }
 }/******************************************************************/