Fehler Nummer 6 - Seite 8

 
die autopsie hat ergeben, dass der fehlercode 139 nicht korrekt verwendet wird. in Wirklichkeit handelt es sich um "trade context is busy", für den es aus irgendeinem Grund keinen speziellen code gibt. ein ähnliches problem wurde heute im englischen forum "Trade Dispatcher: all trade context is busy" diskutiert .
Es gibt nur einen Handelskontext für alle EAs. Die richtige Lösung ist, ein eigenes System von Semaphoren auf globalen Variablen zu erstellen.
ich habe 4 EAs auf 4 Minuten laufen lassen. in 10 Minuten ist der Fehler 139 7 mal aufgetreten
 
die autopsie ergab, dass der fehlercode 139 falsch verwendet wurde. in Wirklichkeit handelt es sich um "trade context is busy", für den es aus irgendeinem Grund keinen speziellen code gibt. ein ähnliches problem wurde heute im englischen forum diskutiert "Trade Dispatcher: all trade context is busy"
Es gibt nur einen Handelskontext für alle EAs. Die richtige Lösung ist, ein eigenes Semaphorensystem auf globalen Variablen aufzubauen.
Ich habe 4 EAs auf 4 Min. in 10 Min. laufen lassen. 7 mal Fehler 139


Könnten Sie mir zumindest in groben Zügen sagen, wie dieses System von Semaphoren aussehen sollte?
1. Insbesondere, wie ein Handel zu erfolgen hat, um andere nicht zu beeinträchtigen.
2. Ausrutscher, Überprüfungen, Zeitüberschreitungen (die es bei MT mit mehreren Threads nicht geben sollte, aber was soll's)

Und schließlich. Verstehen Sie das nicht als Vorwurf. Sie haben ein Lehrbuch. Darin wird der Experte genannt. Zeigen Sie mir die Semaphoren dort.

Hier ist mein Experte. Einfach wie eine Hose für einen Rubel zwanzig. Wechseln Sie jede Stunde eine Position. Wenn Sie sich wirklich um Händler und Gewinne von Brokern kümmern (ich weiß nicht, wie es anderen geht, aber ich möchte zuerst einen stabilen, funktionierenden EA haben und dann von Demo zu Real wechseln), dann zeigen Sie mir bitte am Beispiel dieses EAs von mir, wie ich es richtig machen sollte.

Mit freundlichen Grüßen,
Quark

P.S. Die Frage nach dem Ursprung der Fehler 2, 6, 138 und 4109, die ebenfalls manchmal auftreten, bleibt offen.
 
<br / translate="no"> ein ähnliches Problem wurde heute im englischen Forum "Trade Dispatcher: all trade context is busy" diskutiert.


Ich habe den englischsprachigen Thread gelesen. Ja... Diese Leute müssen dringend Russisch lernen.
Es ist nicht ähnlich, es ist das gleiche Problem. Es stimmt, die Fehler 2, 6, 138 und 4109 sind noch nicht aufgetreten. Sie sprachen nur von 139.

Um ehrlich zu sein, sehe ich den Sinn von IsTradeAllowed nicht. Slava selbst erklärte, wie zehn Expert Advisors diese Funktion nutzen dürfen und dann plötzlich anfangen zu handeln und alle außer dem ersten enttäuscht werden.

Es wäre viel besser, die Anfragen in eine Warteschlange zu stellen, in der sie sich stapeln, einige Zeit leben und dann entweder ausgeführt oder gelöscht werden. Aber das ist alles nur ein Traum.

Vielmehr müssten wir z.B. eine globale Variable nTrading anlegen und dort den Namen des Expert Advisors speichern. Und was sollten andere EAs tun? Zurück zum MT3 mit seinen schwebenden Aufträgen gehen Oder gibt es andere Ideen?

Übrigens können wir auch ohne globale Variable auskommen, etwa so

if(nPending == OP_BUY) nPending = Buy(); else if(nPending == OP_SELL) nPending = Sell();



wobei Buy() und Sell() bei Fehlschlag OP_BUY / OP_SELL und bei Erfolg -1 zurückgeben.

Die Nachteile liegen auf der Hand: Der Makler erhält zehn Aufträge zur Eröffnung (Schließung) anstelle von einem. Wenn dies automatisch geschieht, ist alles in Ordnung. Wenn es ein Mensch ist, wird er beleidigt sein. Schlimmer noch, wenn der Automat und der Mensch nach einer anderen Logik handeln. Ein Automat hat zum Beispiel keine Warteschlange (wie Slava uns erklärte, einen Thread, und die Aufträge konkurrieren miteinander, anstatt eine Warteschlange zu bilden), ein Mensch hingegen schon. Dann fängt der Händler an, mit dem echten Handel zu beginnen, und er wird nicht einmal verstehen, warum, denn ihm wurde versichert (mir - bei der Seminar-Präsentation in Alpari), dass es keinen Unterschied zwischen Demo und echt gibt.

Die zweite Option - jedem Experten und jeder Währung wird eine eigene Mn zugewiesen, so dass die Kombination aus Expert Advisor und Währung einzigartig ist. Dann schreiben wir den Code so, dass der EA mit IM1 in der ersten Sekunde handelt, mit IM7 - in der siebten Sekunde, usw. nach der Öffnung des Balkens. Dadurch erhält das System eine Sekunde Zeit zum Handeln.

Frage an Slava: Reicht eine Sekunde aus, um das Problem zu vermeiden?

Nachteile sind offensichtlich, scalpers - pipsers wird Ihnen sagen, über sie :)

Liebe Entwickler (und alle anderen). Vielen Dank für die Klarstellung. In diesem und in früheren Beiträgen sind noch einige Fragen unbeantwortet geblieben. Ich warte auf eine Antwort.

Quark




 
Und noch eine Frage. Handelt es sich bei der fraglichen Situation um einen Stoppauftrag? Konkurrieren die Experten um ihre Ausführung?
 
//+------------------------------------------------------------------+
//|                                                    TestQuark.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

double dStopLoss;
int nHoursToHold;

datetime timePrev = 0;

int nSlip = 5;

double dLotSize = 0.1;

int nMagic = 0;
string SemaphoreName="TradeSemaphore";

//////////////////
int init ()
{
   if(!GlobalVariableCheck(SemaphoreName)) GlobalVariableSet(SemaphoreName,0.0);
	
	timePrev = 0;

	dStopLoss = 110 * Point;
	nHoursToHold = 1;
	
	if(Symbol() == "EURUSD")
		nMagic = 1;
	else if(Symbol() == "EURJPY")
		nMagic = 2;
	else if(Symbol() == "USDCHF")
		nMagic = 3;
	else if(Symbol() == "GBPUSD")
		nMagic = 4;
	else if(Symbol() == "GBPJPY")
		nMagic = 5;
	else if(Symbol() == "GBPCHF")
		nMagic = 6;
	else if(Symbol() == "USDJPY")
		nMagic = 7;
	else if(Symbol() == "AUDUSD")
		nMagic = 8;
	else if(Symbol() == "EURGBP")
		nMagic = 9;
	else if(Symbol() == "USDCAD")
		nMagic = 10;
	else if(Symbol() == "EURCHF")
		nMagic = 11;
	else if(Symbol() == "EURAUD")
		nMagic = 12;
		
	timePrev += nMagic;	// Open nMagic seconds after the new bar

	return(0);	
}

// ------

int deinit()
{
	return(0);
}
// ------
int start()
{
	if(Bars < 5)
		return(0);
	
	// The previous bar just closed
	bool bIsBarEnd = false;
	if(timePrev != Time[0] + nMagic) 
		bIsBarEnd = true;
	timePrev = Time[0] + nMagic;
	
	if(!bIsBarEnd)
		return(0);

	// ------
	
	int nSignal = GetSignal();

	bool bSemaphored=false;
   while(!IsStopped())
     {
      if(GlobalVariableGet(SemaphoreName)==0.0)
        {
         GlobalVariableSet(SemaphoreName,1.0);
         bSemaphored=true;
         break;
        }
      Sleep(1000);
     }

	if(nSignal == OP_BUY) 
		Buy();
	else if(nSignal == OP_SELL) 
		Sell();

	for(int nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--)
	{
		OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES);

		if(OrderMagicNumber() == nMagic)
		{
			if(CurTime() - OrderOpenTime() > (nHoursToHold - 1) * 60 * 60)
			{
				if(OrderType() == OP_BUY)
					OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua);
				else if(OrderType() == OP_SELL)
					OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed);
			}
		}
	}

	if(bSemaphored) GlobalVariableSet(SemaphoreName,0.0);	

	return(0);
}
// ------

void Sell()
{
	if(AccountFreeMargin() < 500)
		return;

	dLotSize = GetLotSize();

	int nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, 
		0, "Friday", nMagic, 0, OrangeRed);

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", " + nError);
	}
}
// ------
void Buy()
{
	if(AccountFreeMargin() < 500)
		return;

	dLotSize = GetLotSize();

	int nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, 
		0, "Friday", nMagic, 0, Aqua);

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", " + nError);
	}
}
// ------

double GetLotSize()
{
	double dLot = 0.1;
	
	return(dLot);
}

// ------

int GetSignal()
{
	int nSignal;
	if(MathMod(Hour(), 2) == 0)
		nSignal = OP_BUY;
	else
		nSignal = OP_SELL;
		
	return(nSignal);
}

//+------------------------------------------------------------------+


wenn eine Funktion den Wert einer globalen Variablen setzen soll, vorausgesetzt, diese Variable hat einen bestimmten Wert, so dass es kein Konstrukt
gibt.

      if(GlobalVariableGet(SemaphorName)==0.0) { GlobalVariableSet(SemaphorName,1.0); bSemaphored=true; break; }


dann wird es 100% zuverlässig sein
etwas wie

      if(GlobalVariableSetOnCondition(SemaphorName,1.0,0)==true) { bSemaphored=true; break; }




 
Und noch eine Frage. Handelt es sich bei der fraglichen Situation um einen Stoppauftrag? Konkurrieren Expert Advisors um ihre Ausführung?

Nein. Stopps werden auf dem Server ausgeführt.
 
Stattdessen müssten wir z.B. eine globale Variable nTrading erstellen und darin den Namen des aktuell handelnden Expert Advisors eintragen. Und was sollten die anderen EAs tun? Gehen Sie zurück zu MT3 mit seinen ausstehenden Aufträgen oder gibt es andere Ideen?
Für mich persönlich gibt es eine obligatorische Pause zwischen den Trades (einstellbar, jetzt sind es 30 Sekunden). Das ist kaum ein Hindernis für einen profitablen Handel, aber es schützt vor ähnlichen Situationen. Sie wird durch eine globale Variable implementiert. Semaphor und Pause - 2 in einem =)

Und über die Warteschlange - ich hatte eine Idee, einen EA zu machen, der Aufträge ausführt , die in eine Datei geschrieben wurden. Und alle anderen Experten schreiben einfach Aufträge in diese Datei.
Aber es ist nicht sehr einfach für mich (im Sinne einer kompetenten Umsetzung)... Aber es ist möglich, es zu versuchen. Durch gemeinsame Anstrengungen =))
 
Danke :)

Dies ist die Stelle, die ich nicht verstanden habe:

<br/ translate="no"> wenn eine Funktion zum Setzen des Wertes einer globalen Variablen erstellt wird, vorausgesetzt, dass ein bestimmter Wert in dieser Variablen vorhanden ist, so dass es kein Konstrukt gibt

if(GlobalVariableGet(SemaphoreName)==0.0)
{
GlobalVariableSet(SemaphorName,1.0);
bSemaphored=true;
break;
}


Nun zur Logik dieses Falles. Entschuldigen Sie, dass ich Sie belästige, aber...

Wenn ich es richtig verstanden habe, befinden wir uns in einer while-Schleife, bis wir es schaffen, das Semaphor zu setzen. Oder? Dann handeln wir in dem Wissen, dass niemand außer uns handelt. Dann versetzen wir die Semaphore wieder in ihren ursprünglichen Zustand.

Frage: Wie funktioniert while(!IsStopped())? ? Ich dachte, es handele sich um einen Scheck für "Live Trading zulassen".

Frage: Verursachen diese "while" und "Sleep" nicht Verzögerungen im System?

Frage: Werden Sleep und Semaphore im Testmodus korrekt verarbeitet?

Eine weitere logische Frage. Zwischen dem Setzen und Entfernen des Semaphors gibt es (maximal) zwei Möglichkeiten, Aufträge zu bearbeiten. Zuerst Buy() oder Sell() und dann, darunter, CloseOrder(). Werden diese beiden "Aktivitäten" innerhalb des EA nicht miteinander konkurrieren, so als gäbe es zwei Expert Advisors? Oder ist der Prozess garantiert linear und erreicht CloseOrder() erst, wenn Buy() zurückkehrt?

Ich danke Ihnen im Voraus.
Quark
 
И еще один вопрос. Относится ли обсуждаемая ситуация к стоп ордерам? Конкурируют ли эксперты за их исполнение?

Nein. Die Stopps werden auf dem Server abgewickelt, und in unserem Fall gibt es einen Wettbewerb um den Handelsfluss der Experten des Kunden.


Ich habe mich falsch ausgedrückt. Sollte OrderSend(OP_BUYSTOP... auch mit Code umgeben, der Semaphoren setzt und entfernt? Dumme Frage. Sicher, das sollten Sie.
 
Ich habe den Expert Advisor, der im 1. Beitrag auf der 4. Seite gepostet wurde, an den eur - m15 angehängt.
Ich habe die Handelsfunktionen überarbeitet (meine Bibliothek angeschlossen) und sie mit einem anderen euram - m15 verbunden. Meijic hat sich natürlich verändert.

Ich werde dir später am Abend sagen, was ich habe ;)