Error number 6 - page 9

 
Slava, I have put your expert version, for 12 windows (12 currencies). There are fewer errors, but they are there. Sorry. I managed to get 138 and 1. Try it yourself.

Hope for further guidance.

Quark
 
By the way, code
while(!IsStopped()) { if(GlobalVariableGet(strTradeSemaphore) == 0.0) { GlobalVariableSet(strTradeSemaphore, 1.0); bSemaphored = true; break; } Sleep(1000); }



admits that between(GlobalVariableGet(strTradeSemaphore) == 0.0) and GlobalVariableSet(strTradeSemaphore, 1.0); another EA will cut in. We need a function that will capture and inhibit the execution thread (i.e. wait for the resource) and then return control to the Expert Advisor. Something like WaitForExclusive()

. Although, perhaps it is not the point. But the errors keep appearing, alas.

 
That's better. But errors have appeared that weren't there before, such as error 1.
Hope to get some help.

By the way, now that this conversation has started, how can I automatically determine how many digits to leave for the price using NormalizeDouble, i.e. 4 for EURUSD, 2 for EURJPY... ?

double dStopLoss;
int nHoursToHold;

datetime timePrev = 0;

int nSlip = 5;

double dLotSize = 0.1;

int nMagic = 0;
int nDigits = 4;

string strTradeSemaphore = "TradeSemaphore";

//////////////////
int init ()
{
	if(!GlobalVariableCheck(strTradeSemaphore)) 
		GlobalVariableSet(strTradeSemaphore, 0.0);
	
	dStopLoss = 110 * Point;
	nHoursToHold = 1;
	
	if(Symbol() == "EURUSD")
		nMagic = 1;
	else if(Symbol() == "EURJPY")
	{
		nMagic = 2;
		nDigits = 2;
	}
	else if(Symbol() == "USDCHF")
		nMagic = 3;
	else if(Symbol() == "GBPUSD")
		nMagic = 4;
	else if(Symbol() == "GBPJPY")
	{
		nMagic = 5;
		nDigits = 2;
	}
	else if(Symbol() == "GBPCHF")
		nMagic = 6;
	else if(Symbol() == "USDJPY")
	{
		nMagic = 7;
		nDigits = 2;
	}
	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;
		
	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();

	while(!IsStopped())
	{
		if(GlobalVariableGet(strTradeSemaphore) == 0.0)
			GlobalVariableSet(strTradeSemaphore, nMagic);

		if(GlobalVariableGet(strTradeSemaphore) == nMagic)
			break;
		
		Sleep(1000);
	}

	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(nSignal == OP_BUY) 
		Buy();
	else if(nSignal == OP_SELL) 
		Sell();

	GlobalVariableSet(strTradeSemaphore, 0.0);	

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

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

	dLotSize = GetLotSize();

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

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", sell: " + NormalizeDouble(Bid, nDigits) + ", Stop: " + 
			NormalizeDouble(Bid + dStopLoss, nDigits) + ", error: " + nError);
	}
}

// ------

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

	dLotSize = GetLotSize();

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

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", buy: " + NormalizeDouble(Ask, nDigits) + 
			", Stop: " + NormalizeDouble(Ask - dStopLoss, nDigits) + ", error: " + 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);
}

 
Error 138 does sometimes appear (I run 12 pairs on minutes, so it doesn't take long to get an error), and also error 129 at a perfectly normal price.
 
So. Error 1. Loosely translated from the helpdesk "something is wrong". 12 currency pairs on minutes, error about once every 5-10 minutes.

Error 138. Several times a minute (i.e. several of 12 Expert Advisors generate it).

Error 129. I was rationing prices and doing a lot of other things...
 
In fact, now that we're talking about it, how do you automatically determine how many digits to leave for the price with NormalizeDouble, i.e. 4 for EURUSD, 2 for EURJPY...? ?
	int _Digits = MarketInfo( Symbol(), MODE_DIGITS );




and your Expert Advisor with my 5 gave me one error - 6.
my Expert Advisor does not work in my correction - they messed up in this build =)
oh yeah... my 5 doesn't work either =)))) here we go...

 
стати, раз уж этот разговор возник, как автоматически определить, сколько знаков оставлять для цены при помощи NormalizeDouble, то есть, 4 для EURUSD, 2 для EURJPY... ?
	int _Digits = MarketInfo( Symbol(), MODE_DIGITS );




and your Expert Advisor with my 5 gave one error - 6.
my Expert Advisor does not work in my correction - they messed up in this build =)
oh yeah... my 5 doesn't work either =)))) oh man...



Thanks for the code, it would have taken me a long time to find it myself.
The expert suggested by Slava and improved :) by me is given below. You can run it like me - in 12 windows, with 12 currencies. It works for any timeframe, but it's faster on minutes.) I keep getting errors, damn it. I wish I knew why.

double dStopLoss;
int nHoursToHold;

datetime timePrev = 0;

int nSlip = 50;

double dLotSize = 0.1;

int nMagic = 0;
int nDigits;

string strTradeSemaphore = "TradeSemaphore";

//////////////////
int init ()
{
	if(!GlobalVariableCheck(strTradeSemaphore)) 
		GlobalVariableSet(strTradeSemaphore, 0.0);
	
	dStopLoss = 110 * Point;
	nHoursToHold = 1;

	nDigits = MarketInfo( Symbol(), MODE_DIGITS );
	
	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;
		
	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);

	// ------
	
	while(!IsStopped())
	{
		if(GlobalVariableGet(strTradeSemaphore) == 0.0)
			GlobalVariableSet(strTradeSemaphore, nMagic);

		if(GlobalVariableGet(strTradeSemaphore) == nMagic)
			break;
		
		Sleep(1000);
	}

	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);
			}
		}
	}

	Sleep(500);

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

	Sleep(500);
	
	GlobalVariableSet(strTradeSemaphore, 0.0);	
	
	return(0);
}
// ------

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

	dLotSize = GetLotSize();

	double dNormalizer = MathPow(10, nDigits);
	double dBid = MathFloor(Bid * dNormalizer) / dNormalizer; //NormalizeDouble(Bid, nDigits);
	double dStop = MathFloor((Bid + dStopLoss) * dNormalizer) / dNormalizer; //NormalizeDouble(Bid + dStopLoss, nDigits);

	int nResult = OrderSend(Symbol(), OP_SELL, dLotSize, dBid, 
		nSlip, dStop, 0, "Friday", nMagic, 0, OrangeRed);

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", sell: " + dBid + ", Stop: " + dStop + ", error: " + nError);
	}
}

// ------

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

	dLotSize = GetLotSize();

	double dNormalizer = MathPow(10, nDigits);
	double dAsk = MathFloor(Ask * dNormalizer) / dNormalizer; //NormalizeDouble(Bid, nDigits);
	double dStop = MathFloor((Ask - dStopLoss) * dNormalizer) / dNormalizer; //NormalizeDouble(Bid + dStopLoss, nDigits);

	int nResult = OrderSend(Symbol(), OP_BUY, dLotSize, dAsk, 
		nSlip, dStop, 0, "Friday", nMagic, 0, Aqua);

	if(nResult == -1)
	{
		int nError = GetLastError();
		Alert(Symbol() + ", buy: " + dAsk + 
			", Stop: " + dStop + ", error: " + 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);
}


 
By the way, code [skipped]<br/ translate="no"> allows for another EA to cut in between if(GlobalVariableGet(strTradeSemaphore) == 0.0) and GlobalVariableSet(strTradeSemaphore, 1.0);. We need a function that will capture and inhibit the execution thread (i.e. wait for the resource) and then return control to the Expert Advisor. Something like WaitForExclusive()

. Although, perhaps it is not the point. But alas, the errors keep appearing.

this is exactly what i meant about hypothetical function GlobalVariableSetOnCondition, that could set global variable as first parameter, provided its value is equal to the value of second parameter. since access to global variables is blocked, it will give "atomicity"

now about function IsStopped. it checks stop flag, so that EA could normally stop (it has 2.5 seconds for that). it is recommended to use this function as one of loop conditions, especially infinite
 
<br / translate="no"> that's why I was talking about a hypothetical function GlobalVariableSetOnCondition, which could set a global variable by the first parameter, provided its value equals the value of the second parameter. since access to global variables is blocked, this would give "atomicity"


Slava, for the life of me, I don't understand this text. Please explain it in other words, or show me what you mean. If you can.

By the way, what's wrong in the code I've rewritten? I mean, it's clear that something is wrong because it doesn't work, but I don't see the error. According to my hunch, this is what should have provided exclusive access...

while(!IsStopped()) { if(GlobalVariableGet(strTradeSemaphore) == 0.0) GlobalVariableSet(strTradeSemaphore, nMagic); if(GlobalVariableGet(strTradeSemaphore) == nMagic) break; Sleep(1000); }
 

именно так. я поэтому и говорил про гипотетическую функцию GlobalVariableSetOnCondition, которая могла бы устанавливать глобальную переменную первым параметром при условии, что значение её равно значению второго параметра. так как доступ к глобальным переменным блокируется, то это даст "атомарность"


Slava, for the life of me, I don't understand this text. Either explain it in other words, or show me what you mean. If you can.

We are talking about preventing the possibility of wedging between calls of GlobalVariableGet and GlobalVariableSet functions. wedging by another Expert Advisor is real since errors are still observed. this is why I'm talking about atomic access. you and I are talking about solving one and the same problem but in different words
.

By the way, what's wrong in the piece of code I reworked? I mean, it's clear that something is wrong as it doesn't work, but I don't see the error. According to my hunch, this is what should have provided exclusive access...

while(!IsStopped()) { if(GlobalVariableGet(strTradeSemaphore) == 0.0) GlobalVariableSet(strTradeSemaphore, nMagic); if(GlobalVariableGet(strTradeSemaphore) == nMagic) break; Sleep(1000); }



Your example is better
Reason: