Error número 6 - página 8

 
la autopsia ha revelado el uso incorrecto del código de error 139. de hecho es "el contexto comercial está ocupado", para el que no hay ningún código especial por alguna razón. un problema similar se ha discutido hoy en el foro inglés "Trade Dispatcher: all trade context is busy".
sólo hay un contexto de comercio para todos los EAs. la solución correcta es construir su propio sistema de semáforos en las variables globales.
he ejecutado 4 EAs en 4 minutos. en 10 minutos el error 139 ha ocurrido 7 veces
 
la autopsia reveló un mal uso del código de error 139. de hecho es "el contexto comercial está ocupado", para el cual no hay un código especial por alguna razón. un problema similar fue discutido hoy en el foro inglés "Trade Dispatcher: all trade context is busy"
sólo hay un contexto de comercio para todos los EAs. la solución correcta es construir su propio sistema de semáforo en las variables globales.
He ejecutado 4 EAs en 4 min. en 10 min. 7 veces error 139


¿Podría decirme, al menos en términos generales, cómo debería ser este sistema de semáforos?
1. En particular, cómo debe hacerse un intercambio para no interferir con otros.
2. Resbalones, comprobaciones, tiempos muertos (que se prometió que no habría en la MT multihilo, pero vamos)

Y por último. No te lo tomes como un reproche. Tienes un libro de texto. En él se da el experto. Enséñame esos semáforos de ahí.

Aquí está mi experto. Tan simple como unos pantalones por un rublo veinte. Cambia de posición cada hora. Si realmente se preocupan por los comerciantes y los beneficios de los corredores (no sé acerca de la gente, pero quiero conseguir un EA de trabajo estable en primer lugar, y luego cambiar de demo a real), entonces por favor, en el ejemplo de este EA mío, muéstrame cómo debo hacerlo bien.

Sinceramente,
Quark

P.D. La cuestión del origen de los errores 2, 6, 138 y 4109, que también aparecen a veces, sigue abierta.
 
<br / translate="no"> discutido un problema similar hoy en el foro Inglés "Despacho de comercio: todo el contexto comercial está ocupado"


He leído el hilo en inglés. Sí... Estos chicos necesitan aprender ruso urgentemente.
No es similar, es el mismo problema. Es cierto, aún no tienen los errores 2, 6, 138 y 4109. Sólo hablaban de 139.

No veo el sentido de IsTradeAllowed, para ser honesto. El propio Slava explicó cómo diez Asesores Expertos pueden utilizar esta función y de repente comienzan a operar y todos, excepto el primero, se decepcionan.

Sería mucho mejor poner en cola las peticiones, donde se acumularían, vivirían durante algún tiempo, y se ejecutarían o se borrarían. Pero todo esto es un sueño.

Más bien, tendríamos que crear una variable global nTrading, por ejemplo, y almacenar allí el nombre del Asesor Experto. ¿Y qué deberían hacer los demás EA? Volver a MT3 con sus órdenes pendientes ¿O hay otras ideas?

Por cierto, podemos prescindir de la variable global, algo así como

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



donde Buy() y Sell() devuelven OP_BUY / OP_SELL en caso de fallo y -1 en caso de éxito.

Las desventajas son obvias: el corredor recibirá diez órdenes para abrir (cerrar) en lugar de una. Si es automático, todo está bien. Si es un humano, se ofenderá. Peor aún, si el autómata y el humano actúan según una lógica diferente. Por ejemplo, un autómata no tiene cola (como nos explicó Slava, un hilo, y las órdenes compiten en lugar de formar una cola), y un humano sí. Entonces el trader empieza a operar en el real, y ni siquiera entenderá por qué, porque le aseguraron (a mí - en el seminario-presentación en Alpari) que no hay diferencia entre el demo y el real.

La segunda opción - a cada experto y moneda se le asigna su propio Mn, para que la combinación de Asesor Experto + moneda sea única. Entonces escribimos el código de tal manera que el EA con IM1 operará en el primer segundo, con IM7 - en el séptimo segundo, etc. después de la apertura de la barra. Esto le dará al sistema un segundo para operar.

Pregunta a Slava: ¿es suficiente un segundo para evitar el problema?

Las desventajas son obvias, los scalpers - pipsers te las contarán :)

Estimados desarrolladores (y todos). Gracias por las aclaraciones. Todavía hay algunas preguntas sin respuesta en este y en anteriores posts. Esperando una respuesta.

Quark




 
Y una pregunta más. ¿Se refiere la situación en cuestión a las órdenes de suspensión? ¿Compiten los expertos por su ejecución?
 
//+------------------------------------------------------------------+
//|                                                    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 para hacer una función para establecer el valor de una variable global con la condición de que esta variable tiene un cierto valor, por lo que no hay construcción

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


entonces será 100% fiable
algo así como

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




 
Y una pregunta más. ¿Se refiere la situación en cuestión a las órdenes de suspensión? ¿Compiten los Asesores Expertos por su ejecución?

No. Las paradas se ejecutan en el servidor.
 
Más bien, tendríamos que hacer una variable global nTrading, por ejemplo, y escribir en ella el nombre del Asesor Experto que está operando actualmente. ¿Y qué deberían hacer los demás EA? Volver a MT3 con sus órdenes pendientes ¿o hay otras ideas?
Para mí personalmente hay una pausa obligatoria entre las operaciones (ajustable, ahora es de 30 segundos). No es un obstáculo para el comercio rentable, pero protege de situaciones similares. Se implementa a través de una variable global. Semáforo y pausa - 2 en uno =)

Y sobre la cola - Tuve una idea para hacer un EA que ejecuta órdenes escritas en un archivo. Y todos los demás expertos sólo escriben órdenes en este archivo.
Pero no es muy fácil para mí (en el sentido de una aplicación competente)... Pero es posible intentarlo. Por el esfuerzo común =))
 
Gracias :)

Este es el pasaje que no entendí:

<br/ translate="no"> si hacer una función para establecer el valor de una variable global siempre que esa variable tenga un valor determinado para que no haya construcción

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


Ahora sobre la lógica de este caso. Siento molestarle, pero...

Si lo he entendido bien, estamos sentados en un bucle while hasta que consigamos poner el semáforo. ¿Verdad? Entonces comerciamos, sabiendo que nadie está comerciando excepto nosotros. Luego devolvemos el semáforo a su estado original.

Pregunta: ¿cómo funciona while(!IsStopped())? ? Pensaba que era una comprobación para permitir el comercio en vivo.

Pregunta: ¿esos tiempos de espera y de reposo no provocarán retrasos en el sistema?

Pregunta: ¿se procesarán correctamente el sueño y el semáforo en el modo de prueba?

Otra pregunta lógica. Entre poner y quitar el semáforo tenemos dos posibilidades (como máximo) para manejar las órdenes. Primero Buy() o Sell() y luego, debajo, CloseOrder(). ¿No competirán estas dos "actividades" entre sí, aunque dentro del EA, como si hubiera dos Asesores Expertos? ¿O se garantiza que el proceso es lineal y no llegará a CloseOrder() hasta que vuelva Buy()?

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

No. Las paradas se gestionan en el servidor. y en nuestro caso hay competencia por el flujo de operaciones del cliente experto


Me expresé mal. Debe OrderSend(OP_BUYSTOP... ¿también rodearlo de código que establezca y elimine semáforos? Una pregunta tonta. Claro que sí.
 
He adjuntado el Asesor Experto, publicado en el primer post de la cuarta página, al eur - m15.
Rehecho las funciones de comercio (conectado mi biblioteca) y adjuntado a otro euram - m15. Meijic, por supuesto, ha sido cambiado.

Ya os contaré lo que tengo por la noche ;)