Индикатор TVWAP Spread в Pine Script v5: Арбитраж в TradingView

Индикатор TVWAP Spread в Pine Script v5: Арбитраж в TradingView НАЛОГИ, ИП и САМОЗАНЯТОСТЬ
Полное руководство по созданию и применению индикатора TVWAP Spread (Time and Volume Weighted Average Price) на Pine Script v5 для профессионального арбитража в TradingView.
Суть: TVWAP Spread — это усовершенствованный инструмент для парного трейдинга, который объединяет временной распад (Time Decay) и объемы торгов обеих ног спреда для построения динамической средней линии и полос отклонения, минимизируя запаздывание по сравнению с классическими скользящими средними.

В количественном анализе (Quantitative Finance) классический парный арбитраж часто опирается на простые скользящие средние (SMA) или экспоненциальные средние (EMA) для определения средней линии спреда (Mean Reversion). Однако эти методы полностью игнорируют важнейший рыночный фактор — объём торгов (Volume) и динамику ликвидности на обеих ногах спреда.

Индикатор TVWAP Spread (Time and Volume Weighted Average Price) решает эту проблему. Он взвешивает исторические значения спреда не только по времени (с использованием линейного или экспоненциального затухания), но и по нормализованному совокупному объёму двух активов. Это позволяет получить высокоточную «справедливую» стоимость спреда, устойчивую к ложным пробоям на низких объёмах.

Для более глубокого анализа взаимосвязи активов перед запуском арбитража рекомендуем ознакомиться со статьей о Pine Script v5: Поиске Интрадей Раскорреляции BTC и DXY с ta.correlation.

Исходный код

Ниже представлен готовый код индикатора для TradingView на языке Pine Script v5. Скрипт автоматически рассчитывает динамическое соотношение активов (Beta) на основе ковариации, вычисляет взвешенный по времени и объёму спред, а также строит полосы стандартного отклонения для поиска точек входа.

//@version=5
indicator('Time & Volume Weighted Average Price (TVWAP) Spread', overlay=false, precision=6)

// Входные параметры
tickerA = input.symbol('BINANCE:BTCUSDT', title='Asset A (Leg 1)')
tickerB = input.symbol('BINANCE:ETHUSDT', title='Asset B (Leg 2)')
ratioType = input.string('Dynamic (Beta)', title='Ratio Type', options=['Dynamic (Beta)', 'Fixed', 'Constant (1:1)'])
fixedRatio = input.float(1.0, title='Fixed Ratio (A - Ratio * B)', minval=0.000001)
lookbackPeriod = input.int(20, title='Lookback Period (for Beta/TVWAP)', minval=2)
timeDecayType = input.string('Linear', title='Time Decay Type', options=['Linear', 'Exponential', 'None'])
stdDevMultiplier = input.float(2.0, title='StdDev Multiplier', minval=0.1, step=0.1)

// Запрос исторических данных по обоим активам
[closeA, volA] = request.security(tickerA, timeframe.period, [close, volume])
[closeB, volB] = request.security(tickerB, timeframe.period, [close, volume])

// Расчет коэффициента соотношения (Ratio)
var float ratio = 1.0
if ratioType == 'Dynamic (Beta)'
    avgA = ta.sma(closeA, lookbackPeriod)
    avgB = ta.sma(closeB, lookbackPeriod)
    cov = ta.sma((closeA - avgA) * (closeB - avgB), lookbackPeriod)
    varB = ta.variance(closeB, lookbackPeriod)
    ratio := varB != 0 ? cov / varB : 1.0
else if ratioType == 'Fixed'
    ratio := fixedRatio
else
    ratio := 1.0

// Расчет базового спреда
spread = closeA - (ratio * closeB)

// Нормализация объемов для исключения разницы в масштабах цен активов
normVolA = volA / ta.sma(volA, lookbackPeriod)
normVolB = volB / ta.sma(volB, lookbackPeriod)
combinedVol = (normVolA + normVolB) / 2.0

// Расчет TVWAP спреда во временном окне
float sumSpreadVolTime = 0.0
float sumVolTime = 0.0

for i = 0 to lookbackPeriod - 1
    float tWeight = 1.0
    if timeDecayType == 'Linear'
        tWeight := (lookbackPeriod - i) / float(lookbackPeriod)
    else if timeDecayType == 'Exponential'
        tWeight := math.exp(-i / (lookbackPeriod / 3.0))
    
    float v = combinedVol[i]
    float s = spread[i]
    
    if not na(v) and not na(s)
        float weight = v * tWeight
        sumSpreadVolTime += s * weight
        sumVolTime += weight

tvwap = sumVolTime != 0 ? sumSpreadVolTime / sumVolTime : spread

// Расчет полос стандартного отклонения относительно TVWAP
float sumSqDiff = 0.0
for i = 0 to lookbackPeriod - 1
    s = spread[i]
    if not na(s)
        sumSqDiff += math.pow(s - tvwap, 2)
stdDev = math.sqrt(sumSqDiff / lookbackPeriod)

upperBand = tvwap + stdDevMultiplier * stdDev
lowerBand = tvwap - stdDevMultiplier * stdDev

// Визуализация данных
plot(spread, color=color.blue, title='Spread', linewidth=2)
plot(tvwap, color=color.orange, title='TVWAP Line', linewidth=2)
p1 = plot(upperBand, color=color.red, title='Upper Band', style=plot.style_dashed)
p2 = plot(lowerBand, color=color.green, title='Lower Band', style=plot.style_dashed)
fill(p1, p2, color=color.new(color.purple, 95), title='Deviation Channel')

// Сигналы для алертов
alertcondition(ta.crossover(spread, upperBand), title='Spread Cross Upper Band', message='Спред переоценен относительно TVWAP (Шорт спреда)!')
alertcondition(ta.crossunder(spread, lowerBand), title='Spread Cross Lower Band', message='Спред недооценен относительно TVWAP (Лонг спреда)!')

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

  • tickerA / tickerB: Торговые инструменты, формирующие ноги спреда. Например, BINANCE:BTCUSDT и BINANCE:ETHUSDT.
  • ratioType: Метод расчета пропорции между активами. Dynamic (Beta) автоматически подстраивает хедж-коэффициент на основе ковариации активов, Fixed использует статичное значение, а Constant (1:1) подходит для фьючерсных спредов одного актива.
  • lookbackPeriod: Окно расчета (в барах) для вычисления Beta, нормализации объемов и глубины расчета TVWAP.
  • timeDecayType: Тип временного затухания весов. Linear линейно уменьшает вес старых баров, Exponential делает упор на последние бары по экспоненте, а None учитывает только объём.
  • stdDevMultiplier: Коэффициент ширины канала волатильности (аналог полос Боллинджера) для генерации торговых сигналов.

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

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

1. Откройте платформу TradingView и перейдите на любой график цен.

2. В нижней части экрана найдите и откройте вкладку Pine Editor.

3. Полностью удалите стандартный шаблон кода и вставьте скопированный выше код индикатора.

4. Нажмите кнопку Save (Сохранить), введите имя скрипта, а затем нажмите Add to chart (Добавить на график).

5. В настройках индикатора (иконка шестеренки на панели индикатора) укажите интересующие вас активы и выберите тип сглаживания.

Чтобы оценить эффективность сигналов на пробой полос TVWAP, вы можете использовать методы из статьи по созданию кастомной таблицы статистики в Pine Script v5: Winrate и Profit Factor.

А для выбора наиболее волатильных парных комбинаций отлично подойдет наш гайд по созданию Heatmap Волатильности Криптопар с Нормализованным ATR в Pine Script v5.

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