Блог им. WinterMute

Торговая система своими руками. Часть 2. Базовые компоненты.

    • 01 сентября 2017, 11:36
    • |
    • k100
  • Еще

     Приветствую! В предыдущем посте была теория, теперь к делу. Кое-что буду упрощать, чтобы представить картинку в целом.

     Итак, чтобы проект не зависел от API внешней com библиотеки (SmartCom или д.р.), чтобы в коде стратегий  не использовались специфические типы, разработку я начала с обёрток над смарткомом. Я определил три базовых интерфейса: IConnectGate, IMarketDataGate и IPortfolioGate. Соответственно для подключения, для получения маркет-даты и для выставления заявок и работы с портфелем. Причём каждый из этих трёх интерфейсов мне надо было реализовать минимум дважды – для смарткома и для локального тестера.

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

     В случае с локальным тестером, реализации – это по большей части mock объекты, заглушки. Например, реализация IConnectGate для смарткома, это вызов метода подключения  и подписка на результат этого вызова, а в случае с локальным тестером мы никуда физически не подключаемся, а сразу генерируем событие “ Ok! Мы подключились!”.

     Далее, я определил интерфейс IStrategy, всего лишь с одним методом – Start. Вообще, изначально планировал сделать несколько классов  – класс генерирующий сигналы, класс, отвечающий за риск менеджмент, класс, который ведёт и закрывает позицию… Но, подумав, решил не усложнять  – особых плюсов это не дало бы, а только запутало. Все стратегии, которые я бы не делал, все реализуют интерфейс IStrategy. В конструктор стратеги передаются необходимые настройки (торгуемый тиккер, размер допустимой просадки, коэффициенты), инициализируются переменные и происходит подписка на события получения маркет-даты. А метод Start просто запускает процедуру получения маркет-даты и стратегия начинает работать. Конечно, можно было бы определить ещё несколько методов, благодаря которым, мы бы как-то влияли на стратегию во время её работы, или получали от неё какие-то данные, но пока опустим эти детали.

     Если стратегий несколько, и они используют специфические настройки, лучше использовать фабрику для их создания. Фабрика стратегий по некоему ID стратегии возвращает конкретную её реализацию, тем самым мы делегируем фабрике функцию создания стратегий:

interface IStrategyFactory
    {
        IStrategy CreateStrategy(int strategyID);
    }

     Согласно шаблону MVP, один презентер отвечает за одно представление (форму), каждое представление должно иметь презентера. Я создал два класса – некий MainPresenter и MainView для него. При старте программы, после необходимых настроек, вызывается конструктор MainPresenter’а и далее открывается MainView. В последующих постах, я буду детальнее описывать и развивать эту часть. Хочу подчеркнуть – внешний вид не важен, информацию можно получать и из консоли. Учитывая всё вышесказанное можно описать MainPresenter’а в первоначальном виде:

class MainPresenter
    {
        private IMainView mainView;
        private IStrategyFactory strategyFactory;
        private IConnectGate connectGate;

        public MainPresenter(IMainView mainView, IStrategyFactory strategyFactory, IConnectGate connectGate)
        {
            this.mainView = mainView;
            this.strategyFactory = strategyFactory;
            this.connectGate = connectGate;<br />
            this.connectGate.Connected += () =>
              this.strategyFactory.CreateStrategy(1).Start();

            this.connectGate.Connect();
        }

        public IMainView View => mainView;
    }

     В теле конструктора MainPresenter’а происходит инициализация переменных, подписка на событие подключения и собственно подключение. Почём подписка на событие могла бы выглядеть так:

private void ConnectHandler()
    {
        ...
    }

    connectGate.Connected += ConnectHandler; 

     Но первый способ более лаконичен, и для небольших блоков более приемлем. Это т.н. лямбда выражения, или анонимные функции. Лямбды упрощают код, также лямбды используются в выражениях linq (это я покажу в дальнейшем).

     Вот и всё. Мы скрыли все детали реализации, нам не важно, что за брокер, какова будет реализация интерфейсов, какая у нас стратегия торговли, мы не зависим от специфических библиотек – всё это решается в другом месте. Мы обобщили подход – инициализировали объекты, подписались на событие подключения, подключились, и запустились. Причём на данном этапе, все реализации могут быть заглушками.

 

     P.S.
     С днём знаний, друзья! ;-)

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
192 | ★5

Читайте на SMART-LAB:
Фото
Календарь первички ВДО и розничных облигаций (ПКО Вернём YTM 28,71% | БИЗНЕС АЛЬЯНС YTM 26,2%)
💼  ПКО Вернём 1Р4 ( B|ru|  со стабильным прогнозом, 150 млн руб., ставка купона 25,5%, YTM 28,71 % , дюрация 2,14 года до погашения)...
Фото
🏦 Залог развития рынка инвестиционного золота: равная легкость покупки и продажи слитка
Для развития рынка физического золота инвестору нужна возможность не только купить слиток, но и впоследствии продать его на понятных и...
Фото
Стратегия на IV квартал 2026 года. Рынок акций
Алексей Девятов Инвестиционная Стратегия на IV квартал 2026 года предлагает ориентиры для управления портфелем. Ведущие аналитики...
Фото
Модельный портфель рублевых облигаций: итоги, состав, планы
На российском рынке облигаций сохраняется повышенная волатильность. Заметно выросли доходности во 2-ом эшелоне и сегменте ВДО на фоне возросшего...

теги блога k100

....все тэги



UPDONW
Новый дизайн