За то на MQL4 нельзя программировать с ООП, поэтому он все еще популярней.
Я уже показывал свой код, и покажу еще раз:
class CTradeProcessorI : public CMyObject
{
public:
void CTradeProcessorI() { SetMyObjectType(MOT_TRADE_PROCESSOR_I); };
virtualvoid ~CTradeProcessorI() {};
// Настроечный интерфейсvirtualvoid SetSlippage(uint uiSlippage) = 0;
// Торговый интерфейс// Все функции возвращают код возврата торгового сервераvirtualint Buy(long & lTicket,ECurrencySymbol csSymbol,double dVolume,double dTP=0,double dSL=0,ulong ulMagic = 0,string strComment = NULL) = 0; // Всегда по цене Ask, если успешно - возвращается lTicketvirtualint Sell(long & lTicket,ECurrencySymbol csSymbol,double dVolume,double dTP=0,double dSL=0,ulong ulMagic = 0,string strComment = NULL) = 0; // Всегда по цене Bid, если успешно - возвращается lTicket virtualint ModifyTPSL(CTradePosComponentI* ptpcComponent,double dTP=0,double dSL=0) = 0;
virtualint ModifyTPSL(long lTPCTicket,double dTP=0,double dSL=0) = 0;
virtualint CloseTradeComponent(CTradePosComponentI* ptpcComponent,double dCloseVolume=EMPTY_VALUE) = 0; // dCloseVolume - закрываемый объем. Если равен EMPTY_VALUE или равен или больше, чем объем торговой компоненты с указанным тикетом - закрывается вся торговая компонента. virtualint CloseTradeComponent(long lTPCTicket,double dCloseVolume=EMPTY_VALUE) = 0; // dCloseVolume - закрываемый объем. Если равен EMPTY_VALUE или равен или больше, чем объем торговой компоненты с указанным тикетом - закрывается вся торговая компонента. virtualint PendingSet(long & lTicket,ECurrencySymbol csSymbol,ENUM_ORDER_TYPE otOrderType,double dSetPrice,double dVolume,double dTP=0,double dSL=0,ulong ulMagic = 0,string strComment = NULL) = 0; // если успешно - возвращается lTicketvirtualint PendingDelete(long lTicket) = 0;
virtualint PendingDelete(COrderInfoCore* poiOrder) = 0;
virtualint PendingModify(long lTicket,double dSetPrice,double dTP=0,double dSL=0) = 0;
virtualint PendingModify(COrderInfoCore* poiOrder,double dSetPrice,double dTP=0,double dSL=0) = 0;
// Проверка кода возвратаvirtualbool TradeOperationWasSuccessful(int iTradeResCode) = 0;
// Если функция возвращает true, то при возникновении пользовательских ошибок (iTradeResCode > ERR_USER_ERROR_FIRST) советник прекратит работу// В случае false - работа будет продолженаvirtualbool IsUserErrorsFalal() = 0;
};
Это интерфейс торгового процессора - он совершенно одинаков, как для МТ4, так и для МТ5.
Пользователь просто получает этот интерфейс - и у него все возможности для торговых действий. Ему совершенно не надо даже знать, где он находится - на МТ4 или МТ5. Нужно совершить покупку - вызываете функцияю Buy. которая вам заполнит тикет открытой торговой компоненты (для МТ4 - это ордер, для МТ5 - позиция), и вернет код возврата торгового сервера.
Вам даже не надо задумываться над разностью протоколов МТ4 и МТ5 - интерфейс предоставляет всё необходимое.
Это интерфейс торгового процессора - он совершенно одинаков, как для МТ4, так и для МТ5.
Пользователь просто получает этот интерфейс - и у него все возможности для торговых действий. Ему совершенно не надо даже знать, где он находится - на МТ4 или МТ5.
И все это - благодаря ООП.
А примеры использования есть для типичных случаев?
А примеры использования есть для типичных случаев?
Ну, допустим, вот моя функция, отправляющая запрос изменения ТП-СЛ на торговый процессор:
EEAWorkRetcode CChngTPSLRequest::_ProceedRequestInto(CTradeProcessorI* ptpProcessor)
{
ASSERT_MYPOINTER(ptpProcessor);
m_uiServerRetCode = ptpProcessor.ModifyTPSL(m_lComponentTicket,m_dTP,m_dSL);
if(ptpProcessor.TradeOperationWasSuccessful(m_uiServerRetCode) != true)
{
Print("Торговый запрос на изменение ТП-СЛ компоненты отработал с ошибкой, код возврата: ",m_uiServerRetCode);
TRACE_INTEGER("Торговый запрос на изменение ТП-СЛ компоненты отработал с ошибкой, код возврата: ",m_uiServerRetCode);
return(WR_SERVER_PROCEED_ERROR);
};
return(WR_SUCCEEDED);
};
Сперва объекты-части эксперта - формируют запросы на торговые действия (вот, один из таких запросов - на изменение ТП-СЛ). После этого у всех запросов вызывается функция ProceedRequestInto() чтобы отправить информацию о торговом действии в торговый процессор.
Сам торговый процессор представляет из себя объект следующего класса:
// СTradeProcessor - переносимый класс торгового процессора// Именно этот класс необходимо использовать для торговли. // Класс реализует интерфейс CTradeProcessorI#ifdef __MQL5__#include <MyLib\Trade\MT5TradeProcessor.mq5>
#else // __MQL5__#include <MyLib\Trade\MT4TradeProcessor.mq5>
#endif //__MQL5__#ifdef __MQL5__class CTradeProcessor : public CMT5TradeProcessor
#else // __MQL5__class CTradeProcessor : public CMT4TradeProcessor
#endif //__MQL5__
{
public:
void CTradeProcessor(uint uiSlippage = DEFAULT_TRADE_POINT_SLIPPAGE);
void ~CTradeProcessor() {};
// Функции отложенных ордеров, которые используют платформоспецифические virtualint PendingDelete(COrderInfoCore* poiOrder);
virtualint PendingModify(COrderInfoCore* poiOrder,double dSetPrice,double dTP=0,double dSL=0);
};
То есть, в зависимости от платформы - класс CTradeProcessor наследуется либо от класса CMT5TradeProcessor, либо от класса CMT4TradeProceccor.
Все это, конечно, можно сделать и без ООП - с помощью переключателей да ifdef'ов. Но, на мой взгляд, ООП-подход - куда более удобный и ясный. А главное - позволяющий изолировать сущности друг от друга, и избавляться от массы глобальных переменных.
Кстати, еще один "отголосок ООП" - как раз в дополнительных функциях работы с отложками. Торговый процессор - работает с тикетами отложек, что неудобно - обращение к тикетам в МТ4 и МТ5 разное. Поэтому есть общий класс COrderInfoCore - наследник интерфейса ордера. В процессор гораздо удобнее передавать просто указатель на этот объект. Соответственно, таки образом - мы обходим платформозависиые места.
Ну, допустим, вот моя функция, отправляющая запрос изменения ТП-СЛ на торговый процессор:
Сперва объекты-части эксперта - формируют запросы на торговые действия (вот, один из таких запросов - на изменение ТП-СЛ). После этого у всех запросов вызывается функция ProceedRequestInto() чтобы отправить информацию о торговом действии в торговый процессор.
Мне кажется слишком замудрено, чтобы понять что там делается внутри на самом деле... А без понимания сути работы наврядли кто-то воспользуется... Не проще ли написать отдельную версию для МТ5 и подцеплять ее когда надо?
Andrei: Мне кажется слишком замудрено, чтобы понять что там делается внутри на самом деле... А без понимания сути работы наврядли кто-то воспользуется... Не проще ли написать отдельную версию для МТ5 и подцеплять ее когда надо?
А зачем "понимать, что там делается внутри на самом деле" ? Есть фиксированный интерфейс, который выполняет действие, независимо от платформы - его и используем. А что там, на низком уровне - какая разница ?
Но, на мой взгляд, ООП-подход - куда более удобный и ясный. А главное - позволяющий изолировать сущности друг от друга, и избавляться от массы глобальных переменных.
В этом то и смысл, что изолировав все от всего, разобраться с таким кодом будет во много раз сложнее, не говоря уже о невозможности адекватной отладки кода когда нужно знать текущие значения всех необходимых переменных...
А затем, что у меня основной счет открыт на МТ4, а тестер стратегий на МТ5 куда лучше.
Да и во Фрилансе, по слухам, очень частое требование заказчиков - "чтобы работало и на МТ4 и на МТ5" - значит, это неспроста. Сам я во Фрилансе не вижу смысла работать, но можно спросить у тех, кто там работает, зачем заказчики требуют кроссплатформенность.
George Merts: А зачем "понимать, что там делается внутри на самом деле" ? Есть фиксированный интерфейс, который выполняет действие, независимо от платформы - его и используем. А что там, на низком уровне - какая разница ?
Не идет речь о низком уровне, а о логике того что там куда перетекает и во что превращается в каждый возможный момент времени, включая знание всех внутренних переменных... Без понимания всей этой избыточной логики смысл использования данного кода для не автора пропадает начисто...
За то на MQL4 нельзя программировать с ООП, поэтому он все еще популярней.
Я уже показывал свой код, и покажу еще раз:
Это интерфейс торгового процессора - он совершенно одинаков, как для МТ4, так и для МТ5.
Пользователь просто получает этот интерфейс - и у него все возможности для торговых действий. Ему совершенно не надо даже знать, где он находится - на МТ4 или МТ5. Нужно совершить покупку - вызываете функцияю Buy. которая вам заполнит тикет открытой торговой компоненты (для МТ4 - это ордер, для МТ5 - позиция), и вернет код возврата торгового сервера.
Вам даже не надо задумываться над разностью протоколов МТ4 и МТ5 - интерфейс предоставляет всё необходимое.
Все это - возможности ООП.
Я уже показывал свой код, и покажу еще раз:
Это интерфейс торгового процессора - он совершенно одинаков, как для МТ4, так и для МТ5.
Пользователь просто получает этот интерфейс - и у него все возможности для торговых действий. Ему совершенно не надо даже знать, где он находится - на МТ4 или МТ5.
И все это - благодаря ООП.
А примеры использования есть для типичных случаев?
Если бы было по вашей теории, что MQL4=MQL5, то тогда MQL4 можно было запускать на МТ5 и наоборот.
А примеры использования есть для типичных случаев?
Ну, допустим, вот моя функция, отправляющая запрос изменения ТП-СЛ на торговый процессор:
EEAWorkRetcode CChngTPSLRequest::_ProceedRequestInto(CTradeProcessorI* ptpProcessor) { ASSERT_MYPOINTER(ptpProcessor); m_uiServerRetCode = ptpProcessor.ModifyTPSL(m_lComponentTicket,m_dTP,m_dSL); if(ptpProcessor.TradeOperationWasSuccessful(m_uiServerRetCode) != true) { Print("Торговый запрос на изменение ТП-СЛ компоненты отработал с ошибкой, код возврата: ",m_uiServerRetCode); TRACE_INTEGER("Торговый запрос на изменение ТП-СЛ компоненты отработал с ошибкой, код возврата: ",m_uiServerRetCode); return(WR_SERVER_PROCEED_ERROR); }; return(WR_SUCCEEDED); };Сперва объекты-части эксперта - формируют запросы на торговые действия (вот, один из таких запросов - на изменение ТП-СЛ). После этого у всех запросов вызывается функция ProceedRequestInto() чтобы отправить информацию о торговом действии в торговый процессор.
Сам торговый процессор представляет из себя объект следующего класса:
То есть, в зависимости от платформы - класс CTradeProcessor наследуется либо от класса CMT5TradeProcessor, либо от класса CMT4TradeProceccor.
Все это, конечно, можно сделать и без ООП - с помощью переключателей да ifdef'ов. Но, на мой взгляд, ООП-подход - куда более удобный и ясный. А главное - позволяющий изолировать сущности друг от друга, и избавляться от массы глобальных переменных.
Кстати, еще один "отголосок ООП" - как раз в дополнительных функциях работы с отложками. Торговый процессор - работает с тикетами отложек, что неудобно - обращение к тикетам в МТ4 и МТ5 разное. Поэтому есть общий класс COrderInfoCore - наследник интерфейса ордера. В процессор гораздо удобнее передавать просто указатель на этот объект. Соответственно, таки образом - мы обходим платформозависиые места.
Ну, допустим, вот моя функция, отправляющая запрос изменения ТП-СЛ на торговый процессор:
Сперва объекты-части эксперта - формируют запросы на торговые действия (вот, один из таких запросов - на изменение ТП-СЛ). После этого у всех запросов вызывается функция ProceedRequestInto() чтобы отправить информацию о торговом действии в торговый процессор.
Мой код совершенно без изменений запускается на МТ4 и на МТ5.
А зачем запускать в разных терминалах?
Мне кажется слишком замудрено, чтобы понять что там делается внутри на самом деле... А без понимания сути работы наврядли кто-то воспользуется... Не проще ли написать отдельную версию для МТ5 и подцеплять ее когда надо?
George Merts:
Но, на мой взгляд, ООП-подход - куда более удобный и ясный. А главное - позволяющий изолировать сущности друг от друга, и избавляться от массы глобальных переменных.
В этом то и смысл, что изолировав все от всего, разобраться с таким кодом будет во много раз сложнее, не говоря уже о невозможности адекватной отладки кода когда нужно знать текущие значения всех необходимых переменных...
А зачем запускать в разных терминалах?
А затем, что у меня основной счет открыт на МТ4, а тестер стратегий на МТ5 куда лучше.
Да и во Фрилансе, по слухам, очень частое требование заказчиков - "чтобы работало и на МТ4 и на МТ5" - значит, это неспроста. Сам я во Фрилансе не вижу смысла работать, но можно спросить у тех, кто там работает, зачем заказчики требуют кроссплатформенность.
А зачем "понимать, что там делается внутри на самом деле" ? Есть фиксированный интерфейс, который выполняет действие, независимо от платформы - его и используем. А что там, на низком уровне - какая разница ?