Обсуждение статьи "Сделайте торговые графики лучше с интерактивным графическим интерфейсом на основе MQL5 (Часть III): Простой перемещаемый торговый интерфейс"

 

Опубликована статья Сделайте торговые графики лучше с интерактивным графическим интерфейсом на основе MQL5 (Часть III): Простой перемещаемый торговый интерфейс:

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

Для начала давайте вспомним, что мы рассмотрели в предыдущих двух частях:

1. В первой части мы рассмотрели концепцию событий графика, а затем создали две простые перемещаемые панели на одном графике.

2. Во второй части мы пошли еще дальше. Мы использовали классы в файле .mqh, чтобы сделать наш код более эффективным и универсальным, готовым к интеграции с полномасштабными советниками/индикаторами.


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

Автор: Kailash Bai Mina

 

Привет, Калиш,


Интересный подход и поздравления с завершением серии. Кодирование OnEvent - это то, что делает все это реальностью! Поскольку ваша первая статья меня заинтересовала, я разработал свою версию подвижной панели. Это базовый класс, который наследуется отдельными классами для каждого типа панели.Во-вторых, поскольку я уже создал заголовочный файл элементов управления, основанный на примерах в файле справки MQL, я решил использовать его вместо создания класса Text для наследования, и он отлично сработал. Я планирую создать еще два метода для класса GUI, Save и Initialize. Save будет считывать и обновлять CSV-файл и устанавливать начальные позиции и данные. Initialize будет считывать CSV-файл и устанавливать начальные позиции.

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


Удачи вам в ваших будущих начинаниях, я буду наблюдать.


Кейп-Кодда

Файлы:
 

Статья была очень хорошей. Хорошо дидактична и объяснена. Мне понравилось. 😁👍

 
CapeCoddah элементов управления, основанный на примерах в файле справки MQL, я решил использовать его вместо создания класса Text для наследования, и он хорошо работает. Я планирую создать еще два метода для класса GUI, Save и Initialize. Save будет считывать и обновлять CSV-файл и устанавливать начальные позиции и данные. Initialize будет считывать CSV-файл и устанавливать начальные позиции.

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


Удачи вам в ваших будущих начинаниях, я буду наблюдать.


Мыс Кодда

Я рад, что мои статьи приносят вам пользу.

На самом деле вы мотивировали меня написать эту часть 3, иначе из-за отсутствия мотивации это заняло бы больше времени.

Спасибо вам большое за это.

Удачи и вам в ваших будущих начинаниях.

 
Daniel Jose #:

Статья была очень хорошей. Хорошо дидактична и объяснена. Мне понравилось. 😁👍

Мне очень приятно. Спасибо, что уделили время.

 

Привет, Кайлаш,

Я надеюсь, что вы следите за этой статьей, так как я не знаю, как отправить сообщение в приват.

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

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

clsGUI  GUI;
clsAO   AO;
clsBOB  BOB;
clsCTL  CTL;
clsXO   XO;
clsATR  ATR;
clsRSI  RSI;
clsMM   MM;
clsTS   TS;

//clsAO Guis[egElements];
//clsGui GuiS[egElements];
//объект Guis[egElements];

Хотя такой подход вполне адекватен, он приводит к появлению множества отдельных функций для обработки различных задач в панелях EA. Более эффективным подходом было бы создание массива дочерних классов и использование его в качестве параметра при сокращении вызовов функций. Я пробовал использовать первые два подхода, но не могу привести элементы массива к соответствующему дочернему классу, чтобы вызвать его уникальные публичные функции.Я добился ограниченного успеха в доступе к публичным переменным, используя класс-обертку с объявлением объекта. Этот подход, похоже, использует определение класса элемента параметра, а не определение класса массива.

int Wrapper(object &theobject){

return(theobject.aninteger):

}

int i=Wrapper(Guis[5]);

Этот подход не работает для Guis[5].Create_Controls(......);

Единственный подход, который я видел, который работает, это использовать c_array для создания массива указателей объектов и добавить их в массив. а затем получить доступ с помощью функции, которая вызывает функцию c_array AT(location) для присвоения указателя массива локальному указателю объекта, объявленного локально, чтобы получить доступ к дочерним переменным локально.

Знаете ли вы или кто-либо другой, как решить эту проблему или дать ссылку на статьи или документацию по MQL, в которых рассматривается массив дочерних классов, а не массив одного класса?

Большое спасибо и с нетерпением жду ваших следующих статей.

CapeCoddah

 

Наглядный пример использования ООП ради ООП.

Получилось громоздко и не удобно (ИМХО). Но работает, а это уже хорошо :)


Нужно добавить OBJPROP_ZORDER иначе кнопки нажимаются через раз.

void Button::Create(string name, int xDis = 0, int yDis = 0, int xSize = 0, int ySize = 0)
  {
   ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, xDis);
   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, yDis);
   ObjectSetInteger(0, name, OBJPROP_XSIZE, xSize);
   ObjectSetInteger(0, name, OBJPROP_YSIZE, ySize);
   ObjectSetInteger(0, name, OBJPROP_ZORDER, 1);
   _name = name;
  }
//+------------------------------------------------------------------+
 
Alexander Slavskii #:
ut it works, which is good :)

Thanks for the suggestion.

 
Aleksandr Slavskii #:

Наглядный пример использования ООП ради ООП.

Получилось громоздко и не удобно (ИМХО). Но работает, а это уже хорошо :)


Нужно добавить OBJPROP_ZORDER иначе кнопки нажимаются через раз.

это вообще не ООП. Это повторно завёрнутые в классы методы терминала. 

если программист захочет сделать иной GUI (модный http, через WebSocket освещённый в прочих статьях), то ничего сделать не сможет. Просто выбросит вообще весь код из статьи и напишет иной.

чтобы коренным образом поменять визуальную часть, но на тех-же ObjectCreate(xx) - всё равно придётся переписывать просто всё.

или как отключить GUI, чтобы он не занимал процессор на VDS-ке

Где reusability ? Почему GUI перемежается с прочим кодом..Про стили, хотя-бы цвета, можно и не говорить

Используя библиотеки статьи, код типичного советника стал короче ? а вот хренушки, не для того писано :-)

 
Maxim Kuznetsov #:

это вообще не ООП. Это повторно завёрнутые в классы методы терминала. 

если программист захочет сделать иной GUI (модный http, через WebSocket освещённый в прочих статьях), то ничего сделать не сможет. Просто выбросит вообще весь код из статьи и напишет иной.

чтобы коренным образом поменять визуальную часть, но на тех-же ObjectCreate(xx) - всё равно придётся переписывать просто всё.

или как отключить GUI, чтобы он не занимал процессор на VDS-ке

Где reusability ? Почему GUI перемежается с прочим кодом..Про стили, хотя-бы цвета, можно и не говорить

Используя библиотеки статьи, код типичного советника стал короче ? а вот хренушки, не для того писано :-)

Ну обсуждать цвета, думаю здесь не совсем корректно.

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


Не понятно зачем отключать  GUI, если это панель для ручной торговли. Хотя, если это не торговая панель, а информационная, то да, лучше продумать отключение.

Мне понравилось как организованна функция RectangleLabel::OnEvent и RectangleLabel::Add, красиво, понятно, читаемо.

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

Панелька в итоге получилась, но времени убил на это больше, чем если бы писал с нуля.

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

 
Aleksandr Slavskii #:

Ну обсуждать цвета, думаю здесь не совсем корректно.

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


Не понятно зачем отключать  GUI, если это панель для ручной торговли. Хотя, если это не торговая панель, а информационная, то да, лучше продумать отключение.

Мне понравилось как организованна функция RectangleLabel::OnEvent и RectangleLabel::Add, красиво, понятно, читаемо.

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

Панелька в итоге получилась, но времени убил на это больше, чем если бы писал с нуля.

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

есть тьма проработанных методик с красивыми стрелочками "как реализовать UI чтобы не было мучительно больно" :-) MVC и подобные. Так там фронт (win,gtk,qt,web) подчас можно менять лёгким движением руки. 

ни одно не было реализовано в MQL. Тут всё прибивается наглухо гвоздями, хуже TurboVision - там хоть так-же классы от адама, но там есть модели  

отдельные лица годами(!!) пишут про "легко и просто" и "простой интерфейс", но ровно то-же самое что в этой статье. Масса кода не облегчающего ничего. Единственный эффект - бонус на счёт автора.