🧑‍💻 Код
August 24

Библиотека для трейдинга: архитектура 2

Архитектура библиотеки: Почему индикаторы делятся на simple, advanced и complex

Архитектура taljure 2

В сегодняшней статье я хочу раскрыть логику одного из ключевых архитектурных решений в библиотеке 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 — это индикаторы, которые:

  • Имеют простую математическую формулу
  • Вычисляются за один проход по данным
  • Не требуют сложного контекста или состояния
  • Идеальны для изучения основ алготрейдинга

Пример SMA:

; По сути, это скользящее окно и среднее арифметическое
(defn sma [data period]
  (map #(when (>= (count %) period)
          (/ (reduce + (take period %)) period))
       (partition period 1 data)))

2. Путь обучения и onboarding

Новичок в алготрейдинге может:

  1. Изучить индикаторы из simple → понять базовые концепции
  2. Перейти к advanced → разобраться в более сложной математике
  3. Освоить complex → понять составные индикаторы и стратегии

Это соответствует дидактическому принципу «от простого к сложному».

3. Технические характеристики и производительность

Simple индикаторы:

  • Легковесные вычисления
  • Минимальная память
  • Подходят для real-time вычислений

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     # Составные индикаторы, машины состояний

Пример advanced индикатора:

; 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. Тестирование и сопровождение

  • Простая логика → простые тесты
  • Сложная логика → комплексные тестовые сценарии
  • Разделение упрощает поиск и исправление ошибок

Тест для simple индикатора:

(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 — это не просто технический прием. Это:

  1. Отражение реальности — в трейдинге действительно есть простые и сложные индикаторы
  2. Организационный принцип — помогает структурировать код и мысли
  3. Масштабируемость — позволяет библиотеке расти органически
  4. Эргономика — пользователи быстро находят нужный уровень сложности

В следующей статье реализуем первый индикатор SMA и посмотрим, как эта архитектура работает на практике.

Как вы организуете сложные доменные области в своих проектах? Сталкивались ли с подобными архитектурными дилеммами?