В Pine Script® теперь есть ассоциативные массивы

31 авг, 2023

Представляем новый инструмент для всех, кто работает с Pine — ассоциативные массивы (maps). Это коллекции, которые содержат данные в парах ключ-значение, т.е. позволяют пользователям попарно связывать элементы разных типов. В отличие от других доступных в Pine коллекций, вместо индекса, т.е. порядкового номера элемента в коллекции, в ассоциативном массиве скрипты быстро получают доступ к значениям, используя именно ключи.

Все функции, связанные с коллекциями map, хранит пространство имен map. Чтобы создать ассоциативный массив, используйте функцию map.new<key_type, value_type>():

//@variable A map containing `int` keys and  `line` values.
m = map.new<int, line>()

Ключи у такой структуры могут иметь любой фундаментальный тип (int, float, bool, string или color), а её значения могут быть любого типа, даже того, который пользователь объявил сам при помощи ключевого слова type.

После создания ассоциативного массива вы можете использовать с ним любую функцию из пространства имён map. Например, с помощью метода map.put() можно поместить в него пары ключ-значение, а получить значение, связанное с уникальным ключом, можно с помощью функции map.get(). Вы также можете сгенерировать массив из всех имеющихся ключей или значений, используя map.keys() или map.values(). Дополнительную информацию об этих новых коллекциях и связанных с ними функциях можно найти на странице Maps нашего Руководства пользователя.

В приведённом ниже примере мы создали скрипт, который использует ассоциативные массивы, чтобы окрашивать фон графика при изменении цен в рамках определённой сессии. В коллекции map хранится информация о времени закрытия и чистом изменении цен для каждого дня сессии, а затем на основе этого вычисляется отношение изменения цены текущей сессии к среднему изменению за определенное количество исторических сессий. Скрипт окрашивает фон графика на основе этого соотношения, используя содержимое ассоциативного массива цветов, и отображает значение соотношения в Окне данных:

//@version=5
indicator("Session change highlighter", overlay = true)

// Inputs
sessionInput = input.session("0800-1700", "Session")
timezone     = input.string("America/New_York", "Timezone")
length       = input.int(10, "Sessions to compare")

//@variable A map of `int` closing time keys and `float` price change values.
var data = map.new<int, float>()
//@variable A map of `string` keys and `color` values for calculating the `highlightColor`.
var colors = map.new<string, color>()

var float sessionOpen    = na
float     relativeChange = na
int       closeTime      = time_close("D", sessionInput, timezone)

// Put (`string`, `color`) pairs into the `colors` map on the first bar.
if barstate.isfirst
    colors.put("Purple", color.new(color.purple, 50))
    colors.put("Orange", color.new(color.orange, 50))
    colors.put("Yellow", color.new(color.yellow, 50))

if not na(closeTime)
    // Update the session's opening price.
    if na(closeTime[1])
        sessionOpen := open

    // Assign a new value to the `closeTime` key in the `data` map.
    data.put(closeTime, math.abs(close - sessionOpen) / sessionOpen)

    //@variable An `array` of price changes from each session in the `data` map.
    sessionHistory = data.values()
    //@variable The number of sessions included in the `data` map.
    dataSize = data.size()

    if dataSize >= length
        //@variable The average price change over `length` sessions.
        avgSessionChange = sessionHistory.slice(dataSize - length, dataSize).avg()
        relativeChange := data.get(closeTime) / avgSessionChange

//@variable Returns a color gradient based on the `relativeChange` using the values in the `colors` map.
highlightColor = switch
    relativeChange <= 1 => color.from_gradient(relativeChange, 0, 1, colors.get("Purple"), colors.get("Orange"))
    =>                     color.from_gradient(relativeChange, 1, 2, colors.get("Orange"), colors.get("Yellow"))

bgcolor(highlightColor, title = "Background highlight")
plot(relativeChange, "Relative Change Ratio", highlightColor, display = display.data_window)

Ниже мы приводим примеры опубликованных на TradingView скриптов, которые используют ассоциативные массивы:

Volume/Market Profile от SamRecio

Volume Profile от LuxAlgo

Historical Pattern Matcher от Trendoscope

Чтобы быть в курсе новых возможностей Pine Script®, следите за разделом Информация о релизах в руководстве пользователя. Учётная запись PineCoders также транслирует обновления в канале Squawk Box в Telegram, в Twitter и в публичном чате Pine Script® Q&A на TradingView.

Мы надеемся, это обновление будет вам полезно. Обязательно делитесь с нами своими отзывами и предложениями — мы делаем TradingView для вас, и нам важно знать, что вы думаете.

Команда TradingView

Look first Then leap

Мы создали TradingView, чтобы вы могли пользоваться самыми крутыми функциями.
Открыть график