k100
k100 личный блог
14 сентября 2017, 12:49

Торговая система своими руками. Часть 5. Работа с БД. Дата-сервис, структура таблиц.

     Приветствую. В предыдущем посте описывался интерфейс  для генерации тиковых данных – ITickGenerator. Его реализации могут быть разными: данные могут генерироваться на лету, или браться из БД. В случае с БД, возникает необходимость в организации ещё одного слоя приложения – слоя доступа к данным. TickGenerator, всё также будет оповещать подписчиков (стратегии, которые выставляют заявки), но по тем данным, которые он получит из БД.

     Сейчас не важно, какая будет база данных, и где она будут храниться – на сервере, в файлах или в оперативной памяти. Не важно, также, какие специфические библиотеки и драйвера буду для этого использоваться. Сейчас, я просто приведу пример того, как можно разделить бизнес-логику приложения и слой доступа к данным.

     Я создал отдельный модуль, и там и развернул всю архитектуру, связанную с БД, основные компоненты которой: сущности, репозитории и дата-сервис.

     Хотя понятие сущности (Entity), само по себе, достаточно общее, здесь, буду применять его в узком смысле – это классы, представляющие таблицы БД, возможно, с какой-то дополнительной логикой. В простейшем случае, одна сущность – одна таблица. Между сущностями может быть связь (например, один ко многим), которая отражается и в связи между таблицами.  Сущность описывается полями класса, которые отражают колонки таблиц.

     Репозитории, это один из паттернов проектирования, это концепция манипулирования коллекциями сущностей одного типа:  добавление, изменение, выборка по каким-то критериям. У каждой сущности должен быть свой репозиторий. Например, задачей репозитория заявок, может быть добавление новой заявки в коллекцию всех заявок и выборка всех совершённых заявок за какой-то период дат.

     И последнее, что необходимо – это класс дата-сервис. По сути, он аккумулирует все репозитории внутри себя. Впоследствии, на него может лечь управление транзакциями и правами доступа к данным. В остальных частях проекта используется именно дата-сервис.  Хотелось бы отметить также, что, дата-сервис отвечает и за маппинг. Это значит, что он конвертирует коллекции сущностей, полученные от репозиториев, в так называемые DTO (data transfer object). DTO – это классы-копии сущностей по части полей, но без логики и прочих аспектов. Т.е. DTO это облегченная версия сущности, и именно коллекции DTO должны циркулировать между различными слоями приложения, а не сущности. Для маппинга можно использовать готовые библиотеки, например – Automapper.

     Для проведения бэк-тестов и сохранения результатов, в простейшем случае, нужно  всего лишь три таблицы: таблица, откуда будут браться тиковые данные, и таблицы для сохранения заявок и сделок.
Таблицы
     Таблица заявок (ORDERS) хранит информацию о портфеле, о стратегии, которая выставила эту заявку, цену, объём и прочие данные. Таблица сделок (TRADES) хранит ссылку на заявку, и свои цену/объём – ведь  на одну заявку может быть несколько сделок и все по разной цене. В таблицу тиков (TICKS) импортируются тиковые данные.

     Теперь, можно представить реализацию ITickGenerator работающую с дата-сервисом:

class TickGenerator : ITickGenerator
{
   public event EventHandler<StockTickEventArgs> OnTick;
   public event Action OnEnd;
   private IDataService dataService;

   public TickGenerator(IDataService dataService)
   {
     this.dataService = dataService;
   }

   public void Start(string symbol)
   {
     var ticks = dataService.Ticks(symbol);

     foreach (var t in ticks)
     OnTick?.Invoke(this, 
       new StockTickEventArgs()
       {
         Symbol = t.Symbol,
         Id = t.Id,
         DateTieme = t.DateTime,
         Price = t.Price,
         Vol = t.Vol
       });

     OnEnd?.Invoke();
   }
}

     TickGenerator, ничего не знает о способе хранения данных и организации доступа к ним. Задача TickGenerator’а – на каждый тик оповестить подписчиков (вызвать событие onTick) и в конце просигнализировать о завершении прогона (вызвать событие onEnd). Дата-сервис (IDataService), используется в качестве поставщика данных, и является связующим звеном между бизнес-логикой приложения и слоем доступа к данным.

     Для проведения бэк-тестов, я качаю данные (например, с Финама), заливаю их в таблицу TICKS и гоняю тесты. В качестве СУБД я использую ORACLE, есть бесплатные версии – XE. В ORACLE много интересных фишек – например, аналитические функции (о них расскажу позже). Также, можно использовать и PostgreSQL или даже встраиваемые NoSql СУБД, не требующие установки (это удобно для демонстрационных примеров). Что за СУБД не важно, если нет специфических требований по скорости (не важны миллисекунды), то сойдёт любая. БД – это просто способ хранения данных, ещё один аспект реализации. В следующем посте я расскажу про внутреннюю реализацию репозиториев и про способ связи с самой базой данных.

14 Комментариев
  • CloseToAlgoTrading
    14 сентября 2017, 12:58
    так работают тесты уже?
      • CloseToAlgoTrading
        14 сентября 2017, 13:44
        k100, это вы хорошо, быстро двигается прогрес :)
          • Евгений
            14 сентября 2017, 13:55
            k100, а какой в итоге опыт? Сколько сотен тысяч рублей в месяц? ;-)
              • Евгений
                14 сентября 2017, 14:12
                k100, вот и давайте забежим вперед. Вы на что-то потратили время. Сколько теперь вам приносит доход эти затраты? Если ничего, то зачем об этом рассказывать? Другие потратят время в никуда, а могли бы на что-то полезное.
                • CloseToAlgoTrading
                  14 сентября 2017, 14:39
                  Евгений, Монетизировать сей труд не сложно даже вне биржи, если человек работает как разработчик, такого рода практика всегда полезна ибо повышает квалификацию, которая в последствии оплачивается выше :)

                  Но вы в целом с какой целью интерисуетесь? не тратьте время
                  • Евгений
                    14 сентября 2017, 14:48
                    Denis, стёб на айтишниками, которые думают, что их труды были полезны ;-) 
  • AntiKukl
    14 сентября 2017, 13:57
    пока не прочел всю серию статей, но плюсую… интересно, продолжайте… мои роботы проще — главное чтобы работали, поддержка и модификация вторичны… но есть желание систематизировать торговую модель…
  • AntiKukl
    14 сентября 2017, 14:00
     тики финама — моветон на мой взгляд… сам использую orderLog цериха в qsh формате…

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн