Пересечение графиков

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

Пишу определение пересечения графиков таким кодом:
// пересекает ли линия IND1 линию IND2 (true=да)? 
// строим по двум последним точкам, т.е. коротким отрезкам
bool
isIND1_intersect_IND2(double arrClose[]) { double dIND1curr = arrGetIND1Value(0, arrClose), dIND1prev = arrGetIND1Value(1, arrClose); double dIND2curr = arrGetIND2Value(0, arrClose), dIND2prev = arrGetIND2Value(1, arrClose); // debug only Print ("DT: ", TimeToStr(Time[0],TIME_DATE|TIME_MINUTES), ". dIND1curr: ", dIND1curr, ". dIND1prev: ", dIND1prev, ". dIND2curr: ", dIND2curr, ". dIND2prev: ", dIND2prev); if ( (dIND1curr >= dIND2curr) && (dIND1prev <= dIND2prev) || (dIND1curr <= dIND2curr) && (dIND1prev >= dIND2prev) ) // пересеклись { Print("Случилось isIND1_intersect_IND2 !!!"); return (true); } return (false); }
И пример чисел:
USDCHF,M30: DT: 2005.02.17 09:30. dIND1curr: 1.1856. dIND1prev: 1.1861. dIND2curr: 1.1858. dIND2prev: 1.1857

Не пойму почему, но этот простой код определения пересечения двух отрезков НЕ работает :( Подайте идеи, please.
 

Похоже на неправильную группировку условий. Попробуйте так

   if (
      (dIND1curr >= dIND2curr && dIND1prev <= dIND2prev)
      || (dIND1curr <= dIND2curr && dIND1prev >= dIND2prev)
   ) // пересеклись 

или так (с Вашими скобками)

   if (
      ((dIND1curr >= dIND2curr) && (dIND1prev <= dIND2prev))
      || ((dIND1curr <= dIND2curr) && (dIND1prev >= dIND2prev))
   ) // пересеклись



 

Точно!

После расстановки скобок всё заработало. Я полагал неявно по своему опыту программирования, что операция AND (&&) имеет приоритет над OR (||), но здесь это правило неверно, приоритет операций, похоже, равный.

Учту на будущее.

Спасибо.

 

У нас приоритеты оговариваются особо в https://docs.mql4.com/ru/basis/operations/rules

Внимание: приоритет выполнения операций в языке MQL4 несколько отличается от приоритета, принятого в языке Си.

 

Да, в вашей системе ИЛИ имеет приоритет над И.

В С++ наоборот.

Лучше всего скобки ставить явно.

 
Я всегда ставлю скобки, чтобы не напрягать голову. Влияют ли скобки на скорость работы кода - не знаю, но зато голова не болит.
 

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

if((dIND1curr >dIND2curr) !=( dIND1prev > dIND2prev)) пересеклись

 

Замечательно!:)

 

Мне кажется, без знаков <= и >= (именно =) этот код может проглотить пересечение, если они совпали прямо в точке: dIND1curr == dIND2curr, а потом дальше разошлись. Или пара (dIND1prev, dIND2prev) строго <, >, а (dIND1curr, dIND2curr) может <=, >=.

Или не так?

 

Обратите внимание на использование "!=". Это неравенство позволяет сделать вывод о пересечении в случаях:

1. (<) != (>)
2. (<) != (=)
3. (>) != (<)
4. (>) != (=)
5. (=) != (>)
6. (=) != (<)


По-моему, очень красивое решение:)

 

Если эта тема интересна, то могу развить. Алгоритм пересечения основывается на правиле Куши, или лагранжа, не помню уже , из начала мат. анализа.
Правило такое, функция f(x) пересекла ось Х если f(x1)*f(x2) < 0 , x1<x2.
Зададим f(x) = ind1-ind2. х1 = dIND1prev - dIND2prev, x2 = dIND1cur - dIND2cur, как видно х1 < х2. И отсюда формула
if((dIND1prev - dIND2prev)*(dIND1cur - dIND2cur)<0) --> пересеклись. (Если комуто не ясно, пишите, присобачу рисунок.)
Ну а дальше каждый изменяет как ему нравится.
Единственная проблемма алгоритма - известен только факт пересечения, но неизвестно в какую сторону. Так что либо добавлять лишнюю строчку, либо писать алгоритм, чтоб не зависил от того, в какую сторону пересечется, что намного красивее и короче.