Многие стратегии основаны на поиске максимумов и минимумов цены за определенный период времени, либо на скачке цены. Как же найти такие экстремальные ценовые бары при помощи скрипта? Давайте разберемся.
Ищем highest high и lowest low в TradingView Pinescript
В Pinescript есть 2 функции, помогающие найти самый высокий максимум и самый низкий минимум:
- Функция ta.highest() возвращает максимальное значение для указанных данных и количества баров. Может использоваться с 1 или 2 аргументами.
— ta.highest(source, length) — возвращает максимальное значение типа float в серии source, за указанное количество баров назад length.
— ta.highest(length) — возвращает максимальное значение типа float за указанное количество баров назад length - Функция ta.lowest() возвращает наименьшее значение для указанных данных и количества баров.
— ta.lowest(source, length) — возвращает максимальное значение типа float в серии source, за указанное количество баров назад length.
— ta.lowest(length) — возвращает максимальное значение типа float за указанное количество баров назад length
Функции ta.highest() и ta.lowest() работают с сериями значений. В TradingView большинство значений представляют собой серию, и эта серия имеет такую же длину, что и бары на графике. Т.к. функции ta.highest() и ta.lowest() привязаны к барам, то и работают они с данными привязанными к бару. Т.е. получить значения внутри бара мы не можем.
Мы можем использовать ta.highest(10), чтобы вычислить макс. значение цена за 10 баров, но НЕ можем с ее помощью узнать макс. значение RSI за последние 10 тиков в реальном времени.
Как получить максимальное значение при помощи функции ta.highest()
Функция ta.highest() принимает 1 или 2 аргумента: source и length.
Первый аргумент — это данные, из которых нужно получить наибольшее значение. Второй аргумент — количество баров для расчета.
Чтобы получить high за 20 баров назад нужно написать:
1 |
NewHigh = ta.highest(20) |
Второй способ:
1 |
NewHigh = ta.highest(high, 20) |
Мы можем использовать эту функцию не только для цен, но и для объемов:
1 |
hVolume = ta.highest(volume, 20) |
И для скользящих средних:
1 2 |
sma = ta.sma(close, 10) hSMA = ta.highest(sma, 20) |
Аналогично работает функция ta.lowest().
Учитывать ли текущий бар при расчете high и low?
Давайте посмотрим график макс и мин цен за 20 баров назад с учетом бара в реальном времени:
1 2 3 4 5 6 7 |
//@version=5 indicator(title="rsi", overlay=true) hHighs = ta.highest(high, 20) lLows = ta.lowest(low, 20) plot(hHighs, color=color.green, linewidth=2) plot(lLows, color=color.red, linewidth=2) |
Посмотрите, бары никогда не пересекают график макс и мин цены. Это происходит потому, что мы рассчитали эти экстремальные значения, включив данные бара, на котором рассчитывается скрипт. Единственное, что может сделать бар — это сравняться с самым высоким максимумом или самым низким минимумом, но не пересечь его.
Это может затруднить обнаружение новых максимумов и минимумов на графике.
Если наш код отслеживает новые максимумы или минимумы, мы должны проверить, равен ли текущий бар (==) самому высокому максимуму или самому низкому минимуму. То есть high == high(high, 20) будет истинным, когда цены достигнут нового 20-барного максимума.
Если мы не хотим включать текущий бар в расчет максимальной и минимальной цен, то можем использовать оператор обращения к истории, тем самым не учитывать текущий бар:
1 2 3 4 |
hHighs = ta.highest(high, 20)[1] lLows = ta.lowest(low, 20)[1] plot(hHighs, color=color.green, linewidth=2) plot(lLows, color=color.red, linewidth=2) |
Так мы сможем обнаружить новые high и low:
Этот способ расчета имеет следующие особенности:
- ценовые прорывы, новые high и low легче заметить на графике.
- когда наш код отслеживает новые максимумы или минимумы, мы должны проверить, больше ли максимум текущего бара, чем самый высокий максимум и меньше ли минимум, чем самый низкий минимум. То есть low < low(low, 20)[1] будет истинным всякий раз, когда цены упадут ниже 20-барного минимального минимума.
Пример индикатора: найдем самый высокий максимум и самый низкий минимум
Приведенный ниже скрипт строит 30-барный самый высокий максимум и самый низкий минимум.
Мы рассчитываем эти экстремальные значения, чтобы они не включали данные текущего бара. Таким образом, мы можем легко определить, когда бары прорываются выше самого высокого максимума и когда цены падают ниже самого низкого минимума.
Вот как готовый индикатор выглядит на графике:
1 2 3 4 5 6 7 8 9 10 11 |
//@version=5 indicator(title='High_Low', overlay=true) Highs = ta.highest(high, 30)[1] Lows = ta.lowest(low, 30)[1] plot(series=Highs, color=color.gray, linewidth=2) plot(series=Lows, color=color.fuchsia, linewidth=2) bgColour = high > Highs ? color.new(color.gray, transp=70) : low < Lows ? color.new(color.fuchsia, transp=70) : na bgcolor(color=bgColour) |
Заключение:
- При помощи функций ta.highest() и ta.lowest() мы можем найти самую высокую и низкую цену за указанное количество баров.
- По умолчанию функции рассчитываются с учетом текущего бара. Это может быть проблемой, если мы хотим увидеть, пересекает ли текущий бар экстремальный максимум или минимум.
- К счастью, мы можем использовать оператор обращения к истории ([]) со значением 1 после ta.highest() и ta.lowest(). Когда мы это делаем, то функции вычисляют предыдущие бары, не включая данные текущего бара.
Яков 2023-01-13
// © Jakov1980
//@version=5
indicator(title='close price', overlay=true)
period_1 = 1
period_2 = 2
while close[period_1] > close[period_2]
period_1 := period_1 + 1
period_2 := period_2 + 1
plotchar(bar_index[period_1], char='🍤', size=size.tiny)
Что не так с этим кодом. Хотел текущие минимумы и максимумы отметить. Помогите разобраться