Странное поведение оператора WHILE

 

Привет всем!

У меня есть советник (никогда не тестировал его на сборках до 600, но коду уже 2 года), который застревает во время WHILE на сборке 625.

Дело в том, что когда начинается WHILE, он, похоже, не может проверить выражения: в результате он никогда не выходит. Он помещается в функцию запуска.

Я попробовал очень простой советник, чтобы понять, что происходит:


int counter=0, MaxCount = 10000; 

void start()
  {
  while( counter <= MaxCount )
   {Print("Counter ", counter);
   counter++;
   }
   return;
  }

Ну, первое значение счетчика обычно начинается со случайного значения выше 9500, а не с 0.

Почему так? Есть какие-нибудь предложения?

 

может быть, счетчик получает другое значение где-то еще внутри советника?

void start()
  {
  int counter=0, MaxCount = 10000;
  while( counter <= MaxCount )
   {Print("Counter ", counter);
   counter++;
   }
   return;
  }
 
lord_hiro:

Привет всем!

У меня есть советник (никогда не тестировал его на сборках до 600, но коду уже 2 года), который застревает во время WHILE на сборке 625.

Дело в том, что когда начинается WHILE, он, похоже, не может проверить выражения: в результате он никогда не выходит. Он помещается в функцию запуска.

Я попробовал очень простой советник, чтобы понять, что происходит:

Ну, первое значение счетчика обычно начинается со случайного значения выше 9500, а не с 0.

Почему так? Есть какие-нибудь предположения?

Вы объявили счетчик глобальным, что означает, что он статичен.

Ваш код в OnStart(), counter++ продвигает значение счетчика до 10000.

Поэтому, поскольку он статичен, при следующем тике ваш счетчик будет иметь значение 10 000 для начала.

 
SDC:

Вы объявили счетчик глобальным, что означает, что он статичен.

Ваш код в OnStart(), counter++ продвигает значение счетчика до 10,000.

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


написал он:

lord_hiro:

Ну, первое значение счетчика обычно начинается со случайного значения выше 9500, а не с 0.

Почему так? Есть какие-нибудь предположения?


вот мой ответ


qjol:

возможно, счетчик получает другое значение где-то еще внутри советника, попробуйте:

void start()
  {
  int counter=0, MaxCount = 10000;
  while( counter <= MaxCount )
   {Print("Counter ", counter);
   counter++;
   }
   return;
  }
 
lord_hiro:

Привет всем!

У меня есть советник (никогда не тестировал его на сборках до 600, но коду уже 2 года), который застревает во время WHILE на сборке 625.

Дело в том, что когда начинается WHILE, он, похоже, не может проверить выражения: в результате он никогда не выходит. Он помещается в функцию запуска.

Я попробовал очень простой советник, чтобы понять, что происходит:


Ну, первое значение счетчика обычно начинается со случайного значения выше 9500, а не с 0.

Почему так? Есть какие-нибудь предложения?



Скорее всего, вы смотрите на вкладке "Эксперты", которая не может поддерживать такие быстрые циклы, как этот.

Откройте фактический файл журнала.

 

Я могу сказать одно, что цикл while никогда не выполнится во второй раз, если только в другом месте кода вы снова не вызовете переменную счетчика и не измените ее значение на меньшее, чем 10 001. Вы должны быть осторожны с глобальным объявлением переменных.

 
lord_hiro: Первое значение счетчика обычно начинается со случайного значения выше 9500, а не с 0. Почему так происходит? Есть предложения?
До билда 600 неинициализированные переменные инициализировались нулем. Теперь они содержат случайные значения, если их не инициализировать.
 
Он действительно инициализировал их, должно быть что-то другое, изменяющее значение переменной счетчика...
 
Как сказал GumRai, журнал не может справиться с такой скоростью, он пропускает большую часть фактических данных и показывает вам только некоторые фрагменты.
 

GumRai, вы правы: в логе отображаются все выходы, начиная с 1.

Разница между размещением объявления переменной в глобальном пространстве и внутри OnStart() в том, что в первом случае цикл выполняется один раз, а во втором - повторяется бесконечно.

Но... Очевидно, что я выбрал неправильный пример для отладки, потому что цикл подсчета выполняется нормально.

Все началось со следующего советника.

Вот его код:

 extern int SwingBarCount = 100;
int start()



{

int SwingHighShift = 0;
string StringHighStatus = "False";
int SwingHigh = 0;


while (StringHighStatus == "False" || SwingHighShift <= SwingBarCount)
   {
   
   if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == iHigh(NULL, 0, SwingHighShift) && iFractals(NULL, 0, MODE_UPPER, SwingHighShift) > Close[0])
      {
      StringHighStatus = "True";
      SwingHigh = SwingHighShift;
      ObjectDelete("SwingHigh");
      ObjectCreate("SwingHigh", OBJ_VLINE, 0, Time[SwingHigh], 0);
      ObjectSet("SwingHigh", OBJPROP_COLOR, Red);
      }
      else
      {
      SwingHighShift++;
      }

   }

}}

Я удалил другой, не относящийся к делу код для ясности, и он выполняется до WHILE, потому что я поставил несколько точек останова перед этим.

Он должен начинаться с того, что условие WHILE будет истинным и циклически повторять IF ELSE, пока StringHighStatus не станет истинным или StringHighShift не достигнет SwingBarCount.

Вместо этого я вижу, что она никогда не заканчивается, потому что после WHILE идет серия команд COMMENT и PRINT, которые не выдают никакого результата.

В то время как StringHighStatus может оставаться ложным, счетчик должен достичь SwingBarCount.

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

while (!EndCycle)
   {
   
   if(iFractals(NULL, 0, MODE_UPPER, SwingHighShift) == iHigh(NULL, 0, SwingHighShift) && iFractals(NULL, 0, MODE_UPPER, SwingHighShift) > Close[0])
      {
      StringHighStatus = "True";
      SwingHigh = SwingHighShift;
      ObjectDelete("SwingHigh");
      ObjectCreate("SwingHigh", OBJ_VLINE, 0, Time[SwingHigh], 0);
      ObjectSet("SwingHigh", OBJPROP_COLOR, Red);
      }
      else
      {
      SwingHighShift++;
      }
      if( StringHighStatus == "True" ) EndCycle = TRUE;
      if( SwingHighShift > SwingBarCount ) EndCycle = TRUE;
   }

Я не понимаю, почему он обрабатывает EndCycle, а не другое условие.

Спасибо всем за ответы!

 
if( StringHighStatus == "True" ) EndCycle = TRUE;
else if( SwingHighShift > SwingBarCount ) EndCycle = TRUE;
попробуйте включить еще.
Причина обращения: