Довольно распространенная задача в скриптах узнать пересекается ли какое-то значение с другим. Например, мы можем захотеть проверить, пересекла ли 50-периодная скользящая средняя 10-периодную SMA. Или проверить не опустился ли Индекс относительной силы (RSI) ниже 30 или поднялся выше 70.
Как узнать, пересекаются ли значения друг с другом?
В TradingView есть три полезные функции, чтобы узнать пересечение значений:
- ta.crossover() сообщает нам, пересекается ли серия с другой серией или с некоторым фиксированным значением снизу вверх.
- ta.crossunder() сообщает нам, пересекается ли серия с другой серией или с некоторым фиксированным значением сверху вниз.
- ta.cross() сообщает, пересекается ли серия над или под другой серией или некоторым фиксированным значением.
Функция ta.crossover()
Встроенная функция ta.crossover (source1, source2) возвращает значение true, если на текущем баре source1 больше, чем значение source2, а на предыдущем баре значение source1 было меньше или равно значению source2.
Проиллюстрируем работу индикатора на графике:
Один и тот же индикатор мы нанесли на график и вынесли под ним.
Под графиком вы видите линию красного цвета — цена закрытия close, а синюю линию — ema(close, 50).
Каждая свечка, на которой цена close, больше чем close на предыдущей свечке, и цена пересекается с ЕМА50, снизу вверх, помечается ромбом.
Т.е. если close [1]
1 2 3 4 5 6 7 8 |
//@version=5 indicator(title='cross', overlay=true) plot (ta.ema(close, 50)) // выводим EMA50 синим цветом plot (close, color=color.red) // выводим close красным цветом x=ta.crossover(close, ta.ema(close, 50))// переменной х присваиваем true, если случилось пересечение ЕМА50 и close снизу вверх plotshape(x, style=shape.diamond, color=color.black) // помечаем свечи, где x=true черным ромбом |
ta.crossover() возвращает true, если:
- На предыдущем баре значение первого аргумента функции должно быть меньше или равно значению второго аргумента.
- А на текущем баре значение первого аргумента функции должно быть больше второго аргумента.
Рассмотрим другой пример, как определить пересекает ли переменный ряд фиксированный уровень.
Предположим, мы хотим узнать на каких барах индекс относительной силы (RSI) пересекает уровни 30 и 70, и пометить эти бары.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//@version=5 indicator(title='cross', overlay=false) rsiValue = ta.rsi(close, 14) // рассчитываем RSI в периодом 14 //закрасим фон свечей, на которых RSI пересекает уровень 70 снизу вверх фиолетовым цветом bgcolor(color=ta.crossover(rsiValue, 70) ? color.new(color.purple, transp=80) : na) //закрасим фон свечей, на которых RSI пересекает уровень 30 снизу вверх цветом лайм bgcolor(color=ta.crossover(rsiValue, 30) ? color.new(color.lime, transp=80) : na) plot(series=rsiValue, color=color.black)// рисуем RSI с периодом 14 черным цветом hline(price=30)//рисуем уровень 30 для RSI hline(price=50)//рисуем уровень 50 для RSI hline(price=70)//рисуем уровень 70 для RSI |
Функция ta.crossunder()
Встроенная функция ta.crossunder(source1, source2) возвращает значение true, если на текущем баре source1 меньше, чем значение source2, а на предыдущем баре значение source1 было больше или равно значению source2. Т.е. пересечение двух серий происходит сверху вниз.
Добавим в предыдущий индикатор функцию ta.crossunder:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//@version=5 indicator(title='cross', overlay=false) rsiValue = ta.rsi(close, 14) bgcolor(color=ta.crossover(rsiValue, 70) ? color.new(color.purple, transp=80) : na) bgcolor(color=ta.crossover(rsiValue, 30) ? color.new(color.lime, transp=80) : na) bgcolor(color=ta.crossunder(rsiValue, 70) ? color.new(color.yellow, transp=80) : na) bgcolor(color=ta.crossunder(rsiValue, 30) ? color.new(color.gray, transp=80) : na) plot(series=rsiValue, color=color.black) hline(price=30) hline(price=50) hline(price=70) |
Выделим дополнительно свечи, на которых RSI пересекает уровни 30 и 70 сверху вниз желтым и серым цветом:
ta.crossunder() возвращает true, если:
- На предыдущем баре значение первого аргумента функции должно быть больше или равно значению второго аргумента.
- А на текущем баре значение первого аргумента функции должно быть меньше второго аргумента.
Функция ta.cross() определяет любые пересечения
Когда направление пересечения не имеет значения, мы используем функцию ta.cross(). Она возвращает значение true, когда две серии или два значения пересекаются и false, если пересечение не случилось. Т.е. если произошло пересечение двух величин в любом направлении, функция возвращает true.
Функция ta.cross() может использоваться в 2-х вариантах:
- она определяет пересекаются ли 2 серии значений, например EMA50 и EMA100.
- пересекается ли серия значений и с фиксированной величиной, например RSI пересекла уровень 50.
Например, проверим пересекаются ли 2 скользящие средние
Первый способ использования ta.cross() состоит в том, чтобы посмотреть, не пересекаются ли некоторые ряды значений с другими.
Скажем, у нас есть индикатор, который строит две скользящие средние, и мы хотим выделить те бары, на которых скользящие средние пересекаются:
1 2 3 4 5 6 7 8 9 10 11 12 |
//@version=5 indicator(title='cross', overlay=true) MyEma= ta.ema(close,9) // переменная MyEma принимает серию значений EMA9 MySma=ta.sma(close, 100)// переменная MySma принимает серию значений EMA100 plot(MyEma, color=color.fuchsia)// рисуем MyEma (ЕМА9) цветом фукция plot(MySma, color=color.lime)// рисуем MySma (EMA100) цветом лайм s=ta.cross(MyEma,MySma) // переменной s присваивается значение true, //каждый раз, как происходит пересечение двух серий: MyEma и MySma plotchar(series=s, char = '🍑') //рисуем персик на каждом баре, где s=true, т.е. произошло пересечение |
Вот так выглядит график:
Приведем еще один пример: выделим свечи, на которых произошло пересечение ЕМА50 и цены 4320.
1 2 3 4 5 6 7 8 9 10 |
//@version=5 indicator(title='cross', overlay=true) MySma = ta.sma(close, 50) // переменная MyEma принимает серию значений EMA50 bgcolor (ta.cross(MySma, 4320) ? color.new(color=color.olive, transp=80) : na) // при помощи тернарного оператора проверяем условие: пересекаются ли MySma и 4320 // если факт пересечения проверяет функция ta.cross, если пересечение случилось, то в // bgcolor возвращаем значение color.new(оливковый цвет прозрачность 80), если нет, то na // bgcolor окрашивает фон свечи в указанный цвет plot(MySma, color=color.fuchsia, linewidth = 2) // рисуем MySma цветом фуксия и толщиной 2 |
Выделяем свечи на графике:
Как функции пересечения учитывают исторические и реальные бары
- ta.crossover(), ta.crossunder() и ta.cross() всегда сравнивают значение текущего бара со значением предыдущего бара.
- Когда бар является историческим баром, функции пересечения сравнивают значение бара при закрытии со значением закрытия предыдущего бара.
- Когда текущий бар является баром в реальном времени, функции сравнивают текущее обновление цены в реальном времени со значением закрытия предыдущего бара.
- Это также означает, что в режиме реального времени мы можем видеть пересечение во время первого обновления цены, но затем при следующем обновлении цены в реальном времени пересечение может исчезнуть, а затем появиться вновь.
- Одна вещь, которую функции пересечения не могут сделать, это сравнить текущий тик в реальном времени с предыдущим тиком.
Наталья 2023-11-12