На криптовалютном рынке цены очень хаотично движутся, прогнозы сбываются не каждый раз (особенно если вы полагаетесь на мнение инфлов), а новостной фон подливает масла в огонь. В этом хаосе многие пытаются найти хоть какие-то закономерности, опираясь не на догадки, а на измеримые данные.
Сегодня мы как раз и займемся таким анализом — разберем популярный в узких кругах индикатор Hash Ribbons. Но сделаем это не как трейдеры в поисках луд успеха, а разберем, что там под условно капотом.
Важный дисклеймер: Эта статья — исключительно техническое и математическое исследование. Это не финансовая рекомендация, не торговый совет и не попытка предсказать будущее. Моя цель — разобрать логику и код конкретного инструмента, а не предложить готовую стратегию. Любые действия на финансовых рынках сопряжены с высоким риском:).
Итак, наша задача — взять экономическую гипотезу, посмотреть, как ее формализовали с помощью математики, и как в итоге она превратилась в код на Pine Script, который может запустить любой желающий.
Концепция.
Чтобы понять логику индикатора, для начала нужно разобраться с двумя вещами: что такое хешрейт и кто такие майнеры.
Если говорить максимально просто, хешрейт (Hash Rate) — это общая вычислительная мощность всех устройств, которые участвуют в работе сети Bitcoin. Это своего рода "пульс" сети. Чем он выше, тем больше вычислительных ресурсов задействовано, тем безопаснее и стабильнее сеть.
Майнеры — это те, кто предоставляет эти вычислительные мощности. Для них это бизнес: они тратят деньги на оборудование и электричество, а взамен получают вознаграждение в виде новых биткоинов и комиссий за транзакции. И как в любом бизнесе, здесь есть своя точка безубыточности.
В этом и кроется суть гипотезы, на которой построен индикатор Hash Ribbons:
Майнеры несут реальные расходы. Главная статья — электричество.
Когда рыночная цена Bitcoin падает, доход от майнинга снижается.
Если цена падает ниже точки безубыточности, наименее эффективные майнеры (те, у кого дорогое электричество или устаревшее оборудование) начинают работать в убыток.
Чтобы остановить потери, они отключают свои устройства. Этот процесс массового отключения и называется «капитуляцией майнеров».
С точки зрения данных, капитуляция майнеров выглядит как заметное и устойчивое падение общего хешрейта сети. Автор индикатора, Чарльз Эдвардс, предположил, что момент, когда майнеры прекращают капитулировать и начинают снова включать оборудование (хешрейт восстанавливается), исторически был благоприятным для покупки актива.
Мы не будем оценивать прибыльность этой гипотезы. Мы просто примем ее как данность и посмотрим, как ее можно измерить и превратить в алгоритм.
Для начала взглянем на исходный код индикатора. Он написан на Pine Script — языке для платформы TradingView. Вот так выглядит его "шапка" и основные настраиваемые параметры:
//@version=5
indicator('Hash Ribbons (Capriole Investments)', overlay=false)
// INPUTS - Пользовательские настройки
type = input.string('Ribbons', options=['Ribbons', 'Oscillator'], title='Plot Type')
// Позволяет переключать вид: "ленты" или осциллятор
len_s = input(30, 'Hash Rate Short SMA (days).')
// Период для короткой (быстрой) скользящей средней хешрейта. По умолчанию 30 дней.
len_l = input(60, 'Hash Rate Long SMA (days).')
// Период для длинной (медленной) скользящей средней. По умолчанию 60 дней.
signals = input(true, 'Plot Signals')
// Включить/выключить отображение сигналов на графике (кружочки и надписи).
plot_halvings = input(true, 'Plot Halvings')
// Показывать ли на графике вертикальные линии в моменты халвингов Bitcoin.
raw = input(false, 'Plot Raw Hash Rate')
// Отображать "сырой" график хешрейта вместо индикатора.
source = input.string('INTOTHEBLOCK:BTC_HASHRATE', options=['QUANDL:BCHAIN/HRATE', 'INTOTHEBLOCK:BTC_HASHRATE'], title='Source Hash Rate')
// Источник данных. Позволяет выбрать, откуда брать информацию о хешрейте.
Как видим, в основе лежат всего несколько ключевых параметров, главные из которых — это периоды для двух скользящих средних. Именно они и являются ядром математической модели индикатора. В следующей части мы разберем, как они работают.

Математическая модель.
Итак, у нас есть гипотеза и поток "сырых" данных — ежедневные значения хешрейта. Проблема в том, что эти данные "шумные": хешрейт может колебаться день ко дню по множеству причин. Нам нужно отделить значимый тренд от этого шума. Как это сделать?
Самый простой и проверенный способ в анализе временных рядов — скользящие средние (Moving Averages).
Если вы не сталкивались с ними, представьте, что вы анализируете среднюю температуру. Можно смотреть на температуру каждый день, но она будет скакать. А можно посчитать среднюю за последние 30 дней и среднюю за последние 60 дней. Сравнивая эти два сглаженных значения, вы сможете понять общий тренд: становится в целом холоднее или теплее, игнорируя при этом разовые потепления или похолодания.
Индикатор Hash Ribbons использует тот же подход, применяя простую скользящую среднюю (SMA) к данным о хешрейте. В коде это выглядит так:
// ЗАПРОС ДАННЫХ И РАСЧЕТ SMA
// Запрашиваем дневные данные о хешрейте из указанного источника.
// lookahead=barmerge.lookahead_on нужен, чтобы на текущем, еще не закрытом дневном баре, использовать данные за вчера. Это защищает от "перерисовки" индикатора в реальном времени.
live_HR_short = request.security(source, 'D', ta.sma(close, len_s), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
live_HR_long = request.security(source, 'D', ta.sma(close, len_l), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
// Для исторических данных "заглядывание вперед" не нужно
hist_HR_short = request.security(source, 'D', ta.sma(close, len_s), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
hist_HR_long = request.security(source, 'D', ta.sma(close, len_l), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
// ... далее идет код для склейки исторических и real-time данных ...
// В переменные HR_short и HR_long попадают итоговые значения SMA
HR_short := barstate.isrealtime ? live_HR_short : hist_HR_short
HR_long := barstate.isrealtime ? live_HR_long : hist_HR_long
Здесь len_s и len_l — это те самые периоды (30 и 60 дней по умолчанию), которые мы видели в настройках. ta.sma(close, len_s) — это встроенная функция Pine Script, которая и вычисляет среднее значение хешрейта за указанный период.
Теперь у нас есть две линии:
1. Быстрая SMA (30 дней) — более чувствительна к свежим изменениям.
2. Медленная SMA (60 дней) — более инертная, показывает долгосрочный тренд.
Именно взаимодействие этих двух линий и формирует логику индикатора):
Начало «капитуляции»: Быстрая SMA пересекает медленную сверху вниз. Это означает, что краткосрочная тенденция стала хуже долгосрочной. Математически это и есть наш сигнал о начале проблем у майнеров.
Конец «капитуляции» (Восстановление): Быстрая SMA возвращается обратно и пересекает медленную снизу вверх. Тренд меняется на позитивный, хешрейт восстанавливается.
В коде эти моменты отслеживаются с помощью специальных функций:
// ОПРЕДЕЛЕНИЕ СОСТОЯНИЙ
// ta.crossunder() возвращает true в тот момент, когда первая линия пересекает вторую сверху вниз.
capitulation = ta.crossunder(HR_short, HR_long)
// ta.crossover() делает то же самое для пересечения снизу вверх.
recovered = ta.crossover(HR_short, HR_long)
// Также вводится промежуточное состояние, когда майнеры находятся в процессе капитуляции
miner_capitulation = HR_short < HR_long
Таким образом, мы формализовали нашу гипотезу. "Капитуляция майнеров" — это больше не абстрактное понятие, а конкретное, измеримое состояние системы: HR_short < HR_long.
Но это еще не все. Индикатор не просто фиксирует эти пересечения, а строит на их основе более сложный, композитный сигнал.
Композитный сигнал.
Автор индикатора пошел дальше и добавил второе условие, которое завязано уже не на хешрейт, а на ценовой моментум. Идея в том, чтобы совместить два события: восстановление хешрейта и начало роста цены.
Для оценки ценового моментума используются те же SMA, но уже от цены закрытия (close) и с периодами 10 и 20 дней (s10 и s20).
Финальная логика, формирующая сигнал "Buy", выглядит так:
// ЛОГИКА СИГНАЛА "BUY"
buy = false
buy := ta.crossover(s10, s20) and ta.barssince(recovered) < ta.barssince(ta.crossunder(s10, s20)) and ta.barssince(recovered) < ta.barssince(capitulation) or s10 > s20 and ta.crossover(HR_short, HR_long)
Это сложное логическое выражение, которое, по сути, проверяет два сценария:
Сначала восстановился хешрейт, и только после этого начала расти цена.
Цена уже находится в растущем тренде (s10 > s20), и в этот момент происходит восстановление хешрейта, подтверждая позитивный настрой.
Таким образом, то, что называется сигналом "Buy", на самом деле является композитным событием, требующим совпадения нескольких факторов.
Визуализация.
Помимо основной логики, в коде есть несколько полезных дополнений, отвечающих за визуализацию и удобство использования.
1. Отрисовка сигналов
Для отображения всех ключевых событий (начало капитуляции, восстановление, покупка) на графике используется функция plotshape. Она рисует цветные кружки в нужные моменты времени.
// PLOT - SIGNALS
// Рисуем серый круг в момент начала капитуляции
plotshape(signals ? capitulation : na, style=shape.circle, location=location.top, color=color.new(color.gray, 50), size=size.normal, text='Capitulation')
// ... (аналогично для других состояний) ...
// Рисуем синий круг для сигнала "Buy"
plotshape(signals ? buy_plot : na, style=shape.circle, location=location.top, color=color.new(color.blue, 0), size=size.normal, text='Buy')
2. Режим осциллятора
В настройках индикатора можно переключить вид с "лент" на "осциллятор". Это просто альтернативный способ визуализации. Вместо двух линий он показывает гистограмму, отражающую разницу между быстрой и медленной SMA в процентах.
// OSCILLATOR
delta = HR_short - HR_long
diff = delta / HR_short * 100
// PLOT - OSCILLATOR
plot(type == 'Oscillator' ? diff : na, style=plot.style_columns, color=diff < 0 ? color.red : color.blue, title='Oscillator')
Если гистограмма ниже нуля — хешрейт в "зоне капитуляции", если выше — в "зоне роста".
3. Отображение халвингов
Индикатор также умеет отмечать на графике даты халвингов Bitcoin — событий, когда награда майнерам сокращается вдвое. Это чисто визуальная метка, она не влияет на расчеты, но помогает сориентироваться в макроциклах рынка.
// HALVINGS
halving_1 = timestamp(2012, 11, 28, 0, 0)
// ... (даты для 2-го и 3-го халвингов) ...
// Закрашиваем фон красным в районе даты халвинга
bgcolor(h1_range and plot_halvings ? color.new(color.red,20) : na)
Заключение
Мы с вами проделали путь от абстрактной экономической гипотезы до ее конкретной реализации в коде. Мы увидели, как с помощью простого, но эффективного аппарата скользящих средних можно формализовать идею о "капитуляции майнеров" и превратить ее в измеримый и визуализируемый алгоритм.
И здесь я хочу еще раз, в последний раз, вернуться к тому, с чего мы начали.
Это не алгоритм для предсказаний. Это всего лишь одна из сотен моделей, которая пытается найти логику в хаосе, и работает с числами. Рынок может и будет вести себя иррационально, и любой, даже самый продуманный алгоритм, может давать сбои. Данная статья — это образовательное упражнение, демонстрация того, как можно применять инженерный подход к анализу рыночных данных. Не более того.
А теперь вопрос к вам. Какие еще неценовые, фундаментальные метрики (on-chain данные) вы считаете интересными для анализа с точки зрения программирования? Сталкивались ли вы с похожими задачами моделирования?
Вступайте в наш чат, 24/7 рабочая атмосфера, разбираем рыночные сетапы вместе с комьнити, так же разбираем ошибки, помогаем друг другу выходить из плохих сделок ссылка на чат (ссылка). Если статья показалась вам интересной, то буду благодарен за подписку на тг канал (ссылка).
Делитесь идеями в комментариях!
Junecat
Вот хорошо, когда "картинка для привлечения внимания" сделана человеком, а не сгенериована. По крайней мере, две видимые простым глазом ошибки на ней говория о человеческом происхождении...