Español Português
preview
Моделирование рынка: Position View (V)

Моделирование рынка: Position View (V)

MetaTrader 5Тестер |
35 0
Daniel Jose
Daniel Jose

Введение

Здравствуйте и приветствую всех в очередной статье из серии о том, как создать систему репликации/моделирования.

В предыдущей статье, Моделирование рынка: Position View (IV), мы начали связывать индикатор позиции с тремя другими базовыми приложениями, которые уже существовали в сервисе репликации/моделирования. Хотя на данном начальном этапе мы сосредоточимся на использовании этих четырех приложений на демо-счете или на реальном счете. Тем не менее, я не рекомендую использовать эти приложения на реальном счете. По крайней мере, на данный момент, так как они всё ещё требуют некоторых доработок. Основная причина, по которой я не рекомендую использовать эти приложения на реальном счете, заключается как раз в том, что советник и индикатор позиции недостаточно стабильны для спокойного использования.

Что касается Chart Trade и индикатора мыши, то их использование на реальном счете не представляет проблем. Хотя сам по себе Chart Trade, без поддержки советника, абсолютно бесполезен.

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

Почему я это говорю? Дело в том, что у многих существует иллюзия, будто программирование — это непрерывное написание тонн кода. Хотя на самом деле это делается только после анализа различных данных и обдумывания возможного решения. Нередко программист проводит довольно много времени, анализируя файлы, которые он сам же возможно создал, чтобы понять, как всё это работает. Иногда эти файлы, то есть лог-файлы, заменяются сессией отладки, если существует такая возможность.

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


Первые проблемы

Несмотря на изложенное в предыдущей статье, это кажется чем-то простым. Там перед нами стоят различные проблемы и множество задач, которые нужно решить и выполнить. Вы, уважаемый читатель, можете представить, что всё легко и просто. По наивности вы просто принимаете то, что вам предлагают. И это ошибка, которой вам, уважаемый читатель, следует постараться избежать. Хуже простого принятия — непонимание и попытка использовать что-то без реального осознания того, что именно используется.

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

Итак, давайте разберем следующую проблему, с которой мы столкнулись. Как уже было показано в предыдущей статье, советник способен размещать индикатор позиции на графике. Этот индикатор запрашивает данные позиции, чтобы отобразить на графике линии, соответствующие позиции и ценовым уровням. До настоящего момента на первый взгляд нет никаких проблем, так как всё работает как и ожидалось. Однако в коде присутствуют некоторые дефекты, или, точнее, в том, как всё реализовано.

Предположим (а это то, что делают многие хорошие программисты — строят предположения), что трейдер снимает советник с графика. Или что он указывает советнику, который отслеживал полный контракт, переключиться на отслеживание открытых позиций по мини-контракту. Что в этих двух случаях произойдет на графике? Помните, что мы только начинаем со всем этим разбираться. Хорошо, в обоих упомянутых случаях у нас возникнут проблемы с индикатором позиции. Потому что в первом случае, когда советник будет удален с графика, все присутствующие индикаторы позиции останутся на графике. Это ошибка, так как у нас нет советника для поддержки системы, если трейдер захочет закрыть позицию. Механизмы, позволяющие сделать это путем прямого взаимодействия с индикатором позиции, ещё не реализованы, но это скоро будет сделано. Нам нужно начать обдумывать эту возможность уже сейчас. Это связано с тем, что, когда данный функционал будет действительно реализован, система уже будет тестироваться на предмет других, не менее важных аспектов, таких как случай удаления советника с графика.

Во втором случае, когда трейдер запрашивает смену вида контракта, сбой может быть ещё более серьезным, так как он вводит трейдера в заблуждение относительно того, что на самом деле происходит на торговом счете. Решение в обоих случаях, по сути, заключается в удалении всех индикаторов позиции, как только советник подвергается какому-либо вмешательству со стороны трейдера. Это вмешательство приведет к тому, что MetaTrader 5 сгенерирует событие DeInit, которое будет перехвачено советником в функции OnDeinit. Таким образом, решение заключается, по сути, в замене старого кода советника на новый. Однако, поскольку большая часть кода требует изменений, достаточно будет заменить фрагмент, приведенный ниже в коде советника, чтобы решить обе проблемы:

54. //+------------------------------------------------------------------+
55. void OnDeinit(const int reason)
56. {
57.     ulong ul;
58.     
59.     switch (reason)
60.     {
61.         case REASON_REMOVE:
62.         case REASON_INITFAILED:
63.             EventChartCustom(0, evEA_At_ChartTrade, -1, 0, "");
64.             break;
65.     }
66.     if (Terminal != NULL) for (int count = PositionsTotal() - 1; count >= 0; count--)
67.     {
68.         ul = PositionGetTicket(count);
69.         if (PositionGetString(POSITION_SYMBOL) != (*Terminal).GetInfoTerminal().szSymbol) continue;
70.         ChartIndicatorDelete(0, 0, IntegerToString(ul));
71.     }
72.     delete Orders;
73.     delete Terminal;
74. }
75. //+------------------------------------------------------------------+

Фрагмент из советника

Обратите внимание, что в этот код мы внесли некоторые изменения, как видно в строке 63. Изначально для получения пользовательских событий указывался идентификатор графика. При изучении документации с целью сокращения количества проверок в коде выяснилось, что при передаче параметра ZERO в качестве идентификатора графика пользовательские события будут направляться на текущий график, где и был инициирован вызов события. Благодаря этому нам не придется проверять указатель, чтобы проверить, был ли он инициализирован или нет. Однако на строке 66 этого не происходит. На данном этапе нам необходимо убедиться, что указатель был инициализирован. Если нет, мы игнорируем код между строками 66 и 71.

Теперь вопрос: что делает данный код? Этот код решает именно две проблемы, упомянутые выше. Обратите внимание, что при наличии открытой позиции на графике будет отображаться индикатор позиции. Когда советник получает от MetaTrader 5 событие DeInit, вызывается функция, показанная в приведенном выше фрагменте. В строке 68 мы получаем данные о позиции из ее индекса. После этого в строке 69 мы проверяем, совпадает ли символ позиции с символом, ожидаемым советником. Поэтому нам необходимо, чтобы переменная Terminal была инициализирована. Иначе мы не смогли бы получить правильное имя для символа.

Если символ соответствует ожидаемому, в строке 70 мы указываем MetaTrader 5 удалить с графика индикатор, имя которого совпадает с тикетом позиции. "Но подождите секунду. Когда я открываю список индикаторов, я не вижу ни одного индикатора с таким именем. То есть там нет ни одного индикатора, имя которого совпадало бы со значением тикета позиции". Вы правы, мой уважаемый читатель. Дело в том, что в индикаторе позиции мы указываем имя, которое MetaTrader 5 будет понимать как имя индикатора. Именно это имя мы должны указать здесь, в строке 70.

Отлично, проблема решена. Однако, несмотря на то что эта проблема решена, из-за одной детали, которую я упустил из виду, возникает потенциальный сбой в случае, если трейдер изменит таймфрейм при запущенном на графике советнике. Этот сбой вызовет ошибку выполнения (runtime error), приведет к выгрузке советника с графика и зафиксирует ошибку в терминале MetaTrader 5.

Как правило, и это довольно распространенное явление, мы можем получить аналогичную ошибку времени выполнения в программах на C/C++ при работе с указателями, если попытаемся использовать указатель, который не инициализирован. "Но подождите. В предыдущей статье упоминалось, что указатели инициализируются значением NULL". Да, они инициализируются этим значением. Однако при смене таймфрейма приложение не перезапускается с нуля, как можно было бы ожидать, повторная инициализация начинается с функции OnInit. При этом указатель, который инициализировался в глобальном контексте, больше не будет инициализироваться корректно.

Таким образом, работа приложения в целом подвергается серьезному риску, так как мы имеем дело с указателем, который ссылается на неизвестную область памяти. Именно поэтому в MQL5 использование указателей ограничено, чтобы избежать подобных ошибок. Но поскольку мы действительно хотим и нуждаемся в использовании указателей, нам также необходимо исправить данный недостаток. Однако это очень легко исправить, как показано в следующем фрагменте кода.

13. //+------------------------------------------------------------------+
14. input eTypeContract user00 = MINI;         //Cross order in contract
15. //+------------------------------------------------------------------+
16. C_Orders       *Orders;
17. C_Terminal     *Terminal;
18. //+------------------------------------------------------------------+
19. int OnInit()
20. {
21.     Terminal = NULL;
22.     Orders = new C_Orders(0xC0DEDAFE78514269);
23.     
24.     return INIT_SUCCEEDED;
25. }
26. //+------------------------------------------------------------------+

Фрагмент из советника

Посмотрите на строку 21. Именно она исправляет проблему. Сравните этот предыдущий фрагмент с оригинальным кодом из прошлой статьи, и вы поймете, что здесь изменилось. Один нюанс: строки находятся на тех же позициях, что и в оригинале. Итак, три потенциальные ошибки исправлены. Но мы всё ещё не дошли до действительно сложных проблем. Чтобы немного разграничить темы, рассмотрим первую из этих проблем в новом разделе.


Проблема, имеющая множество решений

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

На счетах типа HEDGING понятие средней цены отсутствует на торговом сервере. Это относится только к трейдеру, так как у вас может быть открыто несколько различных позиций, одни из них длинные (Buy), другие короткие (Sell). Хорошо. Каждая из них может иметь совершенно разный объем, а также разную цену открытия позиции. Выполнив расчет на основе цены и объема каждой из позиций, вы получите определенное значение. Это и есть значение средних цены и объема. Такой расчет трейдер должен выполнять самостоятельно, если счет относится к типу HEDGING.

Напротив, на счетах типа NETTING ситуация несколько иная. В этом случае средняя цена, а также совокупный объем, передаются и поддерживаются торговым сервером. Обратите внимание на масштаб проблемы, с которой мы сталкиваемся при попытке создать сервис репликации/моделирования. Было бы гораздо проще создать его, сделав так, чтобы все операции выполнялись на счетах типа NETTING. Необходимость охватить оба типа счетов создает ряд сложностей, которые вынуждают нас отложить завершение проекта.

Так и в чём же проблема? Проблема в том, что в отличие от открытия новой позиции на счете типа HEDGING, при выполнении этого действия на счете типа NETTING средняя цена, как и объем, меняется. В случае с объемом решение является простым, хотя мы его ещё не рассматривали. Но в случае с проблемой цены ситуация выглядит несколько сложнее. Это связано с тем, что сложно удерживать индикатор позиции привязанным к одной цене. Возможно, это предложение прозвучало странно. Но подумайте вот о чем: когда средняя цена позиции меняется на сервере, советник узнает об этом. Однако индикатор позиции — нет. Это наша первая проблема.

Есть и другие, но мы начнем именно с нее. Можно подумать: "Хорошо, всё, что нужно сделать, это заставить индикатор позиции следовать за тем, что происходит в позиции. Всё очень просто". Однако, уважаемый читатель, на практике дела обстоят совсем иначе. Если вы настроите индикатор позиции на отслеживание изменений в позиции, вам придется делать это через событие OnTimer, что совершенно не рекомендуется, либо через событие OnCalculate, что также нежелательно. Я не говорю, что вы не можете это сделать. Я просто указываю на то, что это нежелательно, так как может привести к неисправности, из-за которой индикатор заблокируется. Также это может заблокировать все остальные индикаторы на графике символа. Проще говоря, это крайне неудачное решение.

Хорошо, в этом случае можно немного поразмышлять и сказать: "Мы можем получить доступ к объекту HLINE и изменить его положение в коде советника". Это было бы хорошим решением, но у него есть ещё одна проблема. Объект HLINE — это лишь один из объектов, который нам понадобится и который мы будем использовать внутри индикатора позиции. Следовательно, от этого решения следует отказаться. Индикатор позиции должен быть тем, кто управляет объектами, и больше никем другим.

Думаю, на этом этапе вы уже, вероятно, думаете: "Какой же вы настойчивый. Зачем всё так усложнять? Сделайте всё проще". Иногда я даже подумываю об этом, но мне нравятся трудности. Моё предложение может вызвать у вас головную боль. Потому что сейчас мы погрузимся в мир, который для многих новичков окажется совершенно неизведанным. Однако для тех, кто зарабатывает этим на жизнь, это вполне привычный мир. Давайте разберем, как создавать и интерпретировать лог-файлы. Простейшее решение — использовать функцию OnTradeTransaction для решения нашей проблемы. Потому что она вызывается только тогда, когда что-то происходит. Сервер сообщает нам с точностью, что произошло, поэтому нам нет необходимости расследовать это.

Но поскольку функция OnTradeTransaction довольно сложная, нам необходимо создать лог-файл, чтобы понять, что происходит при увеличении позиции. Обратите внимание на это. Я покажу, что происходит, когда открывается позиция, а вскоре после этого увеличиваем её объём. В итоге мы полностью закрываем позицию. Всё это делается с помощью советника, индикатора мыши и функции Chart Trade, которые мы уже разработали. На начальном этапе мы не будем беспокоиться об индикаторе позиции.

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

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property icon "/Images/Market Replay/Icons/Replay - EA.ico"
04. #property description "Demo version between interaction"
05. #property description "of Chart Trade and Expert Advisor"
06. #property version   "1.117"
07. #property link "https://www.mql5.com/pt/articles/13176"
08. //+------------------------------------------------------------------+
09. #include <Market Replay\Order System\C_Orders.mqh>
10. #include <Market Replay\Auxiliar\C_Terminal.mqh>
11. //+------------------------------------------------------------------+
12. enum eTypeContract {MINI, FULL};
13. //+------------------------------------------------------------------+
14. input eTypeContract user00 = MINI;         //Cross order in contract
15. //+------------------------------------------------------------------+
16. C_Orders       *Orders;
17. C_Terminal     *Terminal;
18. //+------------------------------------------------------------------+
19. void AddIndicatorPosition(ulong arg)
20. {
21.     int handle = iCustom(_Symbol, PERIOD_CURRENT, "\\Indicators\\Position View.ex5", arg);
22.     ChartIndicatorAdd(0, 0, handle);
23.     IndicatorRelease(handle);
24. }
25. //+------------------------------------------------------------------+
26. int OnInit()
27. {
28.     Print("Initializing the Expert Advisor...");
29.     Terminal = NULL;
30.     Orders = new C_Orders(0);
31.     
32.     return INIT_SUCCEEDED;
33. }
34. //+------------------------------------------------------------------+
35. void OnTick() {}
36. //+------------------------------------------------------------------+
37. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
38. {
39.     (*Orders).DispatchMessage(id, lparam, dparam, sparam);
40.     switch (id)
41.     {
42.         case CHARTEVENT_CHART_CHANGE:
43.             if (Terminal != NULL) break;
44.             else
45.             {
46.                 ulong ul;
47.                 Terminal = new C_Terminal(0, 0, user00);
48.                 for (int count = PositionsTotal() - 1; count >= 0; count--)
49.                 {
50.                     ul = PositionGetTicket(count);
51.                     if (PositionGetString(POSITION_SYMBOL) != (*Terminal).GetInfoTerminal().szSymbol) continue;
52.                     AddIndicatorPosition(ul);
53.                 }
54.             }
55.         case CHARTEVENT_CUSTOM + evChartTrade_At_EA:
56.             EventChartCustom(0, evEA_At_ChartTrade, user00, 0, "");
57.             break;
58.     }
59. }
60. //+------------------------------------------------------------------+
61. void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result)
62. {
63.     Print(__FUNCTION__);
64. 
65.     MqlTradeTransaction ts[1];
66.     ts[0] = trans;
67.     ArrayPrint(ts);
68. 
69.     MqlTradeRequest tr[1];
70.     tr[0] = request;
71.     ArrayPrint(tr);
72. 
73.     MqlTradeResult rs[1];
74.     rs[0] = result;
75.     ArrayPrint(rs);
76. }
77. //+------------------------------------------------------------------+
78. void OnDeinit(const int reason)
79. {
80.     ulong ul;
81.     
82.     switch (reason)
83.     {
84.         case REASON_REMOVE:
85.         case REASON_INITFAILED:
86.             EventChartCustom(0, evEA_At_ChartTrade, -1, 0, "");
87.             break;
88.     }
89.     if (Terminal != NULL) for (int count = PositionsTotal() - 1; count >= 0; count--)
90.     {
91.         ul = PositionGetTicket(count);
92.         if (PositionGetString(POSITION_SYMBOL) != (*Terminal).GetInfoTerminal().szSymbol) continue;
93.         ChartIndicatorDelete(0, 0, IntegerToString(ul));
94.     }
95.     delete Orders;
96.     delete Terminal;
97. }
98. //+------------------------------------------------------------------+

Советник для создания логов

Глядя на этот код, вы, уважаемый читатель, можете подумать следующее: "Да ладно, ты с ума сошёл. Данный код не генерирует никаких диагностических данных для понимания того, что происходит в функции OnTradeTransaction. Так ли это?" Итак, после выполнения этого кода в MetaTrader 5 был сгенерирован следующий лог-файл:

OK      0       12:05:36.509    Expert Advisor (WDO$,M30)       Initializing the Expert Advisor...
HO      0       12:05:48.773    Chart Trade (WDO$,M30)  Send evChartTradeBuy - Args ( 10?WDO$?WDOU23?D?1?0.00?0.00 )
QH      0       12:05:48.773    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume]  [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration]                             [comment] [position] [position_by] [reserved]
FK      0       12:05:48.774    Expert Advisor (WDO$,M30)       [0]        1       0       0 "WDOU23"    1.000 4975.000       0.000 0.00 0.00        1000      0              2           1 1970.01.01 00:00:00 "Order Generated by Experts Advisor."          0             0        ...
QM      0       12:05:48.797    Expert Advisor (WDO$,M30)       OnTradeTransaction
GF      0       12:05:48.797    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
DS      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]      0 1612507881 "WDOU23"      0            0             0           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    1.000          0             0        ...
GQ      0       12:05:48.797    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
OL      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
CO      0       12:05:48.797    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
DL      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
ER      0       12:05:48.797    Expert Advisor (WDO$,M30)       OnTradeTransaction
KK      0       12:05:48.797    Expert Advisor (WDO$,M30)               [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration]  [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
JI      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0] 1191195305 1612507881 "WDOU23"      6            0             0           0           0 1970.01.01 00:00:00 4975.000           0.000      0.000      0.000    1.000 1612507881             0        ...
GI      0       12:05:48.797    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
OD      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
CG      0       12:05:48.797    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
DD      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
EJ      0       12:05:48.797    Expert Advisor (WDO$,M30)       OnTradeTransaction
KQ      0       12:05:48.797    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
PP      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]      0 1612507881 "WDOU23"      2            0             4           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000 1612507881             0        ...
CP      0       12:05:48.797    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
CN      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
GH      0       12:05:48.797    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
HM      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
IS      0       12:05:48.797    Expert Advisor (WDO$,M30)       OnTradeTransaction
OH      0       12:05:48.797    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
KI      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]      0 1612507881 "WDOU23"      3            0             4           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000 1612507881             0        ...
OG      0       12:05:48.797    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
GG      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
KR      0       12:05:48.797    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
LF      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
MI      0       12:05:48.797    Expert Advisor (WDO$,M30)       OnTradeTransaction
CP      0       12:05:48.797    Expert Advisor (WDO$,M30)           [deal] [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
PM      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]      0       0 ""           10            0             0           0           0 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000          0             0        ...
OO      0       12:05:48.797    Expert Advisor (WDO$,M30)           [action] [magic]    [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration]                         [comment] [position] [position_by] [reserved]
EQ      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]        1       0 1612507881 "WDOU23"    1.000   0.000       0.000 0.00 0.00        1000      0              2           1 1970.01.01 00:00:00 "Order Generated by Experts Advi"          0             0        ...
OM      0       12:05:48.797    Expert Advisor (WDO$,M30)           [retcode]     [deal]    [order] [volume]  [price]    [bid]    [ask] [comment] [request_id] [retcode_external] [reserved]
MP      0       12:05:48.797    Expert Advisor (WDO$,M30)       [0]     10009 1191195305 1612507881    1.000 4975.000 4974.500 4975.000 ""          3531297432                  0        ...
EK      0       12:05:53.264    Chart Trade (WDO$,M30)  Send evChartTradeBuy - Args ( 10?WDO$?WDOU23?D?1?0.00?0.00 )
HG      0       12:05:53.264    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume]  [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration]                             [comment] [position] [position_by] [reserved]
RF      0       12:05:53.264    Expert Advisor (WDO$,M30)       [0]        1       0       0 "WDOU23"    1.000 4974.500       0.000 0.00 0.00        1000      0              2           1 1970.01.01 00:00:00 "Order Generated by Experts Advisor."          0             0        ...
EF      0       12:05:53.287    Expert Advisor (WDO$,M30)       OnTradeTransaction
KM      0       12:05:53.287    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
EN      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]      0 1612507912 "WDOU23"      0            0             0           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    1.000          0             0        ...
KL      0       12:05:53.287    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
CI      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
OD      0       12:05:53.287    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
PI      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
QO      0       12:05:53.287    Expert Advisor (WDO$,M30)       OnTradeTransaction
GF      0       12:05:53.287    Expert Advisor (WDO$,M30)               [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration]  [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
HF      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0] 1191195326 1612507912 "WDOU23"      6            0             0           0           0 1970.01.01 00:00:00 4974.500           0.000      0.000      0.000    1.000 1612507881             0        ...
KD      0       12:05:53.287    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
CQ      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
OL      0       12:05:53.287    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
PQ      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
QG      0       12:05:53.287    Expert Advisor (WDO$,M30)       OnTradeTransaction
GL      0       12:05:53.287    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
IL      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]      0 1612507912 "WDOU23"      2            0             4           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000 1612507881             0        ...
OK      0       12:05:53.287    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
OK      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
KE      0       12:05:53.287    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
LJ      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
ML      0       12:05:53.287    Expert Advisor (WDO$,M30)       OnTradeTransaction
CG      0       12:05:53.287    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
NR      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]      0 1612507912 "WDOU23"      3            0             4           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000 1612507881             0        ...
CR      0       12:05:53.287    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
KL      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
GO      0       12:05:53.287    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
HS      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
IR      0       12:05:53.287    Expert Advisor (WDO$,M30)       OnTradeTransaction
OK      0       12:05:53.287    Expert Advisor (WDO$,M30)           [deal] [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
DH      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]      0       0 ""           10            0             0           0           0 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000          0             0        ...
CJ      0       12:05:53.287    Expert Advisor (WDO$,M30)           [action] [magic]    [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration]                         [comment] [position] [position_by] [reserved]
LE      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]        1       0 1612507912 "WDOU23"    1.000   0.000       0.000 0.00 0.00        1000      0              2           1 1970.01.01 00:00:00 "Order Generated by Experts Advi"          0             0        ...
CJ      0       12:05:53.287    Expert Advisor (WDO$,M30)           [retcode]     [deal]    [order] [volume]  [price]    [bid]    [ask] [comment] [request_id] [retcode_external] [reserved]
KM      0       12:05:53.287    Expert Advisor (WDO$,M30)       [0]     10009 1191195326 1612507912    1.000 4974.500 4974.000 4974.500 ""          3531297433                  0        ...
JI      0       12:06:04.628    Chart Trade (WDO$,M30)  Send evChartTradeSell - Args ( 11?WDO$?WDOU23?D?2?0.00?0.00 )
GS      0       12:06:04.628    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume]  [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration]                             [comment] [position] [position_by] [reserved]
LR      0       12:06:04.628    Expert Advisor (WDO$,M30)       [0]        1       0       0 "WDOU23"    2.000 4974.000       0.000 0.00 0.00        1000      1              2           1 1970.01.01 00:00:00 "Order Generated by Experts Advisor."          0             0        ...
NS      0       12:06:04.652    Expert Advisor (WDO$,M30)       OnTradeTransaction
DH      0       12:06:04.652    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
HI      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]      0 1612508010 "WDOU23"      0            1             0           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    2.000          0             0        ...
LH      0       12:06:04.652    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
LF      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
PQ      0       12:06:04.652    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
OE      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
RH      0       12:06:04.652    Expert Advisor (WDO$,M30)       OnTradeTransaction
HQ      0       12:06:04.652    Expert Advisor (WDO$,M30)               [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration]  [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
OS      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0] 1191195411 1612508010 "WDOU23"      6            0             0           1           0 1970.01.01 00:00:00 4974.000           0.000      0.000      0.000    2.000 1612507881             0        ...
LP      0       12:06:04.652    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
LN      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
PI      0       12:06:04.652    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
OM      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
RP      0       12:06:04.652    Expert Advisor (WDO$,M30)       OnTradeTransaction
HK      0       12:06:04.652    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
MI      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]      0 1612508010 "WDOU23"      2            1             4           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000 1612507881             0        ...
HF      0       12:06:04.652    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
PG      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
DR      0       12:06:04.652    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
CG      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
FI      0       12:06:04.652    Expert Advisor (WDO$,M30)       OnTradeTransaction
LR      0       12:06:04.652    Expert Advisor (WDO$,M30)           [deal]    [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
RN      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]      0 1612508010 "WDOU23"      3            1             4           0           1 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000 1612507881             0        ...
DM      0       12:06:04.652    Expert Advisor (WDO$,M30)           [action] [magic] [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration] [comment] [position] [position_by] [reserved]
DI      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]        0       0       0 ""          0.000   0.000       0.000 0.00 0.00           0      0              0           0 1970.01.01 00:00:00 ""                 0             0        ...
HK      0       12:06:04.652    Expert Advisor (WDO$,M30)           [retcode] [deal] [order] [volume] [price] [bid] [ask] [comment] [request_id] [retcode_external] [reserved]
GH      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]         0      0       0    0.000   0.000 0.000 0.000 ""                   0                  0        ...
JN      0       12:06:04.652    Expert Advisor (WDO$,M30)       OnTradeTransaction
PG      0       12:06:04.652    Expert Advisor (WDO$,M30)           [deal] [order] [symbol] [type] [order_type] [order_state] [deal_type] [time_type]   [time_expiration] [price] [price_trigger] [price_sl] [price_tp] [volume] [position] [position_by] [reserved]
KG      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]      0       0 ""           10            0             0           0           0 1970.01.01 00:00:00   0.000           0.000      0.000      0.000    0.000          0             0        ...
DQ      0       12:06:04.652    Expert Advisor (WDO$,M30)           [action] [magic]    [order] [symbol] [volume] [price] [stoplimit] [sl] [tp] [deviation] [type] [type_filling] [type_time]        [expiration]                         [comment] [position] [position_by] [reserved]
IH      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]        1       0 1612508010 "WDOU23"    2.000   0.000       0.000 0.00 0.00        1000      1              2           1 1970.01.01 00:00:00 "Order Generated by Experts Advi"          0             0        ...
LG      0       12:06:04.652    Expert Advisor (WDO$,M30)           [retcode]     [deal]    [order] [volume]  [price]    [bid]    [ask] [comment] [request_id] [retcode_external] [reserved]
RI      0       12:06:04.652    Expert Advisor (WDO$,M30)       [0]     10009 1191195411 1612508010    2.000 4974.000 4974.000 4974.500 ""          3531297434                  0        ...

Лог-файл операций

Вам понравилось то, что вы видите? Я знаю, что этот лог-файл выглядит кошмарно Он похож на совершенно безумное и бессмысленное деяние. Но поверьте, как я уже говорил, мы здесь проведем всего три операции. Каждое из значений, которые вы видите, имеет свой смысл. Поэтому, прежде чем вы опустите руки, давайте посмотрим, как именно был сгенерирован этот файл. Обратите внимание, что строка 01 — это в точности строка 28 кода советника. Иными словами, записывается всё, что отображается в терминале MetaTrader 5. Несмотря ни на что, это делаю не я, а MetaTrader 5.

Теперь взгляните на строку 02 лог-файла. Обратите внимание на источник данных. Другими словами, это Chart Trade. В этот момент Chart Trade отправил сообщение советнику об открытии рыночной позиции. Прошу заметить, что это сообщение повторяется ещё два раза. Между этими сообщениями видно, что именно делает советник при работе с реальным торговым сервером. Представленные данные были сгенерированы в функции OnTradeTransaction с использованием строк 63, 67, 71 и 75. Смотрите и учитесь.

Каждый раз, когда сервер отправляет ответ в MetaTrader 5, в логе будет отображаться имя функции OnTradeTransaction. Обратите внимание, что в общении прослеживается определенная закономерность. То есть советник отправляет запрос на сервер, и тот незамедлительно возвращает ответ. Каждый из ответов перехватывается функцией OnTradeTransaction, и значения выводятся в следующем порядке: сначала данные структуры MqlTradeTransaction, затем данные структуры MqlTradeRequest и, наконец, данные структуры MqlTradeResult. Это повторяется сообщение за сообщением со стороны сервера.

Но давайте вернемся к коду советника, чтобы понять, как я это сделал. Обратите внимание, что данные о структурах выводятся с помощью функции ArrayPrint. "Но как это возможно? Вы используете ArrayPrint для вывода данных в терминал? Да ладно, вы совсем с ума сошли. Я подумал, что необходимо объявить обо всех этих полях каждой из структур, но вы действительно превзошли уровень сложности и использования MQL5. Я тут пишу тонны кода один за другим, а ты мне выдаешь такое".

Что ж, как я уже говорил, решать всё простым путем неинтересно. Вся прелесть заключается в том, чтобы вывести использование языка на новый уровень. Но теперь возникает вопрос, имеют ли все эти значения из лога хоть какой-то смысл для вас? Если даже после этого их сложно понять, мы можем выгрузить их в базу данных SQL и получить более простую структуру. Для этого мы будем использовать три разные таблицы внутри базы данных. Но это остаётся в качестве домашнего задания. Вы ведь не думали, что я преподнесу вам всё на блюде, правда?

Когда вы изучите эти данные, вы заметите, что значения некоторых полей указывают на действия, выполняемые сервером. В определенный момент сервер сформирует ордер, который будет исполнен по рыночной цене. В этом случае будет создан тикет: 1612507881, с объемом 1 и операцией типа ноль. Иными словами, покупка по рынку. На данный момент у нас нет открытых позиции. Значение в поле Позиция равно нулю. Так будет продолжаться до тех пор, пока поле type структуры MqlTradeTransaction не примет значение 6. То есть сервер отправит перечисление TRADE_TRANSACTION_DEAL_ADD в MetaTrader 5. В этот момент поле Позиция перестанет быть нулем и примет то же значение, что и ордер, созданный на сервере.

После этого сервер генерирует событие 2, которое представляет собой TRADE_TRANSACTION_ORDER_DELETE. В этот момент созданный сервером ордер перестанет существовать. Затем событие 3, которое представляет собой TRADE_TRANSACTION_HISTORY_ADD, регистрирует в истории действия, выполненные на сервере. Наконец, генерируется событие 10, которое представляет собой TRADE_TRANSACTION_REQUEST. Это событие завершает процесс открытия позиции. Но я хочу, чтобы вы обратили внимание на значение созданного тикета. Это важно, поскольку в следующем цикле выполнения запроса, поступающего от Chart Trade, это значение появится снова. Обратите внимание, что значение ордера, созданного сервером, отличается. Однако значение этой позиции сохраняется.

По окончании второго цикла мы получим на сервере позицию с объемом в 2 лота. Теперь нам нужно закрыть позицию. Это происходит в третьем цикле, показанном в логе. Ещё раз отметим, что значение тикета позиции остается неизменным на протяжении всей процедуры.

Здесь возникает интересный момент: можно заметить, что сервер ни разу не вернул нам значение типа 8. В этом случае это будет означать TRADE_TRANSACTION_DEAL_DELETE, что эквивалентно второму типу. Второй тип ордера встречается довольно часто именно потому, что это рыночный ордер. Таким образом, мы можем использовать эти данные лога для реализации обработчика OnTradeTransaction, что избавит нас от необходимости постоянно сканировать в цикле весь список активных ордеров или открытых позиций. В случае с позициями это, возможно, не имеет ни малейшего смысла, если мы работаем на счете типа NETTING. Однако, поскольку мы хотим обобщить систему управления, нам необходимо, чтобы советник мог корректно обрабатывать все возможные сценарии. Хотя некоторые из них могут потребовать немного больше работы при реализации.

Хорошо. На этом этапе у вас, возможно, возникнут следующие мысли: "Хорошо. Вы показали все эти цифры и способы получения данных, которые мы можем использовать для программирования советника. Но я до сих пор не могу до конца понять, как всё это будет использоваться на практике для управления и организации связи между советником и индикатором позиции. На мой взгляд, то, что вы делаете, совершенно бессмысленно. На вашем месте я бы поступил гораздо проще". Если вы так думаете, я должен с вами согласиться. Да, было бы гораздо проще сделать это другим способом, но я не хочу делать очевидные вещи. Я хочу сделать это совершенно новым, неизведанным способом, который при этом будет полностью работоспособен в любой ситуации, какая только может возникнуть в будущем.

Запомните одно: мы не разрабатываем приложение, которое будет постоянно работать параллельно с торговым сервером. Мы разрабатываем систему, которая будет имитировать работу торгового сервера. Это решение требует совершенно иного подхода к реализации того, что вы, скорее всего, уже привыкли видеть в прежних реализациях. Мы больше не можем использовать такие функции, как PositionsTotal, чтобы узнать, что происходит. При использовании системы репликации/моделирования мы не сможем рассчитывать на помощь или поддержку этих функций. Нам необходимо выбрать совершенно иные пути, нежели те, которые многие считают наиболее разумным вариантом действий.


Заключительные идеи

Некоторое время назад я уже писал статью о том, как использовать функцию OnTradeTransaction. С тех пор многое изменилось в моем понимании MetaTrader 5 и MQL5. Поэтому сейчас я демонстрирую те нюансы, которые на тот момент не планировал раскрывать. Это связано с тем, что я заметил растущий интерес к этой теме со стороны начинающих разработчиков и энтузиастов, которые пытаются понять, почему мой код имеет столь экзотический и нешаблонный вид. Я искренне надеюсь, что эти статьи помогают всем понять, что мы можем сделать гораздо больше, чем многие считают возможным.

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

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

Файл Описание
Experts\Expert Advisor.mq5
Демонстрирует взаимодействие между Chart Trade и советником (для взаимодействия требуется Mouse Study).
Indicators\Chart Trade.mq5 Создает окно для настройки отправляемого ордера (для взаимодействия требуется Mouse Study)
Indicators\Market Replay.mq5 Создает элементы управления для взаимодействия с сервисом репликации/моделирования (для взаимодействия требуется Mouse Study).
Indicators\Mouse Study.mq5 Это обеспечивает взаимодействие между графическими элементами управления и пользователем (необходимое как для работы сервиса репликации/моделирования, так и на реальном рынке).
Indicators\Order Indicator.mq5 Отвечает за размещение рыночных ордеров, обеспечивая взаимодействие с ними и контроль над ними.
Indicators\Position View.mq5 Отвечает за определение рыночных позиций, обеспечение взаимодействия с ними и контроль над ними.
Services\Market Replay.mq5 Создает и поддерживает сервис репликации/моделирования рынка (главный файл всей системы).


Перевод с португальского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/pt/articles/13176

Прикрепленные файлы |
Anexo.zip (779.24 KB)
Особенности написания Пользовательских Индикаторов Особенности написания Пользовательских Индикаторов
Написание пользовательских индикаторов в торговой системе MetaTrader 4
От начального до среднего уровня: Произвольный доступ (I) От начального до среднего уровня: Произвольный доступ (I)
В сегодняшней статье мы впервые столкнемся с произвольным доступом к содержимому файла. Это относится как к записи, так и к чтению информации и данных, хранящихся в файле. Однако, поскольку эта тема достаточно обширна, чтобы осветить её в одной статье, здесь мы ограничимся лишь вводным описанием вопроса произвольного доступа.
Особенности написания экспертов Особенности написания экспертов
Написание и тестирование экспертов в торговой системе MetaTrader 4.
Рыночные секреты Ларри Уильямса (Часть 10): Автоматизация  паттернов разворота Smash Day Рыночные секреты Ларри Уильямса (Часть 10): Автоматизация паттернов разворота Smash Day
Мы реализуем разворотные паттерны Smash Day Ларри Уильямса в MQL5, создавая советник на основе правил с динамическим управлением риском, логикой подтверждения пробоя и исполнением по принципу «одна сделка за раз». Читатели смогут провести бэктест, воспроизвести результаты и изучить влияние параметров с помощью тестера стратегий MetaTrader 5 и предоставленного исходного кода.