[Фінтех · Backend-розробка · Автоматизація даних]
Рушій аналізу торгових сигналів
Автоматизований конвеєр, який читає ринкові дані криптовалют, звужує широкий набір інструментів до відібраних кандидатів і перетворює їх на структуровані, перевірені торгові сигнали.
01Огляд проєкту
Рушій сигналів — аналітичне ядро Astra Raven. За розкладом він збирає ринкові дані через зовнішні API бірж, оцінює ринковий контекст і пропускає кожен інструмент через послідовність фільтрів, перш ніж щось дійде до користувача.
Результат — не довільна думка, а структурований об’єкт: інструмент, напрям, зона входу, стоп-лос, цілі та причини, з яких він пройшов перевірку. Його можуть зберігати, відстежувати й оцінювати наступні системи.
02Інженерна задача
Ринкові дані зашумлені й надходять від зовнішніх сервісів, які бувають повільними, обмежують частоту запитів або тимчасово недоступні. Рушій має ухвалювати стабільні рішення в цих умовах і залишати слід, що пояснює кожне з них.
- A
Обробити багато інструментів у заплановане вікно, не блокуючись на повільних відповідях.
- B
Відокремити визначення ринкового контексту від оцінки конкретного інструмента, щоб кожен етап можна було аналізувати окремо.
- C
Відсіювати неповних або суперечливих кандидатів якомога раніше замість видачі неякісного результату.
- D
Зберігати кожен сигнал із контекстом, достатнім для подальшої оцінки його результату.
03Архітектура рішення
Наведіть або натисніть на етап.
Ринкові дані
Свічки, обсяги та метадані інструментів завантажуються через зовнішні API бірж із таймаутами й обмеженням повторів.
04Основні компоненти
- 01
Шар отримання даних
Асинхронні збирачі ринкових часових рядів із контролем частоти запитів, таймаутами та коректною обробкою неповних відповідей.
- 02
Модуль ринкового контексту
Класифікує поточний стан ринку, щоб наступні фільтри адаптували свою поведінку.
- 03
Ранжування кандидатів
Фільтрує набір інструментів і ранжує решту, зберігаючи конвеєр швидким і сфокусованим.
- 04
Ланцюжок перевірок
Упорядковані, незалежно тестовані перевірки. Кандидат, що не пройшов будь-яку з них, відкидається із записаною причиною.
- 05
Зберігання сигналів
SQL-сховище сигналів, їхніх параметрів і життєвого циклу, яке використовують відстеження та звіти.
- 06
Планувальник і звіти
Запуск за розкладом, відстеження результатів і діагностичні зведення для оператора.
05Технологічний стек
Ядро
- Python
- asyncio
- dataclasses
Дані
- Exchange REST APIs
- Time-series processing
- SQLite / SQL
Експлуатація
- Scheduled jobs
- Structured logging
- Reports
06Інтерактивна демонстрація
Симуляція конвеєра сигналів
ІлюстраціяІлюстративне демо. Синтетичний інструмент і згенеровані ціни — без підключення до ринку, без реальних параметрів стратегії, і це не торгова рекомендація.
- Ринкові дані
- Аналіз ринку
- Відбір кандидатів
- Перевірка сигналу
- Перевірки ризику
- Видача сигналу
- Моніторинг
$ press “Run pipeline” to process a synthetic market snapshot
Результат сигналу
—
07Інженерні рішення
- 01
Спершу контекст, потім кандидати
Одноразова оцінка стану ринку на початку спрощує логіку для окремих інструментів і робить обґрунтування кожного сигналу зрозумілішим.
- 02
Відсіювати рано й фіксувати причину
Кожен крок перевірки може відхилити кандидата з явною причиною. Менше сигналів із зрозумілим походженням цінніші за багато непояснених.
- 03
Лише структурований результат
Сигнали — це типізовані об’єкти, а не текст. Доставка, відстеження й звіти працюють з однією структурою.
- 04
Детерміноване ядро
Шлях ухвалення рішення ґрунтується на правилах і відтворюваний для однакових вхідних даних, тож регресії можна виявити.
08Надійність і тестування
- Таймаути та обмежені повтори для кожного зовнішнього запиту.
- Перевірка форми вхідних даних до початку розрахунків.
- Регресійні перевірки під час зміни логіки фільтрів.
- Логи та звіти, за якими можна пояснити пропущений або відхилений інструмент.
09Приклад коду
from dataclasses import dataclass, field
from typing import Callable
@dataclass
class Candidate:
symbol: str
direction: str # "LONG" | "SHORT"
entry: float
stop_loss: float
reasons: list[str] = field(default_factory=list)
Check = Callable[[Candidate], str | None] # returns a rejection reason or None
def has_valid_direction(c: Candidate) -> str | None:
return None if c.direction in {"LONG", "SHORT"} else "unknown direction"
def stop_on_correct_side(c: Candidate) -> str | None:
ok = c.stop_loss < c.entry if c.direction == "LONG" else c.stop_loss > c.entry
return None if ok else "stop loss on wrong side of entry"
CHAIN: list[Check] = [has_valid_direction, stop_on_correct_side]
def run_chain(c: Candidate) -> tuple[bool, str | None]:
for check in CHAIN:
if (reason := check(c)) is not None:
return False, f"{check.__name__}: {reason}"
c.reasons.append(check.__name__)
return True, NoneІлюстрація Ілюстративний інженерний приклад — спрощений ланцюжок перевірок, не production-код.
Вихідний код продукту закритий. Приклади показують інженерний підхід, а не внутрішню логіку. Більше — в Engineering Lab.
10Можливий розвиток
- Підключувані джерела даних для інших майданчиків і класів активів.
- Стенд для бектестів, що проганяє збережені дані через той самий ланцюжок перевірок.
- Дашборд метрик за етапами, який показує, де відсіюються кандидати.