VWMA с кастомными весами через матрицы в Pine Script v5

VWMA с кастомными весами через матрицы в Pine Script v5 Pine Script
Подробное руководство по расчету взвешенной по объему скользящей средней (VWMA) с кастомными весами, используя матричные операции в Pine Script v5. Включает исходный код и пошаговую инструкцию.
Суть: В этой статье мы подробно рассмотрим, как реализовать взвешенную по объему скользящую среднюю (VWMA) с полностью настраиваемыми весами, используя функционал матриц в Pine Script v5. Вы научитесь парсить пользовательские веса из строки, создавать матрицу для их хранения и применять эти веса для расчета VWMA, обеспечивая гибкость в анализе рынка.

Исходный код

Ниже представлен полный исходный код индикатора VWMA с кастомными весами, реализованного с использованием матриц в Pine Script v5. Этот скрипт позволяет вам задавать произвольные веса для каждого бара в окне расчета, что дает значительно большую гибкость по сравнению со стандартными скользящими средними. Мы используем матрицы для демонстрации работы с ними, хотя для одномерного набора весов можно было бы обойтись и массивами.


//@version=5
indicator('VWMA с Кастомными Весами (Матрицы)', shorttitle='VWMA Custom Weights', overlay=true)

// --- Входные параметры ---
int length = input.int(20, 'Длина VWMA', minval=1, tooltip='Количество баров для расчета VWMA.')
string customWeightsStr = input.string('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20', 'Кастомные Веса (через запятую)', tooltip='Введите веса для каждого бара в окне расчета, разделенные запятыми. Количество весов должно совпадать с параметром "Длина VWMA".')
string customWeightsOrder = input.string('Newest to Oldest', 'Порядок Весов', options=['Newest to Oldest', 'Oldest to Newest'], tooltip='Определяет, как применяются кастомные веса: от самого нового бара к самому старому, или наоборот.')

// --- Парсинг и валидация весов ---
// Используем 'var' для инициализации массива только один раз, но его содержимое обновляем на каждом баре
// для реакции на изменения пользовательского ввода.
var array weightsArray = array.new()
array.clear(weightsArray) // Очищаем массив на каждом баре

string[] weightsStrList = str.split(customWeightsStr, ',')
for s in weightsStrList
    float weight = str.tonumber(s)
    if na(weight)
        runtime.error('Ошибка: Некорректный формат весов. Убедитесь, что все значения являются числами.')
    array.add(weightsArray, weight)

// Проверка длины весов
if array.size(weightsArray) != length
    runtime.error('Ошибка: Количество кастомных весов (' + str.tostring(array.size(weightsArray)) + ') не совпадает с параметром "Длина VWMA" (' + str.tostring(length) + ').')

// --- Создание и заполнение матрицы весов ---
// Используем 'var' для инициализации матрицы только один раз.
// Если 'length' меняется, пересоздаем матрицу.
var matrix weightsMatrix = matrix.new(1, length)
if matrix.cols(weightsMatrix) != length // Проверяем, изменилась ли длина
    weightsMatrix := matrix.new(1, length) // Пересоздаем матрицу с новой длиной

// Заполняем матрицу весами из массива
for i = 0 to length - 1
    float weightVal = array.get(weightsArray, i)
    matrix.set(weightsMatrix, 0, i, weightVal)

// --- Расчет VWMA с кастомными весами ---
float weightedPriceVolumeSum = 0.0
float weightedVolumeSum = 0.0

// Проверяем, достаточно ли баров для расчета
if bar_index >= length - 1
    for i = 0 to length - 1
        // 'dataOffset' указывает, насколько далеко в прошлое мы смотрим (0 = текущий бар, length-1 = самый старый)
        int dataOffset = i 
        // 'weightIndex' указывает, какой вес из матрицы использовать
        int weightIndex = 0

        if customWeightsOrder == 'Newest to Oldest'
            // Вес 0 -> source[0], Вес 1 -> source[1], ..., Вес (length-1) -> source[length-1]
            weightIndex := i
        else // 'Oldest to Newest'
            // Вес 0 -> source[length-1], Вес 1 -> source[length-2], ..., Вес (length-1) -> source[0]
            weightIndex := length - 1 - i

        float currentWeight = matrix.get(weightsMatrix, 0, weightIndex)
        
        // Убедимся, что данные доступны и не являются NA
        if not na(close[dataOffset]) and not na(volume[dataOffset])
            weightedPriceVolumeSum += currentWeight * close[dataOffset] * volume[dataOffset]
            weightedVolumeSum += currentWeight * volume[dataOffset]

// Финальный расчет VWMA
float customVWMA = weightedVolumeSum != 0 ? weightedPriceVolumeSum / weightedVolumeSum : 0.0

// --- Отображение на графике ---
plot(customVWMA, 'Custom VWMA', color.blue, linewidth=2)

// --- Дополнительные функции (примеры использования) ---
// Вы можете использовать эту VWMA для создания торговых стратегий.
// Например, для определения тренда или фильтрации сигналов.
// Для более сложных стратегий и интеграции с внешними системами, 
// рассмотрите статью: Интеграция Pine Script v5 с Google Sheets: Webhook для логов сделок.
// Также, для анализа структуры рынка, может быть полезен Скрипт профиля рынка (Market Profile) с разделением на TPO в Pine Script v5.
// Если вы хотите добавить динамический трейлинг-стоп, ознакомьтесь с: 
// Динамический трейлинг-стоп по ATR в Pine Script v5: Инструкция.

Разбор параметров

  • length: Определяет количество баров, используемых для расчета VWMA. Это окно, в пределах которого будут применяться ваши кастомные веса.
  • customWeightsStr: Строка, в которой вы указываете свои кастомные веса, разделенные запятыми. Количество этих весов должно строго соответствовать значению параметра length. Например, если length равно 5, вы можете ввести ‘1,2,3,2,1’.
  • customWeightsOrder: Этот параметр позволяет выбрать порядок применения кастомных весов. Вы можете выбрать ‘Newest to Oldest’ (веса применяются от текущего бара к самым старым) или ‘Oldest to Newest’ (веса применяются от самых старых баров к текущему).

Как запустить

Чтобы использовать этот индикатор в TradingView, выполните следующие шаги:

  1. Откройте TradingView и перейдите на график нужного вам инструмента.
  2. Нажмите на кнопку ‘Pine Editor’ в нижней части экрана.
  3. Удалите весь существующий код в редакторе.
  4. Скопируйте предоставленный выше исходный код и вставьте его в ‘Pine Editor’.
  5. Нажмите кнопку ‘Добавить на график’ (‘Add to Chart’).
  6. Индикатор появится на вашем графике. Вы можете настроить его параметры (длину, кастомные веса и их порядок) через меню ‘Настройки’ индикатора на графике.

Оцените статью
FinFluct