Скачать MetaTrader 5

Ошибка 130 при отправке любого рыночного ордера

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Есть вопросы по реализации идеи? Обсуди их на форуме!
Александр
26
Александр 2011.10.16 13:14 

Здравствуйте.

Есть советник, использующий в торговле рыночные (не отложенные и не лимитные) ордера. ТФ: Д1. Ордер открывается строго с новой свечой, т.е. началом нового дня, стопы ставятся фиксировано и далеко от цены открытия, профиты - варьируются, но с ними тоже всё нормально в плане: к цене открытия слишком близко не стоят. НО ордера не принимаются сервером, т.е. вылазит ошибка 130 (неправильные стопы).

Не могу понять, в чём дело. Раньше думал, что из-за ещё пары советников, которые тоже в начале нового дня открываются, но нет: убрал их все - проблема осталась. Потом сделал до боли простой советник: открывает buy/Sell сделку в конце текущего дня в 23:50 (или позже). Ордер был отправлен в 23:50, но ошибка всё та же! И главное: по тестам всё нормально, никаких ошибок нет и работает идеально! Потому приходится вручную всё открывать...

Счёт реальный (рублёвый), не демо. Брокер: Alpari. Советники на отложенных ордерах проходят и открываются нормально.

Буду рад возможным советам.

Александр
26
Александр 2011.10.16 13:23  

Вот код открытия сделки:

bool WaitForTradeContext()

{
int P = 0;
// цикл "пока"
while(IsTradeContextBusy() && P < 5)
{
P++;
Sleep(1000);
}
// -------------
if(P == 5)
return(False);
return(True);
}

double ND(double A)
{
return(NormalizeDouble(A, Digits));
}

int OpenOrderCorrect(int Type, double Lot, double Price, double SL, double TP,
bool Redefinition = True)
// Redefinition - при True доопределять параметры до минимально допустимых
// при False - возвращать ошибку
{
// - 1 - == Проверка достаточности свободных средств ====================================
if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lot) <= 0 || GetLastError() == 134)
{
if(!FreeMarginAlert)
{
Print("Недостаточно средств для открытия позиции. Free Margin = ",
AccountFreeMargin());
FreeMarginAlert = True;
}
return(5);
}
FreeMarginAlert = False;
// - 1 - == Окончание блока =============================================================

// - 2 - == Корректировка значений Price, SL и TP или возврат ошибки ====================
RefreshRates();
switch (Type)
{
case OP_BUY:
string S = "BUY";
if (MathAbs(Price-Ask)/Point > 3)
if (Redefinition) Price = ND(Ask);
else return(2);
if (ND(TP-Bid) <= StopLevel && TP != 0)
if (Redefinition) TP = ND(Bid+StopLevel+Tick);
else return(4);
if (ND(Bid-SL) <= StopLevel)
if (Redefinition) SL = ND(Bid-StopLevel-Tick);
else return(3);
break;
case OP_SELL:
S = "SELL";
if (MathAbs(Price-Bid)/Point > 3)
if (Redefinition) Price = ND(Bid);
else return(2);
if (ND(Ask-TP) <= StopLevel)
if (Redefinition) TP = ND(Ask-StopLevel-Tick);
else return(4);
if (ND(SL-Ask) <= StopLevel && SL != 0)
if (Redefinition) SL = ND(Ask+StopLevel+Tick);
else return(3);
break;
case OP_BUYSTOP:
S = "BUYSTOP";
if (ND(Price-Ask) <= StopLevel)
if (Redefinition) Price = ND(Ask+StopLevel+Tick);
else return(2);
if (ND(TP-Price) <= StopLevel && TP != 0)
if (Redefinition) TP = ND(Price+StopLevel+Tick);
else return(4);
if (ND(Price-SL) <= StopLevel)
if (Redefinition) SL = ND(Price-StopLevel-Tick);
else return(3);
break;
case OP_SELLSTOP:
S = "SELLSTOP";
if (ND(Bid-Price) <= StopLevel)
if (Redefinition) Price = ND(Bid-StopLevel-Tick);
else return(2);
if (ND(Price-TP) <= StopLevel)
if (Redefinition) TP = ND(Price-StopLevel-Tick);
else return(4);
if (ND(SL-Price) <= StopLevel && SL != 0)
if (Redefinition) SL = ND(Price+StopLevel+Tick);
else return(3);
break;
case OP_BUYLIMIT:
S = "BUYLIMIT";
if (ND(Ask-Price) <= StopLevel)
if (Redefinition) Price = ND(Ask-StopLevel-Tick);
else return(2);
if (ND(TP-Price) <= StopLevel && TP != 0)
if (Redefinition) TP = ND(Price+StopLevel+Tick);
else return(4);
if (ND(Price-SL) <= StopLevel)
if (Redefinition) SL = ND(Price-StopLevel-Tick);
else return(3);
break;
case OP_SELLLIMIT:
S = "SELLLIMIT";
if (ND(Price - Bid) <= StopLevel)
if (Redefinition) Price = ND(Bid+StopLevel+Tick);
else return(2);
if (ND(Price-TP) <= StopLevel)
if (Redefinition) TP = ND(Price-StopLevel-Tick);
else return(4);
if (ND(SL-Price) <= StopLevel && SL != 0)
if (Redefinition) SL = ND(Price+StopLevel+Tick);
else return(3);
break;
}
// - 2 - == Окончание блока =============================================================

// - 3 - == Открытие ордера с ожидание торгового потока =================================
if(WaitForTradeContext()) // ожидание освобождения торгового потока
{
Comment("Отправлен запрос на открытие ордера ", S, " ...");
int ticket=OrderSend(Symbol(), Type, Lot, Price, 3,
SL, TP, NULL, MagicNumber, 0);// открытие позиции
// Попытка открытия позиции завершилась неудачей
if(ticket<0)
{
int Error = GetLastError();
if(Error == 2 || Error == 5 || Error == 6 || Error == 64
|| Error == 132 || Error == 133 || Error == 149) // список фатальных ошибок
{
Comment("Фатальная ошибка при открытии позиции т. к. "+
ErrorToString(Error)+" Советник отключен!");
FatalError = True;
}
else
Comment("Ошибка открытия позиции ", S, ": ", Error); // нефатальная ошибка
return(1);
}
// ---------------------------------------------

// Удачное открытие позиции
Comment("Позиция ", S, " открыта успешно!");
PlaySound(OpenOrderSound);
return(ticket);
// ------------------------
}
else
{
Comment("Время ожидания освобождения торгового потока истекло!");
return(1);
}
// - 3 - == Окончание блока =============================================================

}


А вот код start-функция советника, которые в текущий день пытается открыть сделку после 23:50:

if (ticket3 == 0) {
if ((TimeHour(TimeCurrent()) == 23) && (TimeMinute(TimeCurrent()) >= 50)) {
double _V2;

V2 = Open[0] - Ask;
tp2 = Ask + Profit*MathAbs(_V2)/100;
ticket = OpenOrderCorrect(OP_BUY, Lot, Ask, Low[0], tp2, true);
ticket3 = 1;
}

}

ticket3 и ticket изначально = 0.

o_o
Модератор
23694
o_o 2011.10.16 16:04  
Accemt:
а стопы не ставить при рыночном открытии пробовали?
Sergey Guliaev
2302
Sergey Guliaev 2011.10.17 08:14  
Accemt:

Здравствуйте.

Буду рад возможным советам.

Уважаемый, выкладывайте код при помощи кнопки SRC.

case OP_BUY: 
 string S = "BUY"; 
 if (MathAbs(Price-Ask)/Point > 3)
 if (Redefinition) Price = ND(Ask);
 else return(2);
//......
 break;

у вас else к какому if относится? Ордера OP_BUY и OP_SELL можно открыть только по текущей цене, для чего вы мудрите с этим Redefinition

Vladimir Paukas
4099
Vladimir Paukas 2011.10.17 08:34  
Accemt:

Здравствуйте.

Есть советник, использующий в торговле рыночные (не отложенные и не лимитные) ордера. ТФ: Д1. Ордер открывается строго с новой свечой, т.е. началом нового дня, стопы ставятся фиксировано и далеко от цены открытия, профиты - варьируются, но с ними тоже всё нормально в плане: к цене открытия слишком близко не стоят. НО ордера не принимаются сервером, т.е. вылазит ошибка 130 (неправильные стопы).

Не могу понять, в чём дело. Раньше думал, что из-за ещё пары советников, которые тоже в начале нового дня открываются, но нет: убрал их все - проблема осталась. Потом сделал до боли простой советник: открывает buy/Sell сделку в конце текущего дня в 23:50 (или позже). Ордер был отправлен в 23:50, но ошибка всё та же! И главное: по тестам всё нормально, никаких ошибок нет и работает идеально! Потому приходится вручную всё открывать...

Счёт реальный (рублёвый), не демо. Брокер: Alpari. Советники на отложенных ордерах проходят и открываются нормально.

Буду рад возможным советам.

Проверьте какой тип ордера передается в OrderSend
Актер
2301
Актер 2011.10.17 08:42  
Да просто счет ндд, стопы нельзя задавать сразу, только после открытия.
Ihor Herasko
9056
Ihor Herasko 2011.10.17 08:43  
valenok2003:

Уважаемый, выкладывайте код при помощи кнопки SRC.

у вас else к какому if относится? Ордера OP_BUY и OP_SELL можно открыть только по текущей цене, для чего вы мудрите с этим Redefinition

В коде все верно. Объяснения могу дать, т.к. код разрабатывал я.

Функция OpenOrderCorrect разрабатывалась для корректировки всевозможных ошибок, возникающих во время поступления торговых приказов. Параметр Redefinition необходим для установки правильной рыночной цены. Например, функция OpenOrderCorrect вызывается с неправильной ценой открытия рыночного ордера, которая отличается от текущей рыночной цены на три пункта (такой слипадж установлен ниже). Если установлен параметр Redefinition, то функция сама подставляет правильную цену. Если Redefinition = false, то функция вернет ошибку. Так что else там относится к правильному if.

Ошибка, возникающая при запрете брокером установки стопов и профитов во время открытия позиции (Market Execution), здесь не прорабатывалась, т.к. код должен был быть использован только на счетах одного конкретного брокера (пользователь Accempt должен знать этого брокера, т.к. с его сайта взят этот код), у которого тип исполнения ордеров Instant Execution, что не приводит к возникновению указанной ошибки.

Sergey Guliaev
2302
Sergey Guliaev 2011.10.17 09:15  
Scriptong:

В коде все верно.

Самая распространённая ошибка программистов )))
Ihor Herasko
9056
Ihor Herasko 2011.10.17 09:36  
valenok2003:
Самая распространённая ошибка программистов )))

Ну так в чем ошибка то? С моей стороны последовало объяснение. С вашей будет?
Виктор
Модератор
6559
Виктор 2011.10.17 09:40  
Scriptong:

Ну так в чем ошибка то? С моей стороны последовало объяснение. С вашей будет?
Он пошутил. Видимо, имел в виду, что самая распространенная ошибка программистов - считать, что в их коде все верно :))

"Если вам кажется, что все идет хорошо, значит вы чего-то не заметили" (с) Мэрфи
Ihor Herasko
9056
Ihor Herasko 2011.10.17 09:42  
granit77:
Он пошутил. Видимо, имел в виду, что самая распространенная ошибка программистов - считать, что в их коде все верно :))

"Если вам кажется, что все идет хорошо, значит вы чего-то не заметили" (с) Мэрфи


Спасибо)))

Забыл с утра чувство юмора включить. А то сразу весь в кодах...

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий