home

Давайте перепишем нашего эксперта с учетом этого совета. В этом нам поможет функция OrderCloseBy():

 

 //+------------------------------------------------------------------+
//| Close everything on Friday.mq4 |
//| Copyright © 2006, Andrey Vedikhin |
//| http://www.vedikhin.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Andrey Vedikhin"
#property link "http://www.vedikhin.ru"


//---- input parameters
extern int MyHour=22;
extern int MyMinute=00;

// 5 - Friday
#define MyDay 5

datetime LastTradeTime;

//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
// установим время последней торговой операции вчерашним днем
LastTradeTime = CurTime()-24*60*60;
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----


//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
// проверим, не закрывали ли мы все уже сегодня
// если да - выходим
if (TimeDayOfYear(CurTime())==TimeDayOfYear(LastTradeTime)) return(0);

// если не пятница - выходим
if (DayOfWeek()!=MyDay) return(0);


// проверим, не наступило ли время закрывать позиции
if (((TimeHour(CurTime())==MyHour)&&(TimeMinute(CurTime())>=MyMinute))
||(TimeHour(CurTime())>MyHour))
{
// закроем все позиции и удалим ордера
while (OrdersTotal()>0)
{
// выделим первую позицию или ордер в списке
if (!OrderSelect(0, SELECT_BY_POS))
// в случае неудачи выйти из цикла
break;

// если отложенный ордер, то удалить
if (OrderType()>OP_SELL)
{
if (!OrderDelete(OrderTicket()))
{
Print("Ошибка ", GetLastError()," при удалении отложенного ордера ",
OrderTicket());
break;
}
}
// если открытая позиция, то закрыть
else
{
// попробуем найти локированную позицию по этому же инструменту
int ticket0;
ticket0 = OrderTicket();

string symbol0;
symbol0 = OrderSymbol();

int ordertype0;
ordertype0 = OrderType();

int i;
for (i = 1; i

// заново выделим нулевую позицию
if (!OrderSelect(ticket0, SELECT_BY_TICKET))
// в случае неудачи выйти из цикла
break;

double price;
if (OrderType()==OP_SELL)
price = MarketInfo(OrderSymbol(), MODE_ASK);
else
price = MarketInfo(OrderSymbol(), MODE_BID);


if (!OrderClose(OrderTicket(), OrderLots(), price, 3))
{
Print("Ошибка ", GetLastError()," при закрытии позиции ",
OrderTicket());
break;
}
}

// пауза 10 секунд
Sleep(10000);
}
if (OrdersTotal()==0) LastTradeTime = CurTime();
}

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


 

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

 

 bool OrderCloseBy(int ticket, int opposite, color сolor=CLR_NONE)


 

Функция OrderCloseBy() закрывает одну позицию другой позицией по тому же самому инструменту. В случае успеха она возвращает true, а в случае ошибки — false. Код ошибки можно в дальнейшем узнать с помощью функции GetLastError().

Параметры функции OrderCloseBy():

  • ticket — тикер первой позиции;
  • opposite — тикер второй позиции;
  • сolor — цвет закрывающей стрелки на графике. Если параметр отсутствует или его значение равно CLR_NONE, то закрывающая стрелка не отображается на графике.

Разберем каждую новую строчку нашего эксперта:

 

 // попробуем найти локированную позицию по этому же инструменту
int ticket0;
ticket0 = OrderTicket();

string symbol0;
symbol0 = OrderSymbol();

int ordertype0;
ordertype0 = OrderType();

int i;
for (i = 1; i


// заново выделим нулевую позицию
if (!OrderSelect(ticket0, SELECT_BY_TICKET))
// в случае неудачи выйти из цикла
break;


 

Вначале запомним номер тикера, инструмент и тип операции выделенной позиции (первой в списке открытых позиций и отложенных ордеров) в переменных ticket0, symbol0 и ordertype0 соответственно:

 

 int ticket0;
ticket0 = OrderTicket();


string symbol0;
symbol0 = OrderSymbol();

int ordertype0;
ordertype0 = OrderType();


 

После этого в цикле переберем все оставшиеся позиции в поиске позиции, чтобы найти позицию по тому же инструменту, но открытую в другом направлении (OrderType()==((ordertype0+1)%2)):

 

 int i;
for (i = 1; i

 

Если такую позицию мы нашли, то закроем ее и нашу первоначально выделенную позицию с помощью функции OrderCloseBy() и в случае успеха присвоим переменной i значение -2.

Далее мы проверяем были ли закрыты локированные позиции. Если «да», то делаем паузу и переходим к следующей итерации цикла while, т.е. смотрим следующую позицию/ордер — кандидатов на закрытие/удаление:

 

 if (i==-2)
{
Sleep(10000);
continue;
}


 

Если же локированные позиции были не найдены, то вновь выделяем первую позицию в списке открытых позиций и отложенных ордеров:

 

 if (!OrderSelect(ticket0, SELECT_BY_TICKET)) 
// в случае неудачи выйти из цикла
break;


 

Далее пытаемся закрыть эту позицию с помощью функции OrderClose().