2.2 Программируем индикатор анализа открытых ордеров

Всем привет! В этом уроке мы впервые пройдемся перебором по всем открытым ордерам и составим небольшую статистику по сделкам текущей валютной пары.

Как и на прошлом занятии, информацию на экран мы будем выводить через функцию Comment. Создаем новый пользовательский индикатор как обычно. Даем ему имя, вносим в него свои данные программиста: имя автора, ссылку на ресурс. Если у вас нет сайта — укажите наш, почему бы и нет. Дополнительных параметров и функций добавлять не нужно, индикатор также должен отображаться на графике по умолчанию, а не в отдельном окне.

Данный индикатор будет простым, без внешних настроек extern, в следующем уроке мы его немного усложним, все постепенно.

Перед началом кодинга вам нужно открыть график любого торгового символа, на котором вы будете проверять работоспособность индикатора. Далее нужно открыть на демо счете несколько ордеров с разным торговым лотом. Давайте отправим заявку на 3 новых ордера на покупку и один на продажу, а также несколько отложенных ордеров любого типа. Все по одному символу. Цели выставлять не нужно. Без этих ордеров вы просто не сможете увидеть корректный результат работы нашего индикатора.

Ну что ж, начнем творить. Функцию обработки событий OnInit оставляем пустой. Добавляем вручную функцию OnDeinit, где обнулим информацию в Comment, чтобы после удаления индикатора с графика не осталось информации о его использовании.

Теперь перейдем к работе в функцию обработки событий OnCalculate. Так как цель данного кода в анализе всех открытых ордеров по текущей валютной паре, то нам нужно создать переменные для хранения необходимых нам данных. В первую очередь мы должны знать отдельно количество ордеров на покупки, продажи и сумму отложек. Подсчет количества чего-либо ведется целыми числами, без дробей, поэтому тип данных этих переменных будет int.

Соответственно переменная cnt_buy будет считать (count) сумму ордеров для покупок. Сейчас мы не знаем сумму, поэтому задаем ей значение, равное нулю. То же самое и с другими переменными. Для ускорения работы мы объявляем тип данных int в самом начале строки только один раз, а уже далее через запятую вводим их наименования и значения, завершая все точкой с запятой.

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

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

В итоге функция OnCalculate будет иметь вид:

Для анализа всех открытых ордеров (рыночных и отложенных) нам нужно воспользоваться оператором цикла for. Наша цель — перебором пробежаться по всем ордерам и разделить их на разные типы, после чего задать переменным известные значения. Прописываем цикл:

Перебор всех значений начинается с нуля, т.е. с самого первого открытого ордера. Заканчивается, когда будет достигнуто значение OrdersTotal(), т.е. суммарное значение всех открытых и отложенных ордеров. Шаг будет равен единице. Как мы знаем, цикл для ордеров начинается с нуля, а не с единицы, поэтому и заканчивается раньше, чем будет достигнуто значение переменной AllOrders во втором выражении. По другому этот цикл можно было бы написать так (смысл выражения бы не изменился):

Окей. Цикл запущен и уже работает, теперь нужно указать ему определенные действия. Перед началом работы с каждым ордером его нужно выделить, иначе невозможно узнать его тип, лот, профит и т.д. Выделение происходит через функцию OrderSelect. Выделять ордер можно как по индексу (в нашем случае по текущей итерации цикла: 0, 1, 2…), либо по тикету. Последний нам в данном случае неизвестен, поэтому мы работаем с индексом. Вторым параметром функции является Флаг способа выбора. Соответственно, если мы выбираем ордер по индексу, то прописывается флаг SELECT_BY_POS (выбор по позиции), а если по тикету, то SELECT_BY_TICKET. Последний третий параметр нужен, чтобы выбрать источник данных для ордеров: MODE_TRADES — текущие открытые и отложенные ордера, MODE_HISTORY — данные о закрытых и удаленных ордерах, а также информация о пополнение/снятии средств со счета, которая хранится во вкладке история. Данная функция имеет тип bool и возвращает true при успешном выделении ордера, и false при неудаче. Прописываем функцию в теле оператора for.

Мы добавили условие: если функция возвращает false, мы прерываем текущую итерацию и переходим к следующей с помощью оператора continue. При true работа продолжается. На практике не помню момента, чтобы ордер не был выделен, всегда все проходило гладко, но проверить нужно.

Ордер по списку выделен, теперь мы может узнать по нему всю необходимую информацию: тикет, магик номер, символ, цену открытия, цели, лот и т.д. 

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

Соответственно, если символ ордера не равен символу графика — итерация пропускается, данный ордер в расчет не берется. Далее нам нужно разделить все ордера на 3 типа: покупки, продажи и отложенные. Последние будет учитывать вместе, чтобы было проще. Для этого с помощью условных операторов if/else пропишем следующие строки:

Получается, что если тип выделенного ордера (OrderType) соответствует покупкам, т.е. значению предопределенной переменной OP_BUY, тогда выполняются действия в фигурных скобках данного оператора. Если же нет, то идет проверка на ордер на продажи. Если и это условие не выполняется, то остается только один вариант оператора else — это отложенные ордера.

Пришло время использовать объявленные нами в самом начале статьи переменные для подсчета количества ордеров, суммы лотов и прибыли в валюте депозита. Добавляем их в код последовательно, начиная с покупок:

cnt_buy++ обозначает, что мы каждый раз прибавляем единицу к счетчику ордеров, когда этот ордер на покупку. OrderLots() — функция, которая возвращает торговый лот текущего ордера. Чтобы узнать чистую прибыль на текущий момент, мы должны сложить три значения: прибыль выбранного ордера (OrderProfit), своп, который был начислен за перенос позиции на следующий день (OrderSwap), а также комиссию, которая была снята брокером в момент открытия ордера (OrderCommission)

Повторяем те же действия отдельно для продаж и отложенных ордеров. В итоге тело цикла for будет иметь следующий вид:

Мы закончили с частью, отвечающей за анализ ордеров. Теперь нужно вывести полученную информацию на экран, чтобы данные отображались каждый тик.

Вывод информации на график

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

Начнем через знак плюс (+) добавлять в нее описания и значения переменных, которые сразу же переведем в текстовый вид. Не забываем ставить знак \n для переноса текста на новую строчку. Начнем с покупок:

Мы указали, что данный блок отображает информацию для покупок, последовательно в каждой новой строке отображая: количество ордеров, суммарный лот и прибыль. Чтобы текст соответствовал значению прибыли или убытка, мы воспользовались оператором который определит, что для прибыльных ордеров нужно выводить текст «Суммарная прибыль», а для убыточных «Суммарный убыток». В конце строчки прописываем функцию AccountCurrency(), чтобы в конце числового выражения показывать валюту депозита.

Те же самые действия проделываем для продаж, прибавляя уже к объявленной переменной q дополнительные данные:

Для отложенных ордеров.

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

Готово, осталось вывести все это на экран:

Законченный индикатор будет выглядеть на графике так:

На этом все. Полный код находится по ссылке ниже. На следующем уроке мы немного усложним данный код дополнительными функциями.

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

0. Начало работы

Скачать код урока

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Заполните поле
Заполните поле
Пожалуйста, введите корректный адрес email.
Вы должны согласиться с условиями для продолжения

Меню