Библиотека для трейдинга: архитектура 2
Архитектура библиотеки: Почему индикаторы делятся на simple, advanced и complex
В сегодняшней статье я хочу раскрыть логику одного из ключевых архитектурных решений в библиотеке Taljure — разделения индикаторов по уровню сложности на модули simple
, advanced
и будущие complex
.
Текущая структура
(ns taljure.core (:require [taljure.indicators.simple :as simple])) (def sma simple/sma) ; Простое скользящее среднее (def ema simple/ema) ; Экспоненциальное скользящее среднее (def atr simple/atr) ; Average True Range (def rsi simple/rsi) ; Relative Strength Index
Почему не просто свалка в одном модуле?
1. Ментальное разделение ответственности
simple
— это индикаторы, которые:
- Имеют простую математическую формулу
- Вычисляются за один проход по данным
- Не требуют сложного контекста или состояния
- Идеальны для изучения основ алготрейдинга
; По сути, это скользящее окно и среднее арифметическое (defn sma [data period] (map #(when (>= (count %) period) (/ (reduce + (take period %)) period)) (partition period 1 data)))
Новичок в алготрейдинге может:
- Изучить индикаторы из
simple
→ понять базовые концепции - Перейти к
advanced
→ разобраться в более сложной математике - Освоить
complex
→ понять составные индикаторы и стратегии
Это соответствует дидактическому принципу «от простого к сложному».
3. Технические характеристики и производительность
Advanced индикаторы (например, MACD, Bollinger Bands):
- Многоуровневые вычисления (индикаторы от индикаторов)
- Требуют больше ресурсов
- Могут нуждаться в кешировании
Complex индикаторы (например, машина состояний для стратегий):
Как будет развиваться архитектура
src/taljure/indicators/ └── simple.clj # SMA, EMA, RSI, ATR...
src/taljure/indicators/ ├── simple.clj # Базовые: SMA, EMA, RSI, ATR ├── advanced.clj # MACD, Bollinger Bands, Ichimoku... └── complex.clj # Составные индикаторы, машины состояний
; MACD = разница между EMA(12) и EMA(26) ; Signal = EMA(9) от MACD ; Гистограмма = MACD - Signal ; Уже требует композиции нескольких индикаторов!
4. Гибкость подключения зависимостей
- Подключать только нужные модули
- Избегать ненужных зависимостей
- Оптимизировать bundle size для разных use cases
; Если пользователю нужны только простые индикаторы (:require [taljure.indicators.simple :as indicators]) ; Если нужны все возможности (:require [taljure.indicators.simple :as simple] [taljure.indicators.advanced :as advanced] [taljure.indicators.complex :as complex])
5. Тестирование и сопровождение
- Простая логика → простые тесты
- Сложная логика → комплексные тестовые сценарии
- Разделение упрощает поиск и исправление ошибок
(deftest sma-test (is (= [nil nil 2.0 3.0 4.0] (sma [1 2 3 4 5] 3))))
Тест для advanced индикатора уже потребует setup с готовыми данными и может проверять несколько аспектов поведения.
Почему это лучше альтернатив?
Альтернатива 1: По одному модулю на индикатор
indicators/ ├── sma.clj ├── ema.clj ├── rsi.clj └── ...
→ Слишком дробно, сложно управлять
Альтернатива 2: Все в одном модуле indicators.clj
→ 2000+ строк кода, сложно ориентироваться
Альтернатива 3: Группировка по назначению (trend, volatility, volume)
→ Субъективно, многие индикаторы многозадачны
Мое решение: Группировка по сложности реализации — объективный и технически обоснованный критерий.
Заключение: Архитектура как отражение доменной области
Разделение на simple/advanced/complex — это не просто технический прием. Это:
- Отражение реальности — в трейдинге действительно есть простые и сложные индикаторы
- Организационный принцип — помогает структурировать код и мысли
- Масштабируемость — позволяет библиотеке расти органически
- Эргономика — пользователи быстро находят нужный уровень сложности
В следующей статье реализуем первый индикатор SMA и посмотрим, как эта архитектура работает на практике.
Как вы организуете сложные доменные области в своих проектах? Сталкивались ли с подобными архитектурными дилеммами?