Erreur numéro 6 - page 8

 
l'autopsie a révélé une utilisation incorrecte du code d'erreur 139. en fait, il s'agit de "trade context is busy", pour lequel il n'existe pas de code spécial pour une raison quelconque. un problème similaire a été discuté aujourd'hui dans le forum anglais "Trade Dispatcher : all trade context is busy".
il n'y a qu'un seul contexte de transaction pour tous les EAs. la solution correcte est de construire votre propre système de sémaphores sur les variables globales.
J'ai exécuté 4 EAs sur 4 minutes. En 10 minutes, l'erreur 139 s'est produite 7 fois.
 
l'autopsie a révélé une utilisation incorrecte du code d'erreur 139. en fait, il s'agit de "trade context is busy", pour lequel il n'existe pas de code spécial pour une raison quelconque. un problème similaire a été discuté aujourd'hui sur le forum anglais "Trade Dispatcher: all trade context is busy"
il n'y a qu'un seul contexte de transaction pour tous les EAs. la solution correcte est de construire votre propre système de sémaphore sur les variables globales.
J'ai exécuté 4 EAs sur 4 min. en 10 min. 7 fois erreur 139


Pourriez-vous me dire, au moins en termes généraux, ce que devrait être ce système de sémaphores ?
1. En particulier, la manière dont un échange doit être effectué pour ne pas gêner les autres.
2. Dérapages, vérifications, délais d'attente (dont on avait promis l'absence dans les MT multithreads, mais bon)

Et enfin. Ne prenez pas ça comme une réprimande. Vous avez un manuel scolaire. L'expert y est donné. Montre-moi ces sémaphores là.

Voici mon expert. Simple comme un pantalon pour un rouble vingt. Changez de position toutes les heures. Si vous vous souciez vraiment des traders et des profits des courtiers (je ne sais pas ce qu'il en est pour les autres, mais je veux d'abord obtenir un EA stable et fonctionnel, et ensuite passer de la démo au réel), alors s'il vous plaît, sur l'exemple de mon EA, montrez-moi comment je dois faire correctement.

Sincèrement,
Quark

P.S. La question de l'origine des erreurs 2, 6, 138 et 4109, qui apparaissent aussi parfois, reste ouverte.
 
<br / translate="no"> ont discuté d'un problème similaire aujourd'hui sur le forum anglais "Trade Dispatcher : all trade context is busy".


J'ai lu le fil de discussion sur la langue anglaise. Ouais... Ces gars-là ont besoin d'apprendre le russe de toute urgence.
Ce n'est pas similaire, c'est le même problème. C'est vrai, ils n'ont pas encore les erreurs 2, 6, 138 et 4109. Ils ne parlaient que de 139.

Je ne vois pas l'intérêt de IsTradeAllowed, pour être honnête. Slava lui-même a expliqué comment dix conseillers-experts sont autorisés à utiliser cette fonction, puis commencent soudainement à trader et tout le monde, sauf le premier, est déçu.

Il serait bien mieux de mettre les demandes en file d'attente, où elles s'empileraient, vivraient un certain temps, avant d'être exécutées ou supprimées. Mais tout ceci n'est qu'un rêve.

Il faudrait plutôt créer une variable globale nTrading, par exemple, et y stocker le nom du conseiller expert. Et que doivent faire les autres EA ? Retournez à MT3 avec ses ordres en attente Ou y a-t-il d'autres idées ?

D'ailleurs, on peut faire sans variable globale, quelque chose comme

si(nPending == OP_BUY) nPending = Buy() ; sinon si(nPending == OP_SELL) nPending = Sell() ;



où Buy() et Sell() renvoient OP_BUY / OP_SELL en cas d'échec et -1 en cas de succès.

Les inconvénients sont évidents : le courtier recevra dix ordres à ouvrir (fermer) au lieu d'un seul. S'il est automatique, tout va bien. Si c'est un humain - il sera offensé. Pire, si l'automate et l'humain agissent selon une logique différente. Par exemple, un automate n'a pas de file d'attente (comme nous l'a expliqué Slava, un seul fil, et les ordres se concurrencent au lieu de former une file d'attente), et un humain en a une. Ensuite, le trader commence à trader sur le réel, et il ne comprendra même pas pourquoi, car on lui a assuré (moi - lors du séminaire-présentation à Alpari) qu'il n'y a pas de différence entre la démo et le réel.

La deuxième option - chaque expert et chaque devise se voit attribuer son propre Mn, de sorte que la combinaison Conseiller expert + devise est unique. Ensuite, nous écrivons le code de manière à ce que l'EA avec mn 1 soit négocié à la première seconde, avec mn 7 - à la septième seconde, etc. après l'ouverture de la barre. Cela donnera au système une seconde pour négocier.

Question à Slava : une seconde suffit-elle pour éviter le problème ?

Les inconvénients sont évidents, les scalpeurs - pipsers vous en parleront :)

Chers développeurs (et tous les autres). Merci pour les éclaircissements. Il y a encore des questions sans réponse dans ce message et les précédents. J'attends une réponse.

Quark




 
Et une dernière question. La situation examinée fait-elle référence à des ordres stop? Les experts sont-ils en concurrence pour leur exécution ?
 
//+------------------------------------------------------------------+
//|                                                    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);
}

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


si faire une fonction pour fixer la valeur d'une variable globale à condition que cette variable ait une certaine valeur, afin qu'il n'y ait pas de construction
.

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


alors il sera 100% fiable
quelque chose comme

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




 
Et une dernière question. La situation examinée fait-elle référence à des ordres stop ? Les conseillers experts sont-ils en concurrence pour leur exécution ?

Non. Les arrêts sont exécutés sur le serveur.
 
Il faudrait plutôt créer une variable globale nTrading, par exemple, et y inscrire le nom du conseiller expert en cours de négociation. Et que doivent faire les autres EA ? Retournez à MT3 avec ses ordres en attente ou il y a d'autres idées ?
Pour moi personnellement, il y a une pause obligatoire entre les transactions (réglable, maintenant c'est 30 sec). Il ne s'agit pas d'un obstacle à une négociation rentable, mais d'une protection contre des situations similaires. Elle est mise en œuvre par le biais d'une variable globale. Sémaphore et pause - 2 en 1 =)

Et à propos de la file d'attente - j'ai eu l'idée de faire un EA qui exécute les ordres écrits dans un fichier. Et tous les autres experts se contentent d'écrire des ordres dans ce fichier.
Mais ce n'est pas très facile pour moi (dans le sens d'une mise en œuvre compétente)... Mais il est possible d'essayer. Par un effort commun =))
 
Merci :)

Voici le passage que je n'ai pas compris :

<br/ translate="no">si faire une fonction pour définir la valeur d'une variable globale à condition que cette variable ait une certaine valeur afin qu'il n'y ait pas de construction

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


Maintenant, à propos de la logique de cette affaire. Désolé de vous embêter, mais...

Si j'ai bien compris, on est assis dans une boucle while jusqu'à ce qu'on arrive à activer le sémaphore. N'est-ce pas ? Puis nous échangeons, en sachant que personne n'échange à part nous. Ensuite, nous remettons le sémaphore dans son état initial.

Question : comment fonctionne while(!IsStopped()) ? ? Je pensais qu'il s'agissait d'un chèque pour "Permettre le commerce en direct".

Question : ces temps d'attente et de veille ne vont-ils pas provoquer des décalages dans le système ?

Question : Sleep et sémaphore seront-ils traités correctement en mode test?

Une autre question logique. Entre la mise en place et le retrait du sémaphore, nous avons deux possibilités (maximum) de traiter les commandes. D'abord Buy() ou Sell() et ensuite, en dessous, CloseOrder(). Ces deux "activités" ne vont-elles pas se faire concurrence, bien qu'à l'intérieur de l'EA, comme s'il y avait deux Expert Advisors ? Ou bien le processus est garanti linéaire et il n'atteindra pas CloseOrder() avant le retour de Buy() ?

Merci d'avance.
Quark
 
И еще один вопрос. Относится ли обсуждаемая ситуация к стоп ордерам? Конкурируют ли эксперты за их исполнение?

Non. Les arrêts sont gérés sur le serveur. Et dans notre cas, il y a une concurrence pour le flux de trading expert du client.


Je me suis mal exprimé. Si OrderSend(OP_BUYSTOP... l'entourer également de code qui active et désactive les sémaphores ? Question idiote. Bien sûr, vous devriez.
 
J'ai attaché le Conseiller Expert, posté dans le 1er message de la 4ème page, à l'eur - m15.
J'ai retravaillé les fonctions de commerce (branché dans ma bibliothèque) et l'ai attaché à un autre euram - m15. Meijic, bien sûr, a été changé.

Je vous dirai ce que j'ai plus tard dans la nuit ;)
Raison: