← К каталогу
Исходный код · ID 4677

Двойной линейный регрессионный канал

double linear regression channel.pine
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Данный индикатор отображает на графике TradingView два независимых линейных регрессионных канала. Каждый канал строится на основе расчёта линейной регрессии и стандартного отклонения, формируя центральную линию и границы отклонений на уровнях ±1σ и ±2σ.

Каждый канал поддерживает автоматический подбор длины на основе анализа объёма — выбирается значение, при котором объём достигает максимума в заданном диапазоне. Пользователь может также вручную задавать параметры длины и управлять продлением линий канала влево и вправо от последнего бара.

Индикатор позволяет отображать значения R² (коэффициент корреляции Пирсона) для каждого канала в виде меток на графике, что помогает оценить качество линейной аппроксимации. Все визуальные элементы — цвета линий, их толщина, видимость каналов — настраиваются индивидуально для каждого из двух каналов.

Настройки программы

НастройкаОписание
enable1 Включение или отключение отображения первого канала.
minLen1 Минимальная длина расчётного периода для автоматического подбора первого канала.
maxLen1 Максимальная длина расчётного периода для автоматического подбора первого канала.
src1 Источник данных для расчёта первого канала.
showPearson1 Отображение значения R² и длины первого канала в виде метки на графике.
extendLeft1 Продление линий первого канала влево от начала расчётного диапазона.
extendRight1 Продление линий первого канала вправо от конца расчётного диапазона.
width1 Толщина линий первого канала.
colorMid1 Цвет средней линии первого канала.
colorOut1 Цвет граничных линий ±1σ первого канала.
colorOut2_1 Цвет граничных линий ±2σ первого канала.
enable2 Включение или отключение отображения второго канала.
minLen2 Минимальная длина расчётного периода для автоматического подбора второго канала.
maxLen2 Максимальная длина расчётного периода для автоматического подбора второго канала.
src2 Источник данных для расчёта второго канала.
showPearson2 Отображение значения R² и длины второго канала в виде метки на графике.
extendLeft2 Продление линий второго канала влево от начала расчётного диапазона.
extendRight2 Продление линий второго канала вправо от конца расчётного диапазона.
width2 Толщина линий второго канала.
colorMid2 Цвет средней линии второго канала.
colorOut2 Цвет граничных линий ±1σ второго канала.
colorOut2_2 Цвет граничных линий ±2σ второго канала.
Получить полный код

Поиск по коду файла

indicator('<[Двойной линейный регрессионный канал]>', shorttitle = '<[Двойной линейный регрессионный канал]>', overlay = true)

_linreg_slope(source, length) =>
    max_bars_back(source, 600)
    if not barstate.islast or length <= 1
        [float(na), float(na), float(na)]
    else
        sumX = 0.0
        sumY = 0.0
        sumXSqr = 0.0
        sumXY = 0.0
        for i = 0 to length - 1 by 1
            val = source[i]
            per = i + 1.0
            sumX := sumX + per
            sumY := sumY + val
            sumXSqr := sumXSqr + per * per
            sumXY := sumXY + val * per
            sumXY
        slope = (length * sumXY - sumX * sumY) / (length * sumXSqr - sumX * sumX)
        average = sumY / length
        intercept = average - slope * sumX / length + slope
        [slope, average, intercept]

_linreg_dev(source, length, slope, average, intercept) =>
    max_bars_back(source, 2000)
    upDev = 0.0
    dnDev = 0.0
    stdDevAcc = 0.0
    dsxx = 0.0
    dsyy = 0.0
    dsxy = 0.0
    periods = length - 1
    daY = intercept + slope * periods / 2
    val = intercept
    for j = 0 to periods by 1
        price = high[j] - val
        if price > upDev
            upDev := price
            upDev
        price := val - low[j]
        if price > dnDev
            dnDev := price
            dnDev
        price := source[j]
        dxt = price - average
        dyt = val - daY
        price := price - val
        stdDevAcc := stdDevAcc + price * price
        dsxx := dsxx + dxt * dxt
        dsyy := dsyy + dyt * dyt
        dsxy := dsxy + dxt * dyt
        val := val + slope
        val
    stdDev = math.sqrt(stdDevAcc / (periods == 0 ? 1 : periods))
    pearsonR = dsxx == 0 or dsyy == 0 ? 0 : dsxy / math.sqrt(dsxx * dsyy)
    [stdDev, pearsonR, upDev, dnDev]

f_data_linreg_channel(src, length) =>
    [s, a, i] = _linreg_slope(src, length)
    [stdDev, pearsonR, upDev, dnDev] = _linreg_dev(src, length, s, a, i)
    startPrice = i + s * (length - 1)
    endPrice = i
    [startPrice, endPrice, stdDev, pearsonR]

f_data_auto_linreg_channel(src, _min, _len) =>
    var int autoLength = _min
    int volLen = ta.barssince(volume == ta.highest(volume, _len - 1))
    if not na(volLen) and volLen >= _min and volLen < _len
        autoLength := volLen
        autoLength

    [startPrice1, endPrice1, stdDev1, pearsonR1] = f_data_linreg_channel(src, autoLength)
    [startPrice2, endPrice2, stdDev2, pearsonR2] = f_data_linreg_channel(src, _min)

    startPrice = pearsonR1 > pearsonR2 ? startPrice1 : startPrice2
    endPrice = pearsonR1 > pearsonR2 ? endPrice1 : endPrice2
    stdDev = pearsonR1 > pearsonR2 ? stdDev1 : stdDev2
    pearsonR = pearsonR1 > pearsonR2 ? pearsonR1 : pearsonR2
    [startPrice, endPrice, stdDev, pearsonR, pearsonR1 > pearsonR2 ? autoLength : _min]

group1 = 'Первый канал - Настройки'
enable1 = input.bool(true, 'Вкл/Выкл Канал 1', group = group1)
minLen1 = input.int(20, 'Минимальная длина 1', minval = 1, maxval = 4000, group = group1)
maxLen1 = input.int(70, 'Максимальная длина 1', minval = 5, maxval = 500, group = group1)
src1 = input.source(close, 'Источник 1', group = group1)
showPearson1 = input.bool(false, 'Показывать R² 1', group = group1)
extendLeft1 = input.bool(false, 'Продлевать влево 1', group = group1)
extendRight1 = input.bool(false, 'Продлевать вправо 1', group = group1)
width1 = input.int(2, 'Толщина линий 1', minval = 1, maxval = 5, group = group1)
extendStyle1 = extendLeft1 and extendRight1 ? extend.both : extendLeft1 ? extend.left : extendRight1 ? extend.right : extend.none
colorMid1 = input.color(#ffeb3b, 'Цвет средней 1', group = group1)
colorOut1 = input.color(#00ff0a, 'Цвет 1σ 1', group = group1)
colorOut2_1 = input.color(#ff0000, 'Цвет 2σ 1', group = group1)

[start1, end1, dev1, r1, len1] = f_data_auto_linreg_channel(src1, minLen1, maxLen1)
upper1_1 = start1 + dev1
upper2_1 = start1 + 2 * dev1
lower1_1 = start1 - dev1
lower2_1 = start1 - 2 * dev1

var line base1 = line.new(bar_index - len1 + 1, start1, bar_index, end1, width = width1, extend = extendStyle1, color = enable1 ? color.new(colorMid1, 50) : na)
var line up1_1 = line.new(bar_index - len1 + 1, upper1_1, bar_index, end1 + dev1, width = width1, extend = extendStyle1, color = enable1 ? color.new(colorOut1, 90) : na)
var line low1_1 = line.new(bar_index - len1 + 1, lower1_1, bar_index, end1 - dev1, width = width1, extend = extendStyle1, color = enable1 ? color.new(colorOut1, 90) : na)
var line up2_1 = line

Показано первые 50% кода (символов: 7037)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
703,70₽ ≈ $8.62