TradeBiff

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

Стандартная для MetaTrader Функция отправки довольно ограничена и имеет ряд существенных недостатков, которые будем обходить используя библиотеку ATcl

Ставим себя на место заказчика и формулируем задачу:

Нужно сделать программу которая будет следить за роботом
и при выставлении/изменении/удалении ордеров
будет отправлять скриншот мне и двум инвесторам.

Почти любой заказчик сформулируют задачу именно так (если не короче). С его точки зрения это просто, даже почти элементарно и «если бы он немного знал программирование он бы написал сам». Поэтому он будет сильно удивлён и возмущён тем что вы укажите срок превышающий пару дней, плюс аренду им сервера на весь срок, и цену значительно больше 100 долларов. :-)

Это одна из причин почему статей будет несколько и предназначены они будут отчасти заказчикам, чтобы ознакомить их какие подводные камни скрываются в простой задаче и немного про инженерию разработки.

Возвращаясь к задаче, помимо краткой постановки, в процессе диалога выясняем полный типичный сценарий использования :

  • пользователь подключается к VDS
  • запускает MT4
  • открывает чарт EURUSD например
  • запускает робота, указывая уникальный MAGIC
  • на чарте запускает TradeBiff указав:
    • MAGIC робота,
    • Свой e-mail
    • e-mail`ы пары партнёров
  • открывает следующий символ
  • запускает робота, указывая его MAGIC
  • запускает TradeBiff
  • … и так далее

В принципе ничего больше вы от заказчика не добьётесь. Никаких многостраничных ТЗ. Более того если будете требовать детализовать задание, то просто запугаете и запутаете заказчика. Максимум что ещё следует согласовать, это сценарий/условия приёмки:

  • С чистого листа (то есть на «свежем сервере» или по крайней мере в новом экземпляре MT)
  • Устанавливается TradeBiff
  • Реализуется типичный сценарий
  • Работает в течении недели
  • Если письма приходят заказчику на два разных адреса то проект выполнен

Вся вводная информация получена, можно приступать к работе

Заказчик - профессиональный трейдер, который знает своё дело и знает что часть работы можно автоматизировать обратившись к вам. Вы - профессиональный программист, владеющий отчасти трейдингом и отлично знающий торговую платформу. Взаимная область соприкосновения относительно небольшая.

Ненадо «взрывать мозг» заказчику указывая на очевидные/кажущиеся вам детали программы или нюансы протоколов и MetaTrader. Он этого незнает, знать не хочет и не должен. Это выходит за область его профессиональных знаний и личного любопытства. Нестоит пытаться описать неописуемое и согласовывать несогласуемое.

То есть все проблемы реализации исключительно ваши.

Пока буду готовить вторую часть «марлезонского балета» попробуйте выписать на бумажке (или в коментариях) те проблемы которые очевидно придётся решать. Можете считать это проф.тестом

А пока, непосредственно про программирование:

чтобы выполнить поставленную задачу будем периодически (по таймеру) выполнять следующий цикл:

  • прочесть ордера
  • сравнить с предыдущим списком
  • если что-то поменялось то
    • снять скриншот
    • отправить почту

Проверка ордеров

Для проверки изменений будем периодически сканировать ордера в рынке и сравнивать полученный список с предыдущим. Цикл чтения ордеров уже наверное набил оскомину - он типичный для всех советников и индикаторов. Будем выбирать только ордера с символом чарта и заданным в параметрах MAGIC.

Список будем формировать сразу как объект tcl. А для хранения и сравнения возьмём алгоритм из предыдущего примера (из TradePanel).

на уровне tcl реализуем одну процедуру:

proc SetOrders { orderList } ;

которая получит от нас 1 список - все текущие ордера. Сравнит их с ранее её-же сохранённым списком и вернёт нам три списка:

  • новые ордера, то есть те, тикетов которых не было в предыдущий раз и вдруг они появились.
  • изменённые ордера, тикеты есть в обоих списках, но что-то в них поменялось (например StopLoss)
  • удалённые ордера, в старом списке тикет есть, в новом нет - счтаем что ордер удалён или закрыт

Если в любом из полученных списков есть хотя-бы один элемент, значит надо снимать скриншот и отправлять почту

Скриншот

Скриншот будем делать встроенной функцией MetaTrаder, у которой правда есть свои особенности:

  • надо указывать размер и способ выравнивания изображения. Мы будем делать полный скриншот всего чарта поэтому выравнивание не суть как важно
  • формат картинки определяется по расширению файла, для передачи графиков подходит только png (зачем реализованы прочие форматы - загадка)
  • файл помещается в каталог Files и не всякое имя ему подходит.

Если скриншот снялся удачно, то отправляем его по почте

Отправка почты

Отправка почты от клиента производится протоколом SMTP (Simple Mail Transfer Protocol). А сами письма при этом кодируются в соответсвии с протоколом MIME (Multipurpose Internet Mail Extensions). Обе эти «штуковины» есть в стандартной библиотеке tcl, их и задействуем. Предварительно конечно изучив «мат.часть», то есть почитав описания, стандарты и документацию API.

Для работы с почтой нам надо будет соединяться с сервером, и соответвенно уметь настраиваться под него ( то есть иметь возможность задавать разные настройки):

  • адрес сервера (их кстати может быть несколько альтернатив)
  • номер порта сервера (по умолчанию стандартный 25)
  • почти обязательно на сервере надо «представиться» то сообщать логин и пароль
  • и весь диалог с сервером может шифроваться, по крайней мере мы должны уметь вкл/выкл защиту соединения

Несмотря на значительный объём информации и ёмкость протоколов, API достаточно компактный и процедура отправки почты проста:

  • при помощи пакета mime формируем конверт, который включает текст, вложения и некоторую служебную информацию
  • при помощи пакета smtp соединяемся со своим почтовым сервером и отправляем конверт в нужные адреса

Есть только некоторые нюансы в формировании конверта - у нас есть вложения и он должен иметь сложную структуру:

  • multipart/mixed - весь пакет
    • text/plain - собственно текст письма
    • image/png - наше вложение (передаваемый скриншот)

когда вложений нет, то конверт «плоский» - сразу следует text/plain содержащий текст письма.

Информацию про тему, получателей и прочую помещаем как заголовки конверта или непосредственно при отправке

Для реализации задумки на уровне tcl сделаем класс SMTP где будем хранить основные параметры сервера и соединений и к нему основной рабочий метод SendMail:

method SendMail { from to cc bcc subj body attach } ;

методу надо передать параметры:

  • from - адрес отправителя
  • to - адреса получателей через запятую
  • сс - адреса получателей «твёрдых копий» (carbon copy)
  • bcc - скрытые адреса получателей «твёрдых копий» (blind carbon copy)
  • subj - тема письма
  • body - текст
  • attach - список прикладываемых файлов

Получилась толковая программа в виде индикатора, которая «сидит в чарте» и если вдруг чего-то в ордерах поменялось то рассылает письма с отчётом и скриншотом. Отличное средство на VDS, прям-таки must-have

Исходники будут включены в ближайшее обновление ATcl, но естественно прикладываю к статье tradebiff.zip; Для установки - просто распакуйте архив в каталог терминала.

Помните про подводные камни, те которые надо было для себя выписать на бумажке ?

Так вот «дьявол кроется в деталях» :-)

Хотя на разработку потрачен не один день и не два, но наш текущий результат это не более чем рабочий прототип

до того чтобы «передать заказчику в эксплуатацию» (сдать себе любимому) продукт надо ещё пахать и пахать.. Работы и материалов впереди на две-три статьи и несколько серьёзных изменений в проекте.

Следущая статья (и этап работы) - разбор проблем, уточнение объектной модели, реализация классов на Mql и их синхронизация с классами Tcl. И она точно не последняя, потому что то что «выписывали на бумажке» мы простым внедерением ОО не закроем.