Strasmore Research
Навчання Matt ConnorВід Matt Connor

Вивчення кількісної торгівлі за книгою з відкритим кодом

Книга з відкритим кодом охоплює весь шлях кількісної торгівлі: від даних до ордера. Дізнайтеся, чого навчає кожен етап і що актуально для акцій США.

Книга з алгоритмічної торгівлі з відкритим кодом — це безкоштовна загальнодоступна навчальна програма: повний шлях від необроблених даних до виконання реального ордера, описаний у послідовності, у якій із ним стикається початківець. Рукопис XQuant: Everyone Can Be a Quantitative Trader, опублікований на GitHub користувачем xingwudao, станом на серпень 2026 року має 686 зірок і є показовим прикладом. Його дев’ять розділів охоплюють шлях, яким проходить майже кожна навчальна програма з кількісної торгівлі. На цій сторінці цей шлях розглянуто поетапно: для кожного етапу визначено конкретну проблему, що на ньому виникає, а також зазначено, які частини зберігають актуальність під час переходу від китайських A-акцій до акцій США.

Що містить книга з кількісної торгівлі з відкритим кодом?

Якщо прибрати брендинг із будь-якої навчальної програми для початківців, залишаться п’ять етапів у такому порядку: отримати й очистити дані, побудувати на їхній основі сигнал, протестувати цей сигнал на історичних даних, визначити розмір позиції, а потім передати ордер і сплатити витрати. Зміст XQuant у редакції на коміті 016b66e від 14 липня 2026 року охоплює ті самі питання у дев’яти розділах.

  • Підготовка, а потім розділ один: провести одну повну стратегію від початку до кінця.
  • Розділ два — що купувати: почати з трьох ETF.
  • Розділ три — скільки купувати: порівняти між собою три методи розподілу капіталу.
  • Розділ чотири — коли торгувати: ребалансування, stop loss, take profit.
  • Розділ п’ять — як оцінити якість стратегії: чотири підходи.
  • Розділ шість — не святкувати зарано: запобігання overfitting.
  • Розділ сім — від ідеального до реального: виконання угод.
  • Розділ вісім — життя після запуску: моніторинг, діагностика, ітерації.
  • Розділ дев’ять — пошук нових можливостей: вступ до дослідження факторів.

Порядок розділів заслуговує на увагу. Визначення розміру позиції з’являється у третьому розділі, ще до обох розділів про backtest, а дослідження факторів — в останньому. Шляхи самостійного навчання зазвичай виглядають інакше: спочатку факторна ідея, потім backtest, а правила визначення розміру позиції немає взагалі. Супровідний репозиторій із вправами (333 зірки на ту саму дату) побудований навколо письмових специфікацій завдань, а не готового коду: читач доручає AI-асистенту їх реалізацію. Уміння читати код, якого ви не писали, все одно визначає результат усьому, що наведено нижче, оскільки кожна наступна помилка прихована в певній деталі реалізації.

Етап перший: отримайте дані, а потім визначте всесвіт інструментів

Очищення даних — це видима половина роботи: некоректні prints, пропущені торгові сесії, коригування на спліти та дивіденди. Вибір які саме назви вивчати — невидима половина, і саме на цьому етапі виникає помилка виживших, ще до появи першого рядка коду стратегії. Візьміть усі тикери США, за якими протягом одного тижня в червні щороку укладалися угоди, і визначте, скільки з них продовжували торгуватися в той самий тиждень 2026 року.

ЗапитТікери США, що торгувалися протягом тижня в червні, і скільки з них продовжили торгуватися в червні 2026 року
Точний SQL-код для кожного числа
WITH june_week AS (
    SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS year,
           ticker
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE toMonth(toTimeZone(window_start, 'America/New_York')) = 6
      AND toDayOfMonth(toTimeZone(window_start, 'America/New_York')) BETWEEN 10 AND 16
      AND toYear(toTimeZone(window_start, 'America/New_York')) BETWEEN 2016 AND 2026
      AND volume > 0
    GROUP BY year, ticker
),
survivors AS (
    SELECT ticker FROM june_week WHERE year = 2026
)
SELECT year,
       uniqExact(ticker) AS tickers_traded,
       uniqExactIf(ticker, ticker IN (SELECT ticker FROM survivors)) AS still_trading_2026,
       round(100 * uniqExactIf(ticker, ticker IN (SELECT ticker FROM survivors))
             / uniqExact(ticker), 1) AS still_trading_pct
FROM june_week
GROUP BY year
ORDER BY year
Run this yourself

Із 8224 тикерів, за якими торгували в той тиждень 2016 року, 50% продовжували торгуватися в той самий тиждень 2026 року. Решту було придбано, об’єднано з іншими компаніями, перейменовано або виключено з лістингу. Бектест, побудований на основі сьогоднішнього переліку, вивчає лише ті назви, які збереглися, і оцінює стратегію так, ніби компанії для володіння були обрані заднім числом. Початкова стрічка даних без попередження надасть вам цей перелік тих, що вижили: у посібнику безкоштовного API ринкових даних щодо акцій описано, які дані такі стрічки містять, а які — ні.

Етап другий: перетворення даних на сигнал

Сигнал — це правило, яке оцінює акцію в певний момент часу. Фактор — це сигнал, який, на вашу думку, працює одночасно для багатьох акцій. Класичні приклади — momentum, value та низька волатильність. На цьому етапі помилка полягає в тому, щоб тестувати правила, доки одне з них не спрацює. Двадцять варіантів перетину ковзних середніх на даних за одне десятиліття для одного індексу завжди дадуть переможця. Ним стане варіант, який найкраще підлаштувався під шум. Захист від цього нецікавий, але ефективний: зафіксуйте правило до його вимірювання, відкладіть частину історичних даних, яку ви ніколи не переглядатимете, враховуйте кожен протестований варіант і віддавайте перевагу меншій кількості параметрів, які можна налаштовувати. XQuant присвячує цьому цілий розділ перед дослідженням факторів, і це правильний порядок.

Третій етап: бек-тест, на якому зупиняється більшість початківців

Цей етап завершує більшість самостійних проєктів. Зазвичай це відбувається непомітно — на тлі чудової кривої капіталу. Помилка виживання, описана вище, — перша з двох помилок. Друга — упередження на випередження: стратегія використовує показник, який ринок ще не встиг надати на момент подання заявки. Найпоширеніший варіант — правило, розраховане на основі ціни закриття поточного дня, а виконання заявки за цією самою ціною закриття. Оцініть відстань, яку пропускає таке припущення.

ЗапитСередня різниця між закриттям однієї сесії та відкриттям наступної, за місяцями
Точний SQL-код для кожного числа
WITH sessions AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session,
           argMin(open, window_start) AS session_open,
           argMax(close, window_start) AS session_close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'NVDA')
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2024-08-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session
),
gaps AS (
    SELECT ticker,
           session,
           toFloat64(session_open) AS open_px,
           toFloat64(lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY session)) AS prev_close
    FROM sessions
)
SELECT formatDateTime(toStartOfMonth(session), '%Y-%m') AS month,
       formatDateTimeInJodaSyntax(toStartOfMonth(session), 'MMMM yyyy') AS month_label,
       round(avgIf(abs(open_px / prev_close - 1) * 10000, ticker = 'SPY'), 1) AS spy_gap_bps,
       round(avgIf(abs(open_px / prev_close - 1) * 10000, ticker = 'NVDA'), 1) AS nvda_gap_bps
FROM gaps
WHERE prev_close > 0
GROUP BY month, month_label
HAVING countIf(ticker = 'SPY') > 0 AND countIf(ticker = 'NVDA') > 0
ORDER BY month
Run this yourself

У July 2026 середня відстань між ціною одного закриття та наступним відкриттям, виміряна в базисних пунктах, становила 40.8 для SPY і 107.4 для NVDA. Один базисний пункт — це одна сотa відсоткового пункту. Усі 24 місяців на панелі, починаючи з August 2024, мають значення вище нуля. Бек-тест, який ухвалює рішення на момент закриття і виконує заявку за цією самою ціною, безкоштовно отримує цю відстань у кожній угоді. У реальних торгах так не буває. Упередження на випередження в бек-тестуванні детально розбирає цей механізм, а чому акції мають нічні гепи пояснює сам розрив.

Етап чотири: визначте обсяг покупки

Проблема полягає у відсутності правила. Більшість трейдерів-самоучок ніколи не прописують правило визначення розміру позиції. Тому воно виникає випадково — зазвичай це однакова сума в кожному активі або весь доступний залишок коштів. Однакові суми не означають однаковий ризик.

ЗапитДванадцять місяців денних змін: річна волатильність і найгірша сесія, вісім назв
Точний SQL-код для кожного числа
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS session,
           argMax(close, window_start) AS session_close
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'KO', 'JNJ', 'MSFT', 'AAPL', 'NVDA', 'TSLA', 'COIN')
      AND toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2025-08-01')
      AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
    GROUP BY ticker, session
),
rets AS (
    SELECT ticker,
           toFloat64(session_close) AS close_px,
           toFloat64(lagInFrame(session_close) OVER (PARTITION BY ticker ORDER BY session)) AS prev_close
    FROM daily
)
SELECT ticker,
       round(stddevSamp(close_px / prev_close - 1) * sqrt(252) * 100, 1) AS annualized_vol_pct,
       round(abs(min(close_px / prev_close - 1)) * 100, 2) AS worst_day_pct
FROM rets
WHERE prev_close > 0
GROUP BY ticker
ORDER BY annualized_vol_pct DESC
Run this yourself

За дванадцять місяців до 31 липня 2026 року включно COIN продемонстрував волатильність на річному рівні 68%. Для SPY цей показник становив 12.7%, що було найнижчим значенням у вибірці. Найгірша окрема сесія для COIN завершилася на 13.34% нижче за попереднє закриття. Водночас найгірший день для SPY становив 2.69%. Однакові суми в кожному активі створюють дуже різні денні коливання. Саме ці коливання, а не сигнал, фактично відчуває початківець. У матеріалі визначення розміру позиції за критерієм Келлі наведено один формальний підхід. Матеріал про ризик концентрації показує неформальний підхід.

Етап п’ятий: виконання та витрати, які не враховує бек-тест

Дві категорії витрат, але видимою є лише одна. Комісії та регуляторні збори відображаються у виписці. Прослизання — ні. Це різниця між ціною на екрані та ціною фактичного виконання. Мінімальним орієнтиром для нього є bid-ask spread — відстань між найкращою ціною купівлі та найкращою ціною продажу в певний момент. Покупці платять за ask, а продавці продають за bid, тому операція купівлі та продажу перетинає spread двічі. Spread не є сталим.

ЗапитСередній котирувальний спред за півгодинними інтервалами ET: AAPL і KO, п’ятниця, 17 липня 2026 року
Точний SQL-код для кожного числа
WITH quotes AS (
    SELECT ticker,
           toStartOfInterval(toTimeZone(sip_timestamp, 'America/New_York'), INTERVAL 30 MINUTE) AS bucket,
           toFloat64(ask_price - bid_price) / toFloat64((ask_price + bid_price) / 2) * 10000 AS spread_bps
    FROM global_markets.cache_stocks_quotes
    WHERE ticker IN ('AAPL', 'KO')
      AND sip_timestamp >= toDateTime('2026-07-17 13:00:00')
      AND sip_timestamp < toDateTime('2026-07-17 21:00:00')
      AND bid_price > 0
      AND ask_price > bid_price
)
SELECT formatDateTime(bucket, '%H:%i') AS et_time,
       round(avgIf(spread_bps, ticker = 'AAPL'), 2) AS aapl_spread_bps,
       round(avgIf(spread_bps, ticker = 'KO'), 2) AS ko_spread_bps
FROM quotes
WHERE spread_bps > 0 AND spread_bps < 500
GROUP BY et_time
HAVING countIf(ticker = 'AAPL') > 0 AND countIf(ticker = 'KO') > 0
ORDER BY et_time
Run this yourself

Панель охоплює 16 півгодинних інтервалів однієї п’ятниці — від 09:00-го інтервалу до відкриття ринку до 16:30-го інтервалу після закриття. У першому інтервалі котирування AAPL мали ширину 10.53 базисного пункту, а в останньому — 3.27; для KO відповідні значення становили 28.87 і 8.04. Найвужчі котирування за день розташовані в центральній частині графіка, між цими двома крайніми точками. Стратегія, яка торгує на відкритті за двома найбільш ліквідними акціями ринку, несе інші витрати, ніж її аналог, що працює в середині дня. Бек-тест із припущенням про нульові витрати не враховує жодного з цих варіантів. Bid-ask spread визначає величину витрат, чому spread розширюється на відкритті пояснює форму кривої, а скільки коштує торгівля акцією підсумовує повний цикл купівлі та продажу. Між чистим бек-тестом і торгівлею реальними коштами є ще один крок: паперова торгівля перед використанням реальних коштів.

Які частини навчальної програми про A shares можна перенести на акції США?

XQuant та аналогічні методики розроблені для китайських A shares і ETF. Сам метод переноситься без змін: порядок етапів, визначення, дисципліна проти перенавчання, звичка зазначати витрати окремим рядком, а не додавати їх постфактум, і всі елементи розрахунку розміру позиції. Цінові бари залишаються ціновими барами. Не переноситься лише система правил, яка їх регулює.

  • На ринку A shares діє справжнє обмеження T+1: акції, придбані сьогодні, не можна продати до наступної сесії. У США T+1 — це правило розрахунків, яке не забороняє внутрішньоденні операції, хоча правило pattern day trader обмежує власників маржинальних рахунків із капіталом менш як $25 000 трьома денними угодами протягом п’яти робочих днів.
  • Для акцій основного сегмента A shares діє денний ліміт зміни ціни на рівні 10%, а для акцій сегментів зростання — 20%. Для акцій США денного ліміту немає. Натомість зупинки торгів відбуваються через волатильнісні обмеження та новинні паузи.
  • На ринку A shares заявки виконуються лотами по 100 акцій. Багато брокерів у США виконують заявки на дробові акції, і це змінює можливості, які взагалі може виразити правило розрахунку розміру позиції.
  • У Китаї з продавця стягують гербовий збір. Продавці у США сплачують невеликі регуляторні збори, які відрізняються за розміром і структурою.
  • Структура торгових сесій відрізняється, зокрема через денну перерву в Шанхаї та Шеньчжені. Години роботи фондового ринку США тривають безперервно й завершуються на закриттєвому аукціоні.

Будь-яка константа витрат або часу, скопійована з курсу у власний код, стане помилкою, яка проявиться під час першої реальної заявки.

Зафіксуйте посилання на коміт, а не на README

Станом на серпень 2026 року в репозиторії немає позначених релізів, тому надійним посиланням є коміт: 016b66e від 14 липня 2026 року. Це важливо для книги, над якою ще працюють. Номери розділів змінюються, файли README переписують, а заголовки переміщують. Посилання, яке вело на розділ сім, непомітно може почати вести на інший матеріал. Цитуйте коміт і дату, а в нотатках зазначайте назву прочитаного розділу, а не його номер. Тоді ваші записи можна буде перевірити й через рік. Рукопис опубліковано за ліцензією CC BY-NC-SA 4.0, а скрипти складання — за ліцензією MIT. Та сама дисципліна є й останнім уроком самого курсу: стратегія, яку неможливо повторно виконати на основі зафіксованого знімка даних, є історією, а не результатом.

Часті запитання

Чи можна вивчити кількісну торгівлю за безкоштовною книгою з відкритим кодом?

Для загальної структури — так. Відкритий рукопис дає змогу перевірити кожне твердження за першоджерелом. Але книга не може надати дані, витрати та правила саме вашого ринку. Саме тому навчальна програма, написана для однієї біржі, може не відповідати умовам вашого брокера.

На якому етапі навчання кількісної торгівлі більшість початківців зупиняється?

На бектесті. Там виникають дві помилки, і обидві покращують результат на папері: упередження виживших через формування вибірки заднім числом і упередження на випередження через виконання за ціною, якої ринок ще не встиг зафіксувати. Лише 50% тикерів, що торгувалися того червневого тижня 2016, продовжували торгуватися через десять років.

У чому різниця між упередженням виживших і упередженням на випередження?

Упередження виживших — це проблема вибірки: до тесту потрапили назви, які вже довели здатність залишатися на ринку. Упередження на випередження — це проблема часу: стратегія використовує показник, якого ще не існувало на момент подання заявки. Перше штучно покращує склад вибірки, друге — ціну виконання.

Чи працює курс кількісної торгівлі для китайських A-акцій із торгівлею американськими акціями?

Метод працює. Правила ринку — ні. Збережіть послідовність етапів, дисципліну проти перенавчання та облік витрат. Перед початком торгівлі замініть інфраструктуру даних, обмеження на продаж у режимі T+1, денні ліміти цін і розміри лотів на американські аналоги.


Кожна панель вище є збереженим запитом із SQL-кодом під нею. Відкрийте потрібну панель, замініть тикери або дати та самостійно запустіть запит у терміналі Strasmore.

#quant#learning path#backtesting#open source#beginners