Series хранит историю по свечам. Но иногда вы хотите сами выбирать собираемые значения, их порядок и момент удаления. Для этого подходит массив.

Что хранит массив?

Массив состоит из последовательных элементов. У каждого есть индекс, первый индекс ноль.

Элементы должны иметь один тип. Можно хранить числа или строки, но в числовой массив строки не помещают. Одинаковый тип не означает одинаковое значение: 100, 103 и 101 являются разными числами одного массива.

Если добавить 100, 103 и 101 в таком порядке, элемент 0 равен 100, элемент 1 равен 103, элемент 2 равен 101. Индекс означает место хранения, а не автоматически число свечей назад.

close[1] означает прошлое закрытие. array.get(prices, 1) означает второй элемент prices. Возраст зависит от заполнения массива.

Пространство имён array

array.new_float(0) создаёт пустой числовой массив. Ноль задаёт начальное число элементов, не цену.

ОперацияНазначение
array.push(prices, close)Добавить элемент в конец
array.size(prices)Получить число элементов
array.shift(prices)Удалить и вернуть первый элемент
array.get(prices, 0)Прочитать первый элемент
array.avg(prices)Усреднить сохранённые числа

Индекс array.get должен указывать на существующий элемент. При трёх элементах допустимы 0, 1, 2, но не 3.

Сохраните пять свежих цен

Создайте recent_prices.py:

"""
@pyne edge
"""
from pynecore import Persistent
from pynecore.lib import array, close, color, plot, script, ta


@script.indicator("Recent Prices", overlay=True)
def main():
    prices: Persistent[list[float]] = array.new_float(0)
    array.push(prices, close)
    if array.size(prices) > 5:
        array.shift(prices)
    stored_average = array.avg(prices)
    full_average = ta.sma(close, 5)
    plot(stored_average, "Stored average", color=color.blue, linewidth=2)
    plot(full_average, "SMA 5", color=color.orange)

list[float] задаёт тип числового массива. Persistent сохраняет его для следующей свечи. Создание не повторяется на каждой свече.

Работаем через array. Импортировать универсальную библиотеку Python или писать литерал списка не требуется.

Запустите на демонстрационных данных. Синяя линия усредняет уже собранные цены. На первой свече одна цена, на второй две, затем три и четыре. С пятой сохраняются пять элементов.

График recent_prices.py показывает синее среднее сохранённых цен и оранжевую SMA длиной пять.
Среднее собственного массива сравнивается с SMA полного окна из пяти элементов.

Порядок добавления и удаления

На шестой свече сначала добавляется шестое закрытие. Элементов шесть. Условие if истинно, первый старейший элемент удаляется. При расчёте уже остаются пять закрытий со второй по шестую свечу.

Начало массива здесь старейшая сохранённая цена, конец новейшая. При пяти элементах array.get(prices, 0) возвращает цену четырьмя свечами ранее, не текущую.

Новейшая цена находится по индексу array.size(prices) - 1. Число элементов на единицу больше последнего индекса из-за нумерации с нуля.

Частичное и полное окно

Вначале средние ведут себя по-разному. Массив усредняет реально собранные цены, даже четыре или меньше. ta.sma(close, 5) даёт результат лишь при полном окне.

С пятой свечи они усредняют одинаковые пять закрытий и должны совпадать в пределах точности чисел.

Среднее массива поэтому не является автоматической заменой готовой SMA. Правило начального окна определяете вы.

Зачем ограничивать размер?

Если только добавлять элемент на каждой свече, массив растёт вместе с данными и в конце хранит все обработанные закрытия.

Нам нужны последние пять, поэтому старые удаляются. В момент расчёта размер не больше пяти. В реальной задаче тоже определяйте, какие данные и как долго сохранять.

Попробуйте самостоятельно

Сохраняйте три цены вместо пяти, длину SMA тоже измените на три. Добавьте третьей линией старейший оставшийся элемент.

Решение

Условие удаления:

if array.size(prices) > 3:
    array.shift(prices)

Готовая средняя и новая линия:

full_average = ta.sma(close, 3)
oldest_price = array.get(prices, 0)
plot(oldest_price, "Oldest stored price", color=color.gray)

array.push всегда предшествует чтению, поэтому хотя бы один элемент уже есть. После заполнения до трёх старейшая цена отстоит на две свечи.

Запишите массив

Для трёх сохраняемых элементов и цен 100, 103, 101, 105 запишите содержимое после каждой свечи. На четвёртой должны остаться 103, 101, 105 именно в этом порядке.