Ошибка при исполнении ордера!

 

Я только третий день изучаю MQL4, сегодня столкнулся с проблемой, когда исполняется ордер, эксперт дальше ничего не делает и выдает ошибку 4108. Помогите разобраться! Ниже приводится текст программы. Она простая, взята из книжки и немного измененная. Должна продавать, когда MACD ниже ноля и ставить ордер на 100 пунктов выше и наоборот.
P.S. Я просто тренируюсь:-)

//+------------------------------------------------------------------+
//| FIRST1.mq4 |
//| олег |
//| |
//+------------------------------------------------------------------+
#property copyright "олег"
#property link ""

#define STATE_SQUARE 0
#define STATE_LONG 1
#define STATE_SHORT 2

//---- input parameters
extern int MAPeriod=13;
extern double LotsNumber=1.0;

//---- глобальные переменные
int CurrentState;
int MyOrderTicket;


//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
if (iMACD(NULL, 0, 5, 34, 5, 0, 0, 0) >0 )
CurrentState = STATE_SHORT;
else CurrentState = STATE_LONG;

MyOrderTicket = 0;
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----

//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
int err;

double MA;
MA = iMACD(NULL, 0, 5, 34, 5, 0, 0, 0);


if ( CurrentState == STATE_LONG)
{
if (MA < 0) //МАСД МЕНЬШЕ НОЛЯ, БУДЕМ ПРОДАВАТЬ
{
CurrentState = STATE_SHORT;

//переворачиваемся в продажу

//---закрыть позицию, если была открыта
if ( MyOrderTicket != 0)
{
if (!OrderClose(MyOrderTicket, LotsNumber, Bid, 3, CLR_NONE))
{
err = GetLastError();
Print("Ошибка при закрытии позиции: ", err);
return(0);
}
MyOrderTicket = 0;
}
RefreshRates();

//--- длинная позиция была закрыта успешно

//--- теперь откроем позицию в продажу


MyOrderTicket = OrderSend(Symbol(), OP_SELL, LotsNumber, Bid, 3, Bid+1, 0,
NULL, 0, 0, CLR_NONE);
if (MyOrderTicket<0)
{
err = GetLastError();
Print("Ошибка при открытии позиции: ", err);
MyOrderTicket = 0;
}
}
}
else
{
if (MA > 0) //ЕСЛИ МАСД БОЛЬШЕ НОЛЯ, БУДЕМ ПОКУПАТЬ
{
CurrentState = STATE_LONG;

//переворачиваемся в покупку

//---закрыть позицию, если была открыта
if ( MyOrderTicket != 0)
{
if (!OrderClose(MyOrderTicket, LotsNumber, Ask, 3, CLR_NONE))
{
err = GetLastError();
Print("Ошибка при закрытии позиции: ", err);
return(0);
}
MyOrderTicket = 0;
}
RefreshRates();

//--- короткая позиция была закрыта успешно

//--- теперь откроем позицию в покупку


MyOrderTicket = OrderSend(Symbol(), OP_BUY, LotsNumber, Ask, 3, Ask-1, 0,
NULL, 0, 0, CLR_NONE);
if (MyOrderTicket<0)
{
err = GetLastError();
Print("Ошибка при открытии позиции: ", err);
MyOrderTicket = 0;
}
}
}
//----
return(0);
}

 
Проблемы у вас здесь:
MyOrderTicket = OrderSend(Symbol(), OP_SELL, LotsNumber, Bid, 3, Bid+1, 0, NULL, 0, 0, CLR_NONE);
и здесь:
MyOrderTicket = OrderSend(Symbol(), OP_BUY, LotsNumber, Ask, 3, Ask-1, 0, NULL, 0, 0, CLR_NONE);
Если вы хотели отложить ордер на 100 пунктов ниже или выше, то почему используете команды OP_BUY и OP_SELL? Это ведь рыночные ордера, а не отложенные. Хотя параметры, которые вы используете, больше подходят именно для рыночных ордеров. Единственное - наступили на грабли, на которые многие наступают:

Bid+1
Цена Bid у вас, например, для евро будет 1.52. Теперь прибавляем 1. Выходит 2.52. В ближайшем будущем такой цены не будет. Поэтому вы и получаете ошибку.

Вобщем, вместо Bid+1 используйте Bid+1*Point. Хотя сомневаюсь, что уровень стопов вашего брокера позволит так близко выставить профит или стоп. Поэтому используйте значение больше 10 - не промахнетесь.
 

Спасибо, с уровнем стопов понятно.теперь использую bid+100*point. Советника делал под фунт-йену, поэтому и прибавлял 1. А строка

MyOrderTicket = OrderSend ( Symbol (), OP_SELL, LotsNumber, Bid, 3, Bid + 1, 0, NULL, 0, 0, CLR_NONE ) ;

изначально выглядела:

MyOrderTicket = OrderSend ( Symbol (), OP_SELL, LotsNumber, Bid, 3, 0, 0, NULL, 0, 0, CLR_NONE ) ;

предназначалась для открытия позиции, а я решил чтобы сразу устанавливался и stoploss (100п). Но ничего не вышло. Стоп ставится, но при его исполнении останавливается вся программа:-(((

Две строки: if ( MyOrderTicket != 0)

переписал на: if ( MyOrderTicket > 0)

но все равно, как было, так и осталось!

 
Я специально проверил все работает, если изменить стоп...

Только вы используете нулевой бар для расчета значения МАСД и, когда МАСД колеблется около нуля, открываются туда-сюда позиции. В этом случае пересечение лучше определять как разные знаки МАСД на соседних барах. И лучше, если это будет не 0-ой и 1-ый бар, а 1-ый и 2-ой, так как они уже сформированы.

Хотя могу предположить, что счет, на котором вы тестируете, имеет ограничение на максимальное количество лотов меньше 1. Попробуйте разные значения лота 0.01-0.1.
Еще может быть, что ДЦ не разрешает сразу выставлять стопы и профиты, а только модифицировать их. Тогда нужно открыть позицию, а потом изменить эти уровни.
Причина обращения: