Your Backtest Is Lying: How Cohort Data Exposes the Gaps
By @CoinMarketMan - 14-Jul-2026
Ваш бектест бреше: як дані когорт виявляють прогалини
Ви запустили бектест. Відкритий інтерес різко зріс, фандинг перевернувся в мінус, сигнал спрацював, а симульований P&L повернувся позитивним. Sharpe виглядає чисто. Відсоток виграшів тримається на 200 угодах. Ви запускаєте стратегію в живу торгівлю, і вже за два тижні вона починає зливатися.
Проблема рідко в самому сигналі. Проблема в тому, що сигнал не може вам розповісти. Перевертання фандингу залишається перевертанням фандингу незалежно від того, чи це гаманці з позитивним PnL за весь час, чи гаманці, яких планомірно ліквідують. Стрибок OI виглядає однаково і тоді, коли його рухають когорти Smart Money, що нарощують позицію, і тоді, коли Giga-Rekt гаманці подвоюють ставку на програшний тезис. Ваш бектест ставився до обох сценаріїв однаково, бо не мав способу їх розрізнити.
Саме цю прогалину заповнюють дані когорт. HyperTracker класифікує кожен гаманець на Hyperliquid в одну з 16 поведінкових когорт: 8 за розміром рахунку (від Shrimp до Leviathan) і 8 за всіма часами PnL (від Money Printer до Giga-Rekt). Коли ви накладаєте цю класифікацію на бектест, ви перестаєте запитувати «чи спрацював сигнал?» і починаєте запитувати «хто стоїть по кожен бік цієї угоди?»
Сліпа пляма стандартних бектестів
Більшість бектестів на Hyperliquid використовують ціну, обсяг, відкритий інтерес і ставки фандингу. Це вхідні дані, доступні через публічний API біржі, і їх достатньо для побудови напрямних сигналів, які добре тестуються ізольовано. Проблема виникає, коли ви дивитеся на те, що вони пропускають.
Розглянемо простий лонговий сигнал: OI різко зростає, поки фандинг залишається плоским або злегка негативним. Стандартна інтерпретація: нові гроші заходять у лонги без надмірної плати за кері, що вказує на справжню переконаність, а не на спекуляцію з плечем. У бектесті цей паттерн дає скромно позитивне перевагу на сотнях угод.
Але агрегований OI не каже вам, чию переконаність ви бачите. Якщо зростання OI йде переважно від когорти Money Printer (гаманці з $1M+ прибутку за весь час, segment ID 8) і когорти Smart Money ($100K-$1M прибутку, segment ID 9), ви, мабуть, спостерігаєте обізнане позиціонування. Якщо той самий стрибок OI рухають переважно Giga-Rekt гаманці (нижче -$1M за весь час, segment ID 15) і Full Rekt гаманці (від -$1M до -$100K, segment ID 14), то «переконаність» схожіше на капітуляцію або торгівлю помсти.
Обидва сценарії дають однаковий графік OI. Обидва запускають однаковий сигнал. Але очікуваний результат суттєво різниться, бо якість капіталу за рухом має значення.
Що охоплюють історичні дані (і де вони закінчуються)
Перш ніж додавати контекст когорт у бектест, потрібно розуміти, які дані насправді доступні і наскільки далеко в минуле вони сягають. Історичні ендпоінти HyperTracker мають різні вікна ретроспективи залежно від типу даних.
Найглибша історія у позиціях. Знімки індивідуальних позицій сягають приблизно 10 місяців назад до квітня 2025 року, що дає вихідний матеріал для реконструкції ринку в будь-який момент часу. Філи (записи індивідуальних угод) охоплюють близько 6,5 місяців з липня 2025 року і придатні для побудови цінових рядів та аналізу виконання на рівні угоди.
Дані, специфічні для когорт, мають коротше вікно. Метрики когорт по монетам, ендпоінт, що показує позиціонування кожного сегмента по конкретному активу, пропонує приблизно 4 тижні ретроспективи на один API-виклик. Це ключове обмеження для бектестингу на основі когорт: ви не можете ретроактивно запитати, що когорта Money Printer робила з BTC шість місяців тому, якщо не збирали ці дані на той час.
Упередження когорти (cohort bias), що вимірює напрямний нахил по всіх активах для заданої когорти, охоплює ще менший відрізок: ковзне 12-годинне вікно. Знімки ордерів (стопи, тейк-профіти, кластери лімітних ордерів) сягають приблизно 3 тижні назад. Теплові карти та таблиці лідерів актуальні лише на поточний момент, без жодного архіву.
Порада для розробників: практичний висновок простий. Якщо хочете запускати бектести з урахуванням когорт із достатньою глибиною, починайте збирати дані прямо зараз. Крон-завдання, що викликає ендпоінт метрик когорт кожні 5 хвилин і пише відповіді до бази даних, дасть вам місяць даних за місяць, три місяці за три місяці і так далі. 4-тижневе вікно ретроспективи API є ковзним, тому більш ранні дані виходять за межі вибірки, якщо ви не зберігаєте їх самостійно.
Накладання фільтрів когорт на існуючий бектест
Перебудовувати рушій бектесту з нуля не потрібно. Найчистіший підхід: додати фільтр когорти як пост-сигнальний шлюз. Ваш існуючий сигнал генерує кандидатів, фільтр когорти вирішує, які кандидати виконувати, а які пропускати.
Фільтр працює в три етапи:
Етап 1: Спрацьовує базовий сигнал. Ваша існуюча логіка, якою б вона не була, виявляє торгову можливість. Стрибок OI, дивергенція фандингу, пробій ціни, перетин ковзних середніх. Сигнал не змінюється.
Етап 2: Запит когорти. У момент спрацьовування сигналу робіть запит метрик когорт для відповідного активу. Ви дивитеся на дві речі: які когорти позиціоновані в напрямку вашого сигналу і які позиціоновані проти нього.
Етап 3: Шлюз переконаності. Якщо історично прибуткові когорти (Money Printer, Smart Money, Consistent Grinder) узгоджені з напрямком вашого сигналу, виконуйте угоду. Якщо основними рушіями є історично збиткові когорти (Giga-Rekt, Full Rekt, Semi-Rekt), а прибуткові когорти позиціоновані проти вас, пропускайте. Якщо картина змішана, зменшуйте розмір або взагалі відмовляйтеся від угоди.
Ось як виглядає логіка запиту та шлюзу на практиці:
import requests
BASE_URL = "https://ht-api.coinmarketman.com/api/external"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
# PnL-based cohort segment IDs
PROFITABLE = [8, 9, 10] # Money Printer, Smart Money, Consistent Grinder
UNPROFITABLE = [13, 14, 15] # Semi-Rekt, Full Rekt, Giga-Rekt
def fetch_cohort_metrics(coin):
resp = requests.get(
f"{BASE_URL}/cohort/metrics",
headers=HEADERS,
params={"coin": coin}
)
resp.raise_for_status()
return resp.json()
def cohort_conviction(metrics, signal_direction):
"""
Returns 'pass', 'skip', or 'reduce' based on
whether profitable cohorts align with the signal.
signal_direction: 'long' or 'short'
"""
profitable_net = 0
unprofitable_net = 0
for cohort in metrics:
seg = cohort.get("segmentId")
long_n = cohort.get("longNotional", 0)
short_n = cohort.get("shortNotional", 0)
net = long_n - short_n # positive = net long
if seg in PROFITABLE:
profitable_net += net
elif seg in UNPROFITABLE:
unprofitable_net += net
# Determine alignment
if signal_direction == "long":
aligned = profitable_net > 0 and unprofitable_net < profitable_net
opposed = profitable_net < 0
else:
aligned = profitable_net < 0 and unprofitable_net > profitable_net
opposed = profitable_net > 0
if aligned:
return "pass"
elif opposed:
return "skip"
else:
return "reduce"
У живому циклі бектесту ви викликаєте cohort_conviction() щоразу, коли спрацьовує сигнал, і використовуєте результат для управління виконанням. Угоди з результатом «pass» виконуються в повному розмірі. Угоди з результатом «reduce» виконуються у частковому розмірі (ви самі обираєте частку). Угоди з результатом «skip» не виконуються взагалі.
Побудова конвеєра збору даних
Оскільки метрики когорт мають 4-тижневе вікно ретроспективи, будь-яка серйозна робота з бектестингу вимагає безперервного збору даних. Конвеєр простий: запланований скрипт звертається до API, парсить відповідь і пише до постійного сховища.
import requests
import json
import sqlite3
from datetime import datetime
BASE_URL = "https://ht-api.coinmarketman.com/api/external"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
COINS = ["BTC", "ETH", "SOL", "HYPE"]
def collect_cohort_snapshot(db_path="cohort_history.db"):
conn = sqlite3.connect(db_path)
conn.execute("""
CREATE TABLE IF NOT EXISTS cohort_snapshots (
timestamp TEXT, coin TEXT, segment_id INTEGER,
long_notional REAL, short_notional REAL,
total_notional REAL, raw_json TEXT
)
""")
ts = datetime.utcnow().isoformat() + "Z"
for coin in COINS:
resp = requests.get(
f"{BASE_URL}/cohort/metrics",
headers=HEADERS,
params={"coin": coin}
)
if resp.status_code != 200:
continue
for cohort in resp.json():
conn.execute(
"INSERT INTO cohort_snapshots VALUES (?,?,?,?,?,?,?)",
(ts, coin, cohort.get("segmentId"),
cohort.get("longNotional", 0),
cohort.get("shortNotional", 0),
cohort.get("totalNotional", 0),
json.dumps(cohort))
)
conn.commit()
conn.close()
Запускайте це кожні 5 хвилин через cron або systemd timer. При 4 монетах на виклик ви робите 4 API-запити за цикл, тобто 1 152 виклики на день. Безкоштовний тариф із 100 викликами на день не покриє безперервний збір, але тариф Pulse за $179/міс дає 50 000 викликів на місяць, чого більш ніж достатньо для цілодобового збору по кількох активах із запасом.
Вже через кілька тижнів збору у вас буде достатньо історичних даних когорт, щоб запускати бектести, які справді враховують, хто стояв по кожен бік кожного руху.
Три питання, на які має відповідати ваш бектест
Коли дані когорт вбудовані у ваш бектест, ви можете ставити питання, недоступні бектестам лише на основі ціни:
1. Як змінюється відсоток виграшів при узгодженості розумних грошей?
Запустіть базову стратегію двічі. Один раз без фільтра когорти, другий раз з ним. Порівняйте відсотки виграшів. Якщо відфільтрована версія має суттєво вищий відсоток виграшів при меншій кількості угод загалом, фільтр когорти робить свою роботу: відсіває низько-переконані сетапи, що тягнуть середню ефективність вниз.
Компроміс завжди однаковий. Фільтри зменшують кількість угод. Менше угод означає повільніше складне нарощування, але й менше просадок від низькоякісних сетапів. Якщо відфільтрований Sharpe покращується навіть при незмінному загальному P&L, стратегія більш капіталоефективна і її легше масштабувати.
2. Яке узгодження когорти важливіше?
Не всі когорти мають однакову прогностичну вагу. Тестуйте кожну когорту окремо як фільтр. Чи покращує лише узгодженість з когортою Money Printer результати? А когорта Leviathan (гаманці з $5M+ у перп-капіталі, segment ID 7)? Когорти за розміром і когорти за PnL вимірюють різні речі, і та, що важливіше, залежить від активу і таймфрейму, яким ви торгуєте.
Для активів із великою капіталізацією, як BTC і ETH, когорти за PnL зазвичай інформативніші, бо ринок достатньо глибокий, щоб розмір сам по собі не передбачав напрямок. Для активів із середньою і низькою капіталізацією когорти за розміром можуть мати більше значення, бо один гаманець Whale або Leviathan, що заходить у позицію, становить більшу частку загального відкритого інтересу.
3. Чи прогнозує розбіжність когорт просадки?
Один з найцінніших способів використання даних когорт у бектестингу — аналіз просадок. Перегляньте найгірші серії програшів у вашому бектесті та перевірте, який склад когорт був на вході. Якщо найгірші просадки стабільно збігаються з моментами, коли ваш сигнал був узгоджений зі збитковими когортами і протилежний до позиції прибуткових, ви знайшли структурну слабкість стратегії, яку стандартний бектест ніколи б не виявив.
Ось у чому справжня цінність бектестингу з урахуванням когорт. Ви не просто покращуєте середню ефективність: ви визначаєте конкретні умови, за яких ваша стратегія найбільш уразлива. Це коштує більше, ніж кілька зайвих базисних пунктів середньої прибутковості.
Типові пастки при бектестингу з даними когорт
Дані когорт додають потужну лінзу, але вносять і власні точки відмови.
Перенавчання до конкретної когорти. Якщо ви оптимізуєте стратегію слідувати лише за когортою Money Printer і бектест виходить чудовим, запитайте себе: чи торгуєте ви реальний сигнал, чи просто підганяєте під невелику вибірку гаманців, що виявилися правими протягом тестового periodу? Когорта Money Printer представляє вузький зріз ринку. Будь-яка стратегія, що цілком залежить від позиціонування одного сегмента, є крихкою.
Ігнорування зміни режимів когорт. Гаманці переміщуються між когортами з часом. Гаманець, що був Smart Money у січні, може стати Semi-Rekt до червня після серії програшів. HyperTracker перекласифіковує гаманці на основі PnL за весь час, тому позначки когорт динамічні. Бектест, що припускає статичне членство в когортах, переоцінить якість сигналу, бо частина позицій «розумних грошей», за якими він слідує, насправді генерувалася гаманцями, що тоді були розумними, але зараз вже ні.
Припущення про затримку. Наші дані оновлюються кожні 5 хвилин, а повне оновлення стану займає від 15 до 20 хвилин. У бектесті ви маєте ідеальні дані на кожному таймстемпі. У живій торгівлі ви завжди дивитеся на дані, що є кілька хвилин застарілими. Врахуйте це запізнення у бектесті, використовуючи дані когорти з попереднього знімка, а не з поточного. Якщо сигнал працює лише з даними когорти поточного бару, у продакшні він не працюватиме.
Плутанина кореляції з причинністю. Позиціонування розумних грошей не спричиняє руху ціни в певному напрямку. Це суміжний індикатор: прибуткові гаманці частіше позиціоновані правильно, ніж збиткові. Зв'язок є ймовірнісним, а не детерміністичним. Розглядайте узгодженість когорти як фільтр, що покращує очікувану цінність на багатьох угодах, а не як гарантію в окремій угоді.
Почніть збирати дані когорт для ваших бектестів
Безкоштовний тариф дає вам 100 API-викликів на день. Достатньо, щоб прототипувати конвеєр збору і перевірити якість сигналу перед масштабуванням.
Отримайте безкоштовний API-ключ
Кожен бектест є спрощеною моделлю реальності. Питання в тому, які спрощення коштують вам грошей. Ставитися до будь-якого капіталу як до рівнозначного, ігнорувати, хто стоїть за потоком, і вважати, що OI є OI незалежно від джерела: ці спрощення здаються нешкідливими рівно до того моменту, коли ви запускаєте стратегію в живу торгівлю і спостерігаєте, як вона не дотягує до симульованої кривої. Дані когорт не роблять ваш бектест ідеальним. Вони зменшують брехню, а цього вже достатньо, щоб змінити результат.