Странное поведение оператора switch ? - страница 2

 
Alexey Viktorov:
Почему-то вы заострили внимание на проблеме с PERIOD_CURRENT а вся проблема в не очень правильном подходе к проблеме. Зачем вам ТФ? Для регулирования расстояния от high и low бара достаточно цену перевести в пиксели, прибавить или вычесть N пикселей и полученное значение опять перевести в цену на которую и поставить метку.

На самом деле, у меня как-то так и написано. Но почему-то, в тот момент, когда запускается терминал и ещё иногда по каким-то причинам это расстояние само по себе изменяется.

Вот, например, сегодня я запускаю терминал, открыааю график GBPUSD (Weekly) и вижу следующее:

***

Сменяю таймфрейм графика на любой другой. Возвращаюсь назад на  ТФ (Weekly) и вижу:

***

Как видно на скринах, расстояние на обоих графиках различное. С чего бы это вдруг?

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

Вот обе функции:

//==================================================================================================================================================================================
// Возвращает расстояние равное запрошенному количеству процентов (percent) от экрана в зависимости от переданного таймфрейма. =====================================================
double Draw :: relativeDistance(const ENUM_TIMEFRAMES tf) {
  switch (tf) {
    case PERIOD_M1:
    case PERIOD_M5:
    case PERIOD_M15:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 4;
      break;
    case PERIOD_M30:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 4.5;
      break;
    case PERIOD_H1:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 3.5;
      break;
    case PERIOD_H4:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 4;
      break;
    case PERIOD_D1:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 4.5;
      break;
    case PERIOD_W1:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 4.5;
      break;
    case PERIOD_MN1:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 4.5;
      break;
    default:
      return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * 3;
  }
}
//==================================================================================================================================================================================
// Возвращает расстояние равное запрошенному количеству процентов (percent) от экрана. =============================================================================================
double Draw :: relativeDistance(const double percent) {
  return (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / 100 * percent;
}
//==================================================================================================================================================================================
// Отрисовывает wingdings-символ над/под баром с индексом barIndex. ================================================================================================================
string Draw :: wingdings(string objName,                    // Название объекта
                         const ENUM_LOCATION objLocation,   // Расположение wingdings-символа
                         const long wingdingsCode,          // Код wingdings-символа
                         const int wingdingsWidth,          // Ширина wingdings-символа
                         const color wingdingsColor,        // Цвет wingdings-символа
                         const int barIndex,                // Индекса бара, у которого будет отрисован wingdings-символ
                         const ENUM_TIMEFRAMES tf) {        // Таймфрем, на котором будет отрисован wingdings-символ
//---
  objName += WINGDINGS_NAME + " " + (string)barIndex + " " + TimeToString(barOpenTime(barIndex), TIME_DATE|TIME_MINUTES);

  if (!ObjectCreate(0, objName, OBJ_ARROW, 0, 0, 0)) {
    writeLog(MESSAGE_ERROR, __FUNCTION__ + " { Не удалось создать объект типа 'OBJ_ARROW' }");
    writeLog(MESSAGE_ERROR, __FUNCTION__ + " { _LastError = '" + iToS(_LastError) + "' }");
  }
  ObjectSetInteger(0, objName, OBJPROP_TIME, 0, barOpenTime(barIndex));
//  Print(ObjectGetDouble(0, objName, OBJPROP_PRICE));

  if (objLocation == LOCATION_ABOVE) {
    ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_TOP);
    ObjectSetDouble(0, objName, OBJPROP_PRICE, barHighPrice(barIndex) + relativeDistance(tf));
  }
  else if (objLocation == LOCATION_BELOW) {
    ObjectSetInteger(0, objName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
    ObjectSetDouble(0, objName, OBJPROP_PRICE, barLowPrice(barIndex) - relativeDistance(tf));
  }
  ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, wingdingsCode);
  ObjectSetInteger(0, objName, OBJPROP_WIDTH, wingdingsWidth);
  ObjectSetInteger(0, objName, OBJPROP_COLOR, wingdingsColor);

  ChartRedraw();
//---
  return objName;
}
 

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

пс. для одинакового отступа лучше делать отступ в пикселях, считать сколько пунктов в одном пикселе и перерисовывать видимые объекты.

 
Taras Slobodyanik:

При старте терминала, индикаторы запускаются, но чарта еще нет.

Как я понимаю, теоритически график может быть ещё не подгружен и индикатор уже запустился. Но вот нестыковка.. График недельный. Все бары на графике те, который были вчера. А вчера я тоже запускал платформу. Вот это уже странно. Тем более, странно, что индикатор запустился, при теоритически отсутствующем графике. Если бы, например, я бросил индюк на график с ТФ = М1 и он запустился когда ещё не подгружены данные, то на основании чего он отрисует то, что нужно? Или даже не отрисует, а просчитает то, что нужно. В моём случае отрисовках неких данных для теста, которые дальше не будут принтоваться.


Taras Slobodyanik:

Нужно позже перепроверять, и корректировать.

Всмысле потом? О чём речь? Глазом что-ли перепроверять? )

 
Виктор Демихов:

Как я понимаю, теоритически график может быть ещё не подгружен и индикатор уже запустился. Но вот нестыковка.

я вам говорю практически, не теоретически)
чарт не создан, его нет еще.

Виктор Демихов:

Всмысле потом? О чём речь? Глазом что-ли перепроверять? )

ну, если вы рисуете глазом, то да, им тоже можно)

 
Taras Slobodyanik:

я вам говорю практически, не теоретически)
чарт не создан, его нет еще.

Мысль, я конечно, понял. Подумаю на досуге над реализацией.


Taras Slobodyanik:

ну, если вы рисуете глазом, то да, им тоже можно)

Глазом я рисую лишь мысленно. В данном случае, придётся отлавливать ситуацию наяву..)

 
Виктор Демихов:

Мысль, я конечно, понял. Подумаю на досуге над реализацией.

обычная проверка.
например:

if (ChartGetDouble(0, CHART_PRICE_MAX)<=0 || ChartGetDouble(0, CHART_PRICE_MIN)<=0)

Виктор Демихов:

Глазом я рисую лишь мысленно. В данном случае, придётся отлавливать ситуацию наяву..)

опять таки - проверять изменение размеров чарта и реагировать на это, или в OnChartEvent или в OnTimer

 

В OnCalculate() я написал вот так:

  if (ChartGetDouble(0, CHART_FIXED_MAX) <= 0 || ChartGetDouble(0, CHART_FIXED_MIN) <= 0) {
    Print("max = ", ChartGetDouble(0, CHART_FIXED_MAX));
    Print("min = ", ChartGetDouble(0, CHART_FIXED_MIN));
    return -1;
  }

Самое интересное, что эти дни ни разу не принтанул в журнал терминал ничего. А я так хотел отловить эту ситуацию..((

Искусственно, отключив сеть создать "требуемую атмосферу" тоже не выйдет. Без сети индикатор не показывает всё что нужно.

 
Виктор Демихов:

В OnCalculate() я написал вот так:

Самое интересное, что эти дни ни разу не принтанул в журнал терминал ничего. А я так хотел отловить эту ситуацию..((

Искусственно, отключив сеть создать "требуемую атмосферу" тоже не выйдет. Без сети индикатор не показывает всё что нужно.

Такое можно отловить только на старте работы терминала. При штатной работе неадекватных значений уже не бывает.

P. S. Только заметьте, что проверяете в условии одни значения, а в журнал выводите другие.

 
Ihor Herasko:

Такое можно отловить только на старте работы терминала. При штатной работе неадекватных значений уже не бывает.

Как я понимаю, не только при старте терминала, а, именно, при старте терминала, например, 1-ый раз в день или в несколько дней т.к. если открыть терминал, и, после сразу же закрыть его и открыть снова, навряд ли, будет такой косяк.


Ihor Herasko:

P. S. Только заметьте, что проверяете в условии одни значения, а в журнал выводите другие.

В смысле другие? Я проверяю и вывожу   CHART_FIXED_MIN и CHART_FIXED_MAX.

Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Свойства графиков
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Свойства графиков
  • www.mql5.com
Признак отрисовки ценового графика. Если установлено значение false, то отключается отрисовка любых атрибутов ценового графика и устраняются все отступы по краям графика: шкалы времени и цены, строка быстрой навигации, метки событий Календаря, значки сделок, тултипы индикаторов и баров, подокна индикаторов, гистограммы объёмов и т.д. Значение...
 
Виктор Демихов:

Как я понимаю, не только при старте терминала, а, именно, при старте терминала, например, 1-ый раз в день или в несколько дней т.к. если открыть терминал, и, после сразу же закрыть его и открыть снова, навряд ли, будет такой косяк.

Нет. Все зависит от того, какие события будут выполнены первыми: загрузка данных с сервера или создание чарта. 

В смысле другие? Я проверяю и вывожу   CHART_FIXED_MIN и CHART_FIXED_MAX.

Наверное, Вы отредактировали сообщение. Было CHART_PRICE_MAX и CHART_PRICE_MIN.