Ошибка номер 6 - страница 8

 
вскрытие показало неправильное использование кода ошибки 139. на самом деле это "trade context is busy", для которого почему-то не завели специального кода. сегодня обсуждали аналогичную проблему на английском форуме "Trade Dispatcher: all trade context is busy"
для всех экспертов существует только один торговый поток. правильным решением будет строительство собственной системы семафоров на глобальных переменных.
я запустил 4 эксперта на 4 минутках. за 10 минут работы 7 раз ошибка 139
 
вскрытие показало неправильное использование кода ошибки 139. на самом деле это "trade context is busy", для которого почему-то не завели специального кода. сегодня обсуждали аналогичную проблему на английском форуме "Trade Dispatcher: all trade context is busy"
для всех экспертов существует только один торговый поток. правильным решением будет строительство собственной системы семафоров на глобальных переменных.
я запустил 4 эксперта на 4 минутках. за 10 минут работы 7 раз ошибка 139


Не могли бы вы, хотя бы в общих чертах, рассказать, какой должна быть эта система семафоров?
1. В частности, как должна совершаться сделка, чтобы не мешать другим.
2. Слипы, проверки, таймауты (которых обещали, что нет в многопотоковом МТ, ну да ладно)

Ну и наконец. Не сочтите за упрек. У вас есть учебник. В нем приведен эксперт. Покажите мне там эти семафоры.

Вот мой эксперт. Прост, как трусы за рубль двадцать. Каждый час перевернуть позицию. Если Вы действительно заботитесь о трейдерах и о доходах брокеров (не знаю, кто как, а я хочу сначала получить стабильно работающий эксперт, а затем переходить с демо на реал), то пожалуйста, на примере этого моего эксперта, покажите, как НАДО делать правильно.

С уважением,
Кварк

П.С. Вопрос о происхождении ошибки 2, 6, 138 и 4109, которые тоже иногда вылезают, остается открытым.
 

сегодня обсуждали аналогичную проблему на английском форуме "Trade Dispatcher: all trade context is busy"


Прочитал я англоязычную ветку. Н-да... Этим ребятам надо срочно учить русский.
Это не аналогичная, это та же самая проблема. Правда, ошибки 2, 6, 138 и 4109 они пока не получили. Речь шла только о 139.

Смысла в IsTradeAllowed я не вижу, если честно. Слава сам же объяснил, как десять экспертов получают добро от этой функции, после чего дружно кидаются торговать, и обламываются все, кроме первого.

Куда лучше было бы сделать очередь запросов, где они бы накапливались, жили некоторое время, и либо исполнялись, либо удалялись. Но это все мечты.

Скорее, придется делать глобальную переменную nTrading, например, и писать в нее мн торгующего в данный момент эксперта. Закономерный вопрос - а что делать остальным экспертам? Опять назад, к МТ3 с его pending ордерами... или есть другие идеи?

Кстати, можно и без глобальной переменной, достаточно чего-то вроде

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



где Buy() и Sell() возвращают OP_BUY / OP_SELL при неудаче и -1 в случае успеха.

Минусы очевидны - брокер получит десять ордеров на открытие (закрытие), вместо одного. Если это автомат, все хорошо. Если человек - он обидится. Хуже, если автомат и человек действуют по разной логике. Например, у автомата нет очереди (как нам объяснил Слава, один поток, и ордера конкурируют, вместо того, чтобы строиться в очередь), а у человека есть. Тогда, начав торговать в реале, трейдер прогорит, и даже не поймет почему, ведь его уверяли (меня - на семинаре-презентации в Альпари), что нет никакой разницы между демо и реалом.

Второй вариант - каждому эксперту и валюте присваивается свой мн, так, что сочетание эксперт + валюта уникально. Затем пишем код так, что эксперт с мн 1 торгует в первую секунду, с мн 7 - в седьмую и т.д. после открытия бара. Это даст системе секунду на сделку.

Вопрос Славе - хватит ли секунды, чтобы избежать проблемы?

Минусы очевидны, о них вам расскажут скальперы - пипсовики :)

Уважаемые разработчики (и все-все-все). Спасибо за разъяснения. В этом и предыдущих постах остались неотвеченные вопросы. Жду ответа.

Кварк




 
И еще один вопрос. Относится ли обсуждаемая ситуация к стоп ордерам? Конкурируют ли эксперты за их исполнение?
 
//+------------------------------------------------------------------+
//|                                                    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);
}

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


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

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


тогда будет 100 процентов надёжности
что-то типа

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




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

нет. стопы отрабатываются на сервере. а в нашем случае идёт конкуренция за экспертный торговый поток клиента
 
корее, придется делать глобальную переменную nTrading, например, и писать в нее мн торгующего в данный момент эксперта. Закономерный вопрос - а что делать остальным экспертам? Опять назад, к МТ3 с его pending ордерами... или есть другие идеи?
Лично у меня между сделками - обязательная пауза (настраиваемая, сейчас 30 сек). Для прибыльной торговли это вряд ли преграда, а от подобных ситуаций защищает. Реализовано через глоб. переменную. Семафор и пауза - 2 в одном =)

А на счёт очереди - у меня была идея сделать эксперта, исполняющего ордера, записанные в файле. А всеми остальными экспертами просто писАть в этот файл приказы.
Но это не очень просто, как для меня ( в смысле, грамотно реализовать )... Но попробовать можно. Общими усилиями =))
 
Спасибо :)

Вот этот пассаж я не понял:


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

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


Теперь насчет логики этого дела. Вы уж извините, что пристаю, но...

Если я правильно понял, мы сидим в цикле while до тех пор, пока не удастся выставить семафор. Так? Потом торгуем, зная, что кроме нас никто не торгует. Потом возвращаем семафор к исходному состоянию.

Вопрос: как работает while(!IsStopped()) ? Из хелпа не совсем понятно, я-то думал, это проверка на Allow Live Trading.

Вопрос: эти while и Sleep не будут тормозить систему?

Вопрос: будет ли Sleep и семафор корректно обрабатываться в режиме тестирования?

Еще по логике. Между установкой и снятием семафора, у нас две (максимум) возможности работы с ордерами. Сначала Buy() или Sell() и потом, ниже, CloseOrder(). Не будут ли эти две "активности" конкурировать друг с другом, хоть внутри эксперта, но также, как если бы экспертов было два? Или процесс гарантированно линеен, и пока Buy() не вернется, до CloseOrder() дело не дойдет?

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

нет. стопы отрабатываются на сервере. а в нашем случае идёт конкуренция за экспертный торговый поток клиента


Я неправильно выразился. Надо ли OrderSend(OP_BUYSTOP... тоже окружать кодом, устанавливающим и снимающим семафоры? Глупый вопрос. Надо, конечно.
 
Прикрепил эксперта, выложенного в 1-м посте на 4-й странице, на евру - м15.
Переделал торговые ф-ции (подключил свою библиотеку) и повесил на другую евру - м15. Мейджик, есс-но, поменял.

Ближе к ночи скажу, что получилось ;)