Erro número 6 - página 8

 
a autópsia revelou o uso incorreto do código de erro 139. na verdade é "o contexto comercial está ocupado", para o qual por alguma razão não foi criado um código especial. um problema semelhante foi discutido hoje no fórum inglês "Trade Dispatcher: all trade context is busy".
há apenas um contexto comercial para todos os EAs. a solução correta é construir seu próprio sistema de semáforos sobre variáveis globais.
em 4 minutos. em 10 minutos o erro 139 ocorreu 7 vezes
 
a autópsia revelou um uso indevido do código de erro 139. na verdade é "o contexto comercial está ocupado", para o qual não existe um código especial por algum motivo. um problema semelhante foi discutido hoje no fórum inglês "Trade Dispatcher: all trade context is busy"
há apenas um contexto comercial para todos os EAs. a solução correta é construir seu próprio sistema semáforo sobre variáveis globais.
Eu executei 4 EAs em 4 min. em 10 min. 7 vezes erro 139


Você poderia me dizer, pelo menos em termos gerais, qual deveria ser este sistema de semáforos?
1. Em particular, como um comércio deve ser feito para não interferir com outros.
2. Escorregões, cheques, timeouts (que foram prometidos para estar ausentes em MT multithreaded, mas vamos lá)

E finalmente. Não tome isto como uma reprimenda. Você tem um livro didático. Nele é dado o especialista. Mostre-me aqueles semáforos ali.

Eis o meu especialista. Simples como uma calça para um rublo vinte. Vire uma posição a cada hora. Se você realmente se importa com comerciantes e lucros de corretores (eu não sei sobre as pessoas, mas quero primeiro obter uma EA estável funcionando, e depois mudar de demonstração para real), então, por favor, no exemplo desta minha EA, mostre-me como eu devo fazer isso direito.

Sinceramente,
Quark

P.S. A questão da origem dos erros 2, 6, 138 e 4109, que às vezes também aparecem, permanece em aberto.
 
<br / translate="no"> discutiu um problema semelhante hoje no fórum inglês "Trade Dispatcher: all trade context is busy" (Despachante comercial: todo o contexto comercial está ocupado)


Eu li o tópico em inglês. Sim... Esses caras precisam aprender russo urgentemente.
Não é similar, é o mesmo problema. É verdade, eles ainda não têm erros 2, 6, 138 e 4109. Eles estavam falando apenas de 139.

Para ser honesto, não vejo o ponto em IsTradeAllowed. O próprio Slava explicou como dez Expert Advisors podem usar esta função e, de repente, começar a negociar e todos, exceto o primeiro, ficam desapontados.

Seria muito melhor fazer fila de pedidos onde eles se amontoassem, vivessem por algum tempo e fossem executados ou excluídos. Mas tudo isto é um sonho.

Ao invés disso, teríamos que criar uma variável global nTrading, por exemplo, e armazenar ali o nome do Expert Advisor. E o que outros EAs devem fazer? Voltar ao MT3 com suas ordens pendentes Ou existem outras idéias?

A propósito, podemos prescindir da variável global, algo como

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



onde Buy() e Sell() devolvem OP_BUY / OP_SELL em caso de fracasso e -1 em caso de sucesso.

As desvantagens são óbvias - o corretor receberá dez ordens para abrir (fechar) em vez de uma. Se for automático, tudo está bem. Se for um ser humano - será ofendido. Pior, se o autômato e o humano agem de acordo com lógica diferente. Por exemplo, um autômato não tem fila (como Slava nos explicou, um fio, e as ordens competem em vez de formar uma fila), e um humano sim. Então o comerciante começa a negociar no real, e ele nem vai entender o porquê, porque ele recebeu a garantia (eu - na apresentação do seminário em Alpari) de que não há diferença entre demonstração e real.

A segunda opção - a cada especialista e moeda é atribuído seu próprio Mn, de modo que a combinação Expert Advisor + moeda é única. Depois escrevemos o código de tal forma que a EA com IM1 negociará no primeiro segundo, com IM7 - no sétimo segundo, etc., após a abertura da barra. Isto dará ao sistema um segundo para o comércio.

Pergunta a Slava - é um segundo o suficiente para evitar o problema?

As desvantagens são óbvias, os escalpadores - os pistões lhe falarão sobre elas :)

Caros desenvolvedores (e tudo mais). Obrigado pelos esclarecimentos. Ainda há algumas perguntas não respondidas neste e em posts anteriores. Esperando por uma resposta.

Quark




 
E mais uma pergunta. A situação em discussão se refere a ordens de parada? Os especialistas competem por sua execução?
 
//+------------------------------------------------------------------+
//|                                                    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);
}

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


se for feita uma função para definir o valor de uma variável global na condição de que essa variável tenha um determinado valor, de modo que não haja construção

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


então será 100% confiável
algo como

      if(GlobalVariableSetOnCondition(SemaforeName,1.0,0)==verdadeiro) { bSemaphored=verdadeiro; break; }




 
E mais uma pergunta. A situação em discussão se refere a ordens de parada? Os Expert Advisors competem por sua execução?

Não. As paradas são executadas no servidor.
 
Ao invés disso, teríamos que fazer uma variável global nTrading, por exemplo, e escrever nela o nome do Expert Advisor atualmente em negociação. E o que os outros EAs devem fazer? Voltar ao MT3 com suas ordens pendentes ou há outras idéias?
Para mim pessoalmente há uma pausa obrigatória entre os ofícios (ajustável, agora é de 30 segundos). Dificilmente é um obstáculo para o comércio lucrativo, mas protege de situações semelhantes. Ela é implementada através de uma variável global. Semáforo e pausa - 2 em 1 =)

E sobre a fila - tive a idéia de fazer uma EA que executasse ordens escritas em um arquivo. E todos os outros especialistas apenas escrevem ordens a este arquivo.
Mas não é muito fácil para mim ( no sentido de uma implementação competente )... Mas é possível tentar. Por esforço comum =)))
 
Obrigado :)

Esta é a passagem que eu não entendi:

<br/ translate="no"> if make a function to set the value of a global variable provided that variable has a certain value so that there is no construct

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


Agora sobre a lógica deste caso. Desculpe incomodá-lo, mas...

Se entendi corretamente, estamos sentados em um loop até conseguirmos definir o semáforo. Certo? Então nós negociamos, sabendo que ninguém está negociando, exceto nós. Então devolvemos o semáforo ao seu estado original.

Pergunta: como funciona(!IsStopped())? ? Pensei que era um cheque para permitir o comércio ao vivo.

Pergunta: esses não causarão atrasos no sistema enquanto dormem?

Pergunta: o sono e o semáforo serão processados corretamente em modo de teste?

Outra pergunta lógica. Entre o ajuste e a remoção do semáforo, temos duas (máximas) possibilidades para tratar as ordens. Primeiro Comprar() ou Vender() e depois, abaixo dele, FecharOrdem(). Essas duas "atividades" não irão competir entre si, embora dentro da EA, como se houvesse dois Conselheiros Especializados? Ou o processo é garantidamente linear e não alcançará CloseOrder() até que a Buy() retorne?

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

Não. As paradas são tratadas no servidor. e em nosso caso há concorrência para o fluxo comercial especializado do cliente


Eu falei mal. Caso Encomende(OP_BUYSTOP... também o envolve com código que define e remove os semáforos? Pergunta boba. Claro, você deve.
 
Anexei o Assessor Especialista, postado no 1º post da 4ª página, ao eur - m15.
Reestruturou as funções comerciais (conectou minha biblioteca) e a anexou a outro euram - m15. Meijic, é claro, foi mudado.

Vou lhe dizer o que tenho mais tarde à noite ;)