Diskussion zum Artikel "Erstellen eines EA, der automatisch funktioniert (Teil 08): OnTradeTransaktion"
Ich habe ein Problem, das mich verwirrt.
Vielen Dank für diesen wunderbaren Artikel. Ich habe ein Problem, das mich verwirrt. Ich habe einen Code geschrieben, um eine Position zu eröffnen.
Er kann den richtigen Wert zurückgeben, wenn er auf einem Demokonto ausgeführt wird, aber er gibt 0 zurück, wenn er auf einem echten Konto ausgeführt wird.
//+------------------------------------------------------------------+ //|& nbsp;   ; Test1.mq5 | //|& nbsp; Copyright 2023, MetaQuotes Ltd. //|& nbsp;   https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2018, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #include <Trade\Trade.mqh> CTrade m_trade; CDealInfo m_deal; //+------------------------------------------------------------------+ //| EA Trade Initialisierungsfunktionen & nbsp;   ; | //+------------------------------------------------------------------+ int OnInit() { //--- EventSetMillisecondTimer(1); OpenPosition(ORDER_TYPE_BUY, 0.01, 123456); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); } //+------------------------------------------------------------------+ //| EA-Zitierfunktion & nbsp;   ; || //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ void OnTimer() { } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ ulong OpenPosition(const ENUM_ORDER_TYPE type, const double lot, const long magic) { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); m_trade.SetExpertMagicNumber(magic); if(m_trade.PositionOpen(_Symbol, type, lot, (type == ORDER_TYPE_BUY) ? ask : bid, 0, 0)) { ulong deal_ticket = m_trade.ResultDeal(); if(HistoryDealSelect(deal_ticket)) m_deal.Ticket(deal_ticket); string flag = (m_deal.DealType() == DEAL_TYPE_BUY) ? "buy" : "sell"; printf(StringFormat("open deal ticket= #%%d order ticket= #%%d %%s %%.2f %%s at %%.%df", _Digits), deal_ticket, m_deal.Order(), flag, m_deal.Volume(), _Symbol, m_deal.Price()); return(deal_ticket); } return(0); }
Olá, Daniel José
Obrigado por dedicar um artigo tão maravilhoso. Estou com um problema que me confunde. Eu escrevi um código para abrir uma posição.
Er kann bei der Ausführung im Demo-Modus den korrekten Wert zurückgeben, bei der Ausführung im realen Modus jedoch 0. Können Sie mir sagen, wo das Problem liegt? á o problema?
Tente verificar o erro, que está sendo retornado, adicionando a linha destacada logo abaixo.
ulong OpenPosition( const ENUM_ORDER_TYPE type, const double lot, const long magic) { double ask = SymbolInfoDouble ( _Symbol , SYMBOL_ASK ); double bid = SymbolInfoDouble ( _Symbol , SYMBOL_BID ); m_trade.SetExpertMagicNumber(magic); if (m_trade.PositionOpen( _Symbol , type, lot, (type == ORDER_TYPE_BUY ) ? ask : bid, 0 , 0 )) { ulong deal_ticket = m_trade.ResultDeal(); if ( HistoryDealSelect (deal_ticket)) m_deal.Ticket(deal_ticket); string flag = (m_deal.DealType() == DEAL_TYPE_BUY ) ? "buy" : "sell" ; printf ( StringFormat ( "open deal ticket= #%%d order ticket= #%%d %%s %%.2f %%s at %%.%df" , _Digits ), deal_ticket, m_deal.Order(), flag, m_deal.Volume(), _Symbol , m_deal.Price()); return (deal_ticket); } Print("Error: ", m_trade.ResultRetcode()); return ( 0 ); }
Tente verificar o errouverado que está sendo retornado, adicionando a linha destacada logo abaixo.
Nein, mein Ziel ist es, ein Dealticket zurückzugeben.
Es kann ein Deal-Ticket der Position auf dem Demo-Konto zurückgeben, aber einen Nullwert auf dem Real-Konto, warum?
ulong OpenPosition(const ENUM_ORDER_TYPE type, const double lot, const long magic) { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); m_trade.SetExpertMagicNumber(magic); if(m_trade.PositionOpen(_Symbol, type, lot, (type == ORDER_TYPE_BUY) ? ask : bid, 0, 0)) return(m_trade.ResultDeal()); return(0); }
Não, meu objetivo é devolver um bilhete de acordo
Er kann das Ticket für die Position in der Demoversion zurückgeben, in der echten Version jedoch nur den Wert Null, wozu?
Eine Zeile, die Sie auffordert, NÃO É... hinzuzufügen. vou repetir. NÃO É para retornar nenhum valor ... ELA SERVE PARA VERIFICAR O ERRO que está dando ao tentar abririr uma posição ... você nÃO deve usar o valor retornado... você deve verificar o ERRO na tabela de erros... Lesen Sie ein DOKUMENTAÇÃO
Hallo, ich verfolge diese Serie von Artikeln. Mein Respekt. Es ist wirklich hilfreich.
Ich teste das Ergebnis und nachdem ich eine Order erstellt habe, lösche ich sie. Aber EA erlaubt es nicht mehr, eine neue Order zu erstellen.
Dieser Codeschnipsel:
case TRADE_TRANSACTION_ORDER_DELETE : if (trans.order == trans.position) (*manager).PendingToPosition(); else (*manager).UpdatePosition(trans.position); // ORDER? break ;
Er verwendet trans.position, die im Falle einer Orderlöschung immer 0 ist. Das ist also der Wert, der an UpdatePosition übergeben wird. Die erste Bedingung sendet ihn direkt an die Return-Anweisung.
Ich habe versucht, das Ticket von trans.order zu übergeben, aber der Code ignoriert es, weil m_position null Daten hat, also ist das Ticket 0 (! = m_Position.Ticket):
Nach dieser. Wenn ich versuche, eine neue Bestellung zu erstellen, hat m_ticketPending den Wert der ersten Bestellung, also wird sie nicht erstellt.
EraseTicketPending wird nicht aufgerufen, denn wenn TRADE_ACTION_REMOVE eintrifft, ist diese Bedingung immer falsch, da request .request.TRADE_ACTION_REMOVE immer falsch ist.
if ((request.symbol == _Symbol ) && (result.retcode == TRADE_RETCODE_DONE ) && (request.magic == def_MAGIC_NUMBER))
ist immer falsch, da request.magic 0 ist.
Ich werde untersuchen, ob dies in den nächsten Kapiteln behoben wird.
Mit freundlichen Grüßen
Ich glaube, ich habe das Problem gefunden.
Wenn die Orderlöschung von der MT5-Benutzeroberfläche aus durchgeführt wird, ist die magische Zahl 0. Also habe ich die Bedingung geändert in
if ((request.symbol == _Symbol ) && (result.retcode == TRADE_RETCODE_DONE ) && ((request.magic == def_MAGIC_NUMBER) || request.magic == 0 ))
und es scheint zu funktionieren wie erwartet.
Hallo, Daniel Jose.
Vielen Dank für diesen wunderbaren Artikel. Ich habe ein Problem, das mich verwirrt. Ich habe einen Code geschrieben, um eine Position zu eröffnen.
Es kann den richtigen Wert zurückgeben, wenn es auf Demo-Konto ausgeführt wird, aber es gibt 0 zurück, wenn es auf einem realen Konto ausgeführt wird, können Sie mir helfen, zu beraten, wo das Problem ist?
Diese Funktion hat eine offene Position und gibt DEAL TICKET zurück:
//+------------------------------------------------------------------+ //|& nbsp;   ; Test1.mq5 | //|& nbsp; Copyright 2023, MetaQuotes Ltd. //|& nbsp;   https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2018, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> CTrade m_trade; CDealInfo m_deal; CSymbolInfo m_symbol; input double TakeProfit = 0; input double StopLoss = 0; input string PositionComment = ""; double m_point; //+------------------------------------------------------------------+ //| EA Trade Initialisierungsfunktionen & nbsp;   ; | //+------------------------------------------------------------------+ int OnInit() { //--- EventSetMillisecondTimer(1); if(!m_symbol.Name(_Symbol)) // setzt den Symbolnamen return(INIT_FAILED); RefreshRates(); m_trade.SetMarginMode(); m_trade.SetTypeFillingBySymbol(m_symbol.Name()); m_trade.SetDeviationInPoints(INT_MAX); int adjust = (m_symbol.Digits() == 3 || m_symbol.Digits() == 5) ? 10 : 1; m_point = m_symbol.Point() * adjust; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); } //+------------------------------------------------------------------+ //| EA-Zitierfunktion & nbsp;   ; || //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ void OnTimer() { } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ bool RefreshRates(void) { //--- Aktualisierungsraten if(!m_symbol.RefreshRates()) { Print("RefreshRates error"); return(false); } //--- Schutz gegen den Rückgabewert "Null" if(m_symbol.Ask() == 0 || m_symbol.Bid() == 0) return(false); //--- return(true); } //+------------------------------------------------------------------+ //|& nbsp;   nbsp;   nbsp; | //+------------------------------------------------------------------+ ulong OpenPosition(const ENUM_ORDER_TYPE type, const double volume, const long magic) { ulong deal_ticket = 0; double sl = 0; double tp = 0; m_trade.SetExpertMagicNumber(magic); RefreshRates(); double ask = m_symbol.Ask(); double bid = m_symbol.Bid(); switch(type) { case ORDER_TYPE_BUY: if(TakeProfit > 0) tp = m_symbol.NormalizePrice(ask + TakeProfit * m_point); if(StopLoss > 0) sl = m_symbol.NormalizePrice(bid - StopLoss * m_point); break; case ORDER_TYPE_SELL: if(TakeProfit > 0) tp = m_symbol.NormalizePrice(bid - TakeProfit * m_point); if(StopLoss > 0) sl = m_symbol.NormalizePrice(ask + StopLoss * m_point); break; } static datetime from_date = iTime(m_symbol.Name(), PERIOD_D1, 0); ulong time = GetTickCount64(); if(m_trade.PositionOpen(m_symbol.Name(), type, volume, (type == ORDER_TYPE_BUY) ? ask : bid, sl, tp, PositionComment)) { ulong open_execution = GetTickCount64() - time; do { ulong order_ticket = m_trade.ResultOrder(); HistorySelect(from_date, TimeTradeServer()); int total = HistoryDealsTotal(); for(int i = total - 1; i >= 0; i--) { if(!m_deal.SelectByIndex(i)) continue; if(m_deal.Symbol() != m_symbol.Name()) continue; if(m_deal.Entry() != DEAL_ENTRY_IN) continue; if(m_deal.Order() != order_ticket) continue; printf(StringFormat("open #%%I64u %%s %%.2f %%s at %%.%df done in %%I64u ms", m_symbol.Digits()), m_deal.Order(), (type == ORDER_TYPE_BUY) ? "buy" : "sell", m_deal.Volume(), m_deal.Symbol(), m_deal.Price(), open_execution); from_date = m_deal.Time(); deal_ticket = m_deal.Ticket(); break; } } while(deal_ticket == 0); } return(deal_ticket); } //+------------------------------------------------------------------+
Ich fing an, es zu verwenden, um Ereignisse (Öffnen einer Position, Schließen, Ändern) zu fangen, wie ich es vorher in MT4 (Überprüfung ständig die Positionen zu erraten, was passiert ist). In dieser Hinsicht ist der MT5-Ansatz sehr sauber.
ABER WAS GEHT, WENN DER EA WÄHREND EINER STUNDE ABGESCHALTET ODER AUSGESCHALTET IST: Er erhält natürlich keine Ereignisse, aber wenn er neu startet, erhält er nicht die Ereignisse, die er während einer Stunde durcheinander gebracht hat. Also, um zu erraten, was passiert ist, wird es brauchen, um die alte MT4 Weg durch die Analyse der Positionen zu tun, um zu erraten, was passiert ist. Um dieses Problem zu lösen, muss ich die 2 Wege zur Erkennung von Ereignissen beibehalten: den MT5 Weg und den MT4 Weg als Backup.
Bei Marktpositionen geschieht dies sofort.
Ich stimme zu... deshalb wird während des Starts des Expert Advisors eine Überprüfung der Positionen oder ausstehenden Aufträge durchgeführt. Aber dies wird in einem Artikel ein wenig weiter in dieser gleichen Sequenz gesehen.
Automatisierte Übersetzung durch den Moderator

- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Neuer Artikel Erstellen eines EA, der automatisch funktioniert (Teil 08): OnTradeTransaktion :
In diesem Artikel erfahren Sie, wie Sie das Ereignisbehandlungssystem nutzen können, um Probleme im Zusammenhang mit dem Auftragssystem schnell und effizient zu bearbeiten. Mit diesem System wird der EA schneller arbeiten, sodass er nicht ständig nach den benötigten Daten suchen muss.
Jetzt haben wir endlich die Klasse C_Manager und den EA, die miteinander befreundet sind, in einer viel vollständigeren Form. Beides kann funktionieren und dafür sorgen, dass sie nicht aggressiv oder unfreundlich werden. Der Nachrichtenfluss zwischen dem EA und der Klasse C_Manager entspricht somit dem in Abbildung 02:
Abbildung 02. Nachrichtenfluss mit neuen Funktionen
Dieser Ablauf mag zu kompliziert oder völlig unfunktional erscheinen, aber genau das ist bisher umgesetzt worden.
Wenn man sich Abbildung 02 ansieht, könnte man meinen, dass der EA-Code sehr komplex ist. Aber es ist viel einfacher als das, was viele Leute für einen notwendigen Code für einen EA halten. Vor allem, wenn es sich um einen automatisierten EA handelt. Denken Sie an das Folgende: Der EA generiert eigentlich keine Trades. Es ist lediglich ein Mittel oder Werkzeug für die Kommunikation mit dem Handelsserver. Es reagiert also eigentlich nur auf Auslöser, die auf es angewendet werden.
Autor: Daniel Jose