Aber man kann in MQL4 nicht mit OOP programmieren, deshalb ist es immer noch beliebter.
Ich habe meinen Code bereits gezeigt, und ich werde ihn noch einmal zeigen:
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;
};
Dies ist die Schnittstelle des Handelsprozessors - sie ist für MT4 und MT5 identisch.
Der Benutzer erhält nur diese Schnittstelle - und hat alle Möglichkeiten für Handelsaktionen. Sie müssen nicht einmal wissen, ob es sich um MT4 oder MT5 handelt. Sie müssen kaufen - rufen Sie die Funktion Buy auf, die das Ticket für die offene Handelskomponente füllt (für MT4 ist es eine Order, für MT5 eine Position) und den Rückgabecode an den Handelsserver zurückgibt.
Sie müssen nicht einmal über den Unterschied zwischen MT4- und MT5-Protokollen nachdenken - die Schnittstelle bietet alles, was Sie brauchen.
Ich habe meinen Code bereits gezeigt, und ich werde ihn noch einmal zeigen:
Dies ist die Schnittstelle des Handelsprozessors - sie ist für MT4 und MT5 identisch.
Der Nutzer erhält einfach diese Schnittstelle - und schon hat er alle Möglichkeiten für Handelsaktionen. Er muss nicht einmal wissen, ob er mit MT4 oder MT5 arbeitet.
Haben Sie Beispiele für die Verwendung in typischen Fällen?
Nun, nehmen wir an, meine Funktion sendet einen Antrag auf Änderung von TP-SL an den Handelsprozessor:
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);
};
Erstens, EA part objects - form trade action requests (hier ist eine solche Anfrage, TP-SL zu ändern). Danach wird die Funktion ProceedRequestInto() für alle Anfragen aufgerufen, um Informationen über eine Handelsaktion an den Handelsverarbeiter zu senden.
Der Handelsabwickler selbst ist ein Objekt der folgenden Klasse:
// С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);
};
Das heißt, je nach Plattform wird die Klasse CTradeProcessor entweder von der Klasse CMT5TradeProcessor oder von der Klasse CMT4TradeProceccor geerbt.
Natürlich könnte all dies auch ohne OOP, mit Hilfe von Schaltern und ifdefs geschehen. Aber meiner Meinung nach ist der OOP-Ansatz bequemer und klarer, und das Wichtigste ist, dass er es erlaubt, Entitäten voneinander zu isolieren und die Masse an globalen Variablen loszuwerden.
Ein weiteres "Echo von OOP" findet sich übrigens in den zusätzlichen Funktionen für die Arbeit mit den ausstehenden Aufträgen. Der Handelsprozessor - arbeitet mit Tickets von Geschäften, was unpraktisch ist - der Bezug auf das Ticket in MT4 und MT5 ist unterschiedlich. Aus diesem Grund gibt es die gemeinsame Klasse COrderInfoCore, die von der Auftragsschnittstelle abstammt. Es ist viel bequemer, dem Prozessor nur einen Zeiger auf dieses Objekt zu übergeben. Auf diese Weise umgehen wir die plattformabhängigen Fragmente.
Nun, nehmen wir an, meine Funktion sendet einen Antrag auf Änderung von TP-SL an den Handelsprozessor:
Erstens, EA part objects - form trade action requests (hier ist eine solche Anfrage, TP-SL zu ändern). Dann wird die Funktion ProceedRequestInto() für alle Anfragen aufgerufen, um Informationen über eine Handelsaktion an einen Handelsverarbeiter zu senden.
Es scheint mir zu kompliziert zu sein, um zu verstehen, was da eigentlich passiert. Und wenn Sie nicht verstehen, was darin vor sich geht, werden Sie es wahrscheinlich auch nicht benutzen... Wäre es nicht einfacher, eine separate Version für MT5 zu schreiben und diese bei Bedarf einzubinden?
Andrei: Ich denke, es ist zu kompliziert, um zu verstehen, was da wirklich vor sich geht... Und ohne zu verstehen, wie es funktioniert, wird es wohl niemand nutzen... Ist es nicht einfacher, eine separate Version für MT5 zu schreiben und diese bei Bedarf einzubinden?
Warum muss ich "verstehen, was wirklich drin ist"? Es gibt eine feste Schnittstelle, die eine Aktion ausführt, unabhängig von der Plattform - das ist es, was wir verwenden. Und was gibt es, auf niedrigem Niveau - was macht das für einen Unterschied?
Meiner Meinung nach ist der OOP-Ansatz jedoch viel praktischer und übersichtlicher, und - was am wichtigsten ist - er erlaubt es, Entitäten voneinander zu isolieren und die Massen an globalen Variablen loszuwerden.
Das ist der Punkt, wenn man alles von allem isoliert hat, wird es viel schwieriger sein, mit solchem Code umzugehen, ganz zu schweigen von der Unmöglichkeit, den Code angemessen zu debuggen, wenn man die aktuellen Werte aller erforderlichen Variablen kennen muss...
Denn mein Hauptkonto ist auf MT4 eröffnet, und mein Strategietester ist viel besser auf MT5.
Es ist eine häufige Forderung der Kunden in Freelance - "es muss sowohl auf MT4 als auch auf MT5 funktionieren" - das bedeutet, dass es einen Grund dafür gibt. Ich selbst sehe keinen Grund, in der Freiberuflichkeit zu arbeiten, aber Sie können diejenigen, die dort arbeiten, fragen, warum Kunden plattformübergreifend arbeiten wollen.
George Merts: Warum müssen wir "verstehen, was da drinnen eigentlich gemacht wird"? Es gibt eine feste Schnittstelle, die eine Aktion ausführt, unabhängig von der Plattform - das ist es, was wir verwenden. Und was gibt es, auf niedrigem Niveau - was macht das für einen Unterschied?
Es geht nicht um die niedrige Ebene, sondern um die Logik dessen, was zu jedem möglichen Zeitpunkt wohin und in was fließt, einschließlich der Kenntnis aller internen Variablen... Wenn man diese ganze redundante Logik nicht versteht, geht der Sinn der Verwendung dieses Codes für einen Nicht-Autor völlig verloren...
Aber man kann in MQL4 nicht mit OOP programmieren, deshalb ist es immer noch beliebter.
Ich habe meinen Code bereits gezeigt, und ich werde ihn noch einmal zeigen:
Dies ist die Schnittstelle des Handelsprozessors - sie ist für MT4 und MT5 identisch.
Der Benutzer erhält nur diese Schnittstelle - und hat alle Möglichkeiten für Handelsaktionen. Sie müssen nicht einmal wissen, ob es sich um MT4 oder MT5 handelt. Sie müssen kaufen - rufen Sie die Funktion Buy auf, die das Ticket für die offene Handelskomponente füllt (für MT4 ist es eine Order, für MT5 eine Position) und den Rückgabecode an den Handelsserver zurückgibt.
Sie müssen nicht einmal über den Unterschied zwischen MT4- und MT5-Protokollen nachdenken - die Schnittstelle bietet alles, was Sie brauchen.
Dies alles sind OOP-Fähigkeiten.
Ich habe meinen Code bereits gezeigt, und ich werde ihn noch einmal zeigen:
Dies ist die Schnittstelle des Handelsprozessors - sie ist für MT4 und MT5 identisch.
Der Nutzer erhält einfach diese Schnittstelle - und schon hat er alle Möglichkeiten für Handelsaktionen. Er muss nicht einmal wissen, ob er mit MT4 oder MT5 arbeitet.
Und das ist alles OOP zu verdanken.
Gibt es Anwendungsbeispiele für typische Fälle?
Wenn Ihre Theorie war, dass MQL4=MQL5, dann MQL4 könnte auf MT5 und umgekehrt ausgeführt werden.
Haben Sie Beispiele für die Verwendung in typischen Fällen?
Nun, nehmen wir an, meine Funktion sendet einen Antrag auf Änderung von TP-SL an den Handelsprozessor:
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); };Erstens, EA part objects - form trade action requests (hier ist eine solche Anfrage, TP-SL zu ändern). Danach wird die Funktion ProceedRequestInto() für alle Anfragen aufgerufen, um Informationen über eine Handelsaktion an den Handelsverarbeiter zu senden.
Der Handelsabwickler selbst ist ein Objekt der folgenden Klasse:
Das heißt, je nach Plattform wird die Klasse CTradeProcessor entweder von der Klasse CMT5TradeProcessor oder von der Klasse CMT4TradeProceccor geerbt.
Natürlich könnte all dies auch ohne OOP, mit Hilfe von Schaltern und ifdefs geschehen. Aber meiner Meinung nach ist der OOP-Ansatz bequemer und klarer, und das Wichtigste ist, dass er es erlaubt, Entitäten voneinander zu isolieren und die Masse an globalen Variablen loszuwerden.
Ein weiteres "Echo von OOP" findet sich übrigens in den zusätzlichen Funktionen für die Arbeit mit den ausstehenden Aufträgen. Der Handelsprozessor - arbeitet mit Tickets von Geschäften, was unpraktisch ist - der Bezug auf das Ticket in MT4 und MT5 ist unterschiedlich. Aus diesem Grund gibt es die gemeinsame Klasse COrderInfoCore, die von der Auftragsschnittstelle abstammt. Es ist viel bequemer, dem Prozessor nur einen Zeiger auf dieses Objekt zu übergeben. Auf diese Weise umgehen wir die plattformabhängigen Fragmente.
Nun, nehmen wir an, meine Funktion sendet einen Antrag auf Änderung von TP-SL an den Handelsprozessor:
Erstens, EA part objects - form trade action requests (hier ist eine solche Anfrage, TP-SL zu ändern). Dann wird die Funktion ProceedRequestInto() für alle Anfragen aufgerufen, um Informationen über eine Handelsaktion an einen Handelsverarbeiter zu senden.
Mein Code läuft völlig unverändert auf MT4 und MT5.
Warum in verschiedenen Terminals laufen?
Ich denke, es ist zu kompliziert, um zu verstehen, was da wirklich vor sich geht... Und ohne zu verstehen, wie es funktioniert, wird es wohl niemand nutzen... Ist es nicht einfacher, eine separate Version für MT5 zu schreiben und diese bei Bedarf einzubinden?
George Merts:
Meiner Meinung nach ist der OOP-Ansatz jedoch viel praktischer und übersichtlicher, und - was am wichtigsten ist - er erlaubt es, Entitäten voneinander zu isolieren und die Massen an globalen Variablen loszuwerden.
Das ist der Punkt, wenn man alles von allem isoliert hat, wird es viel schwieriger sein, mit solchem Code umzugehen, ganz zu schweigen von der Unmöglichkeit, den Code angemessen zu debuggen, wenn man die aktuellen Werte aller erforderlichen Variablen kennen muss...
Warum in verschiedenen Terminals laufen?
Denn mein Hauptkonto ist auf MT4 eröffnet, und mein Strategietester ist viel besser auf MT5.
Es ist eine häufige Forderung der Kunden in Freelance - "es muss sowohl auf MT4 als auch auf MT5 funktionieren" - das bedeutet, dass es einen Grund dafür gibt. Ich selbst sehe keinen Grund, in der Freiberuflichkeit zu arbeiten, aber Sie können diejenigen, die dort arbeiten, fragen, warum Kunden plattformübergreifend arbeiten wollen.
Warum müssen wir "verstehen, was da drinnen eigentlich gemacht wird"? Es gibt eine feste Schnittstelle, die eine Aktion ausführt, unabhängig von der Plattform - das ist es, was wir verwenden. Und was gibt es, auf niedrigem Niveau - was macht das für einen Unterschied?