Всем привет! Советник работает хорошо, но бывает выскакивает ошибка 130, а бывает не выставляет ТП, бывает очень редко, в основном на движухе и то не всегда. Но это очень напрягает. Вот кусок кода и модификация ордера. NumberOfTry=5 , то есть всего 5 попыток. Понимаю, что цена за это время пока он крутит эти 5 попыток цикле уходит дальше чем ТП+Проскальзывание и потому вылетает эта ошибка 130. Но как сделать, чтобы он открывал по цене какая есть? Хотя тоже понимаю, что цена может рвануть сильно и никакое проскальзывание не спасёт и будет невозможно выставить ТП даже по новой цене или это не так? В общем, помогите опытные товарищи, советом как поступить?!
{ int TpOneBuy = 0; TpOneBuy = Mass[CountTradesBuy()]; ticket=OrderSend(Symbol(),OP_BUY,Lot,Ask,Slippage,0,0,comment,Magic,0,Blue); if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { TPBuy=NormalizeDouble(Ask+TpOneBuy*Point,Digits); for(CountTP=0; CountTP<NumberOfTry; CountTP++) // Цикл повторения попыток установки ТР { if(OrderModify(ticket,OrderOpenPrice(),0,TPBuy,0)) break; else { ErrorTP=GetLastError(); Print("Ошибка установки TP Buy = ",ErrorTP); Sleep(400); } } }
GetLastError() — функция, возвращающая коды ошибок. Кодовые константы ошибок определены
в файле stderror.mqh. Для вывода текстовых сообщений следует использовать функцию
ErrorDescription(), определенную в файле stdlib.mqh.
Константа | Значение | Описание |
---|---|---|
ERR_NO_ERROR | 0 | Нет ошибки |
ERR_NO_RESULT | 1 | Нет ошибки, но результат неизвестен |
ERR_COMMON_ERROR | 2 | Общая ошибка |
ERR_INVALID_TRADE_PARAMETERS | 3 | Неправильные параметры |
ERR_SERVER_BUSY | 4 | Торговый сервер занят |
ERR_OLD_VERSION | 5 | Старая версия клиентского терминала |
ERR_NO_CONNECTION | 6 | Нет связи с торговым сервером |
ERR_NOT_ENOUGH_RIGHTS | 7 | Недостаточно прав |
ERR_TOO_FREQUENT_REQUESTS | 8 | Слишком частые запросы |
ERR_MALFUNCTIONAL_TRADE | 9 | Недопустимая операция нарушающая функционирование сервера |
ERR_ACCOUNT_DISABLED | 64 | Счет заблокирован |
ERR_INVALID_ACCOUNT | 65 | Неправильный номер счета |
ERR_TRADE_TIMEOUT | 128 | Истек срок ожидания совершения сделки |
ERR_INVALID_PRICE | 129 | Неправильная цена |
ERR_INVALID_STOPS | 130 | Неправильные стопы |
ERR_INVALID_TRADE_VOLUME | 131 | Неправильный объем |
ERR_MARKET_CLOSED | 132 | Рынок закрыт |
ERR_TRADE_DISABLED | 133 | Торговля запрещена |
ERR_NOT_ENOUGH_MONEY | 134 | Недостаточно денег для совершения операции |
ERR_PRICE_CHANGED | 135 | Цена изменилась |
ERR_OFF_QUOTES | 136 | Нет цен |
ERR_BROKER_BUSY | 137 | Брокер занят |
ERR_REQUOTE | 138 | Новые цены |
ERR_ORDER_LOCKED | 139 | Ордер заблокирован и уже обрабатывается |
ERR_LONG_POSITIONS_ONLY_ALLOWED | 140 | Разрешена только покупка |
ERR_TOO_MANY_REQUESTS | 141 | Слишком много запросов |
ERR_TRADE_MODIFY_DENIED | 145 | Модификация запрещена, так как ордер слишком близок к рынку |
ERR_TRADE_CONTEXT_BUSY | 146 | Подсистема торговли занята |
ERR_TRADE_EXPIRATION_DENIED | 147 | Использование даты истечения ордера запрещено брокером |
ERR_TRADE_TOO_MANY_ORDERS | 148 | Количество открытых и отложенных ордеров достигло предела, установленного брокером. |
Константа | Значение | Описание |
---|---|---|
ERR_NO_MQLERROR | 4000 | Нет ошибки |
ERR_WRONG_FUNCTION_POINTER | 4001 | Неправильный указатель функции |
ERR_ARRAY_INDEX_OUT_OF_RANGE | 4002 | Индекс массива — вне диапазона |
ERR_NO_MEMORY_FOR_FUNCTION_CALL_STACK | 4003 | Нет памяти для стека функций |
ERR_RECURSIVE_STACK_OVERFLOW | 4004 | Переполнение стека после рекурсивного вызова |
ERR_NOT_ENOUGH_STACK_FOR_PARAMETER | 4005 | На стеке нет памяти для передачи параметров |
ERR_NO_MEMORY_FOR_PARAMETER_STRING | 4006 | Нет памяти для строкового параметра |
ERR_NO_MEMORY_FOR_TEMP_STRING | 4007 | Нет памяти для временной строки |
ERR_NOT_INITIALIZED_STRING | 4008 | Неинициализированная строка |
ERR_NOT_INITIALIZED_ARRAYSTRING | 4009 | Неинициализированная строка в массиве |
ERR_NO_MEMORY_FOR_ARRAYSTRING | 4010 | Нет памяти для строкового массива |
ERR_TOO_LONG_STRING | 4011 | Слишком длинная строка |
ERR_REMAINDER_FROM_ZERO_DIVIDE | 4012 | Остаток от деления на ноль |
ERR_ZERO_DIVIDE | 4013 | Деление на ноль |
ERR_UNKNOWN_COMMAND | 4014 | Неизвестная команда |
ERR_WRONG_JUMP | 4015 | Неправильный переход |
ERR_NOT_INITIALIZED_ARRAY | 4016 | Неинициализированный массив |
ERR_DLL_CALLS_NOT_ALLOWED | 4017 | Вызовы DLL не разрешены |
ERR_CANNOT_LOAD_LIBRARY | 4018 | Невозможно загрузить библиотеку |
ERR_CANNOT_CALL_FUNCTION | 4019 | Невозможно вызвать функцию |
ERR_EXTERNAL_EXPERT_CALLS_NOT_ALLOWED | 4020 | Вызовы внешних библиотечных функций не разрешены |
ERR_NOT_ENOUGH_MEMORY_FOR_RETURNED_STRING | 4021 | Недостаточно памяти для строки, возвращаемой из функции |
ERR_SYSTEM_BUSY | 4022 | Система занята |
ERR_INVALID_FUNCTION_PARAMETERS_COUNT | 4050 | Неправильное количество параметров функции |
ERR_INVALID_FUNCTION_PARAMETER_VALUE | 4051 | Недопустимое значение параметра функции |
ERR_STRING_FUNCTION_INTERNAL_ERROR | 4052 | Внутренняя ошибка строковой функции |
ERR_SOME_ARRAY_ERROR | 4053 | Ошибка массива |
ERR_INCORRECT_SERIES_ARRAY_USING | 4054 | Неправильное использование массива-таймсерии |
ERR_CUSTOM_INDICATOR_ERROR | 4055 | Ошибка пользовательского индикатора |
ERR_INCOMPATIBLE_ARRAYS | 4056 | Массивы несовместимы |
ERR_GLOBAL_VARIABLES_PROCESSING_ERROR | 4057 | Ошибка обработки глобальныех переменных |
ERR_GLOBAL_VARIABLE_NOT_FOUND | 4058 | Глобальная переменная не обнаружена |
ERR_FUNCTION_NOT_ALLOWED_IN_TESTING_MODE | 4059 | Функция не разрешена в тестовом режиме |
ERR_FUNCTION_NOT_CONFIRMED | 4060 | Функция не подтверждена |
ERR_SEND_MAIL_ERROR | 4061 | Ошибка отправки почты |
ERR_STRING_PARAMETER_EXPECTED | 4062 | Ожидается параметр типа string |
ERR_INTEGER_PARAMETER_EXPECTED | 4063 | Ожидается параметр типа integer |
ERR_DOUBLE_PARAMETER_EXPECTED | 4064 | Ожидается параметр типа double |
ERR_ARRAY_AS_PARAMETER_EXPECTED | 4065 | В качестве параметра ожидается массив |
ERR_HISTORY_WILL_UPDATED | 4066 | Запрошенные исторические данные в состоянии обновления |
ERR_TRADE_ERROR | 4067 | Ошибка при выполнении торговой операции |
ERR_END_OF_FILE | 4099 | Конец файла |
ERR_SOME_FILE_ERROR | 4100 | Ошибка при работе с файлом |
ERR_WRONG_FILE_NAME | 4101 | Неправильное имя файла |
ERR_TOO_MANY_OPENED_FILES | 4102 | Слишком много открытых файлов |
ERR_CANNOT_OPEN_FILE | 4103 | Невозможно открыть файл |
ERR_INCOMPATIBLE_ACCESS_TO_FILE | 4104 | Несовместимый режим доступа к файлу |
ERR_NO_ORDER_SELECTED | 4105 | Ни один ордер не выбран |
ERR_UNKNOWN_SYMBOL | 4106 | Неизвестный символ |
ERR_INVALID_PRICE_PARAM | 4107 | Неправильный параметр цены для торговой функции |
ERR_INVALID_TICKET | 4108 | Неверный номер тикета |
ERR_TRADE_NOT_ALLOWED | 4109 | Торговля не разрешена |
ERR_LONGS_NOT_ALLOWED | 4110 | Длинные позиции не разрешены |
ERR_SHORTS_NOT_ALLOWED | 4111 | Короткие позиции не разрешены |
ERR_OBJECT_ALREADY_EXISTS | 4200 | Объект уже существует |
ERR_UNKNOWN_OBJECT_PROPERTY | 4201 | Запрошено неизвестное свойство объекта |
ERR_OBJECT_DOES_NOT_EXIST | 4202 | Объект не существует |
ERR_UNKNOWN_OBJECT_TYPE | 4203 | Неизвестный тип объекта |
ERR_NO_OBJECT_NAME | 4204 | Нет имени объекта |
ERR_OBJECT_COORDINATES_ERROR | 4205 | Ошибка координат объекта |
ERR_NO_SPECIFIED_SUBWINDOW | 4206 | Не найдено указанное подокно |
ERR_SOME_OBJECT_ERROR | 4207 | Ошибка при работе с объектом |
I’m trying to modify an order, but I keep Error modifying order!, error#130. I’m using an ECN broker, so I need to modify the order to set a stoploss/takeprofit.
What I am doing wrong?
int digits = MarketInfo( Symbol(), MODE_DIGITS );
if ( digits == 2 || digits == 3 ) pipdigits = 0.01;
else if ( digits == 4 || digits == 5 ) pipdigits = 0.0001;
selltakeprofit = Ask + ( takeprofit * pipdigits );
sellstoploss = Ask - ( stoploss * pipdigits );
ticket = OrderSend( Symbol(), OP_SELL, lotsize, Ask, 100, 0, 0, 0, 0, 0, CLR_NONE );
if ( ticket < 0 )
{
Print( "venda Order send failed with error #", GetLastError() );
Print( "stop loss = ", sellstoploss );
}
else
{
Print( "Order send sucesso!!" );
Print( "Balance = ", AccountBalance() );
Print( "Equity = ", AccountEquity() );
bool res = OrderModify( ticket, 0, sellstoploss, selltakeprofit, 0 );
if ( res == false )
{
Print( "Error modifying order!, error#", GetLastError() );
Print( "sellstoploss ", sellstoploss );
Print( "selltakeprofit ", selltakeprofit );
Print( "StopLevel ", StopLevel );
Print( "Ask ", Ask );
}
else
{
Print( "Order modified successfully" );
}
}
asked Dec 2, 2014 at 2:33
Filipe FerminianoFilipe Ferminiano
8,25225 gold badges101 silver badges172 bronze badges
Error #130 is ERR_INVALID_STOPS
.
The most likely problem is that
a) the stoploss level you are inputting is too close to the order open price. This is dictated by
MarketInfo( Symbol(), MODE_STOPLEVEL ) // returns a min allowed distance [pts]
else
b) because you have not normalized the stoploss level with NormalizeDouble()
.
See below for a buy order example. In your example, i.e. for a sell order, note that you should be opening the order at the Bid price, not Ask as you have. Note also that the stoploss and takeprofit are usually calculated relative to the bid price, as the bid is what is displayed on your charts, unfortunately you just have to take the spread loss in stride.
Only other minor problem is that you input no colour for the last parameter in OrderModify()
. Unlike in OrderSend()
, these are not initialized by default in the function definition, so you should pass them really.
//--- get minimum stop level
double minstoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL );
Print( "Minimum Stop Level=", minstoplevel, " points" );
double price = Ask;
//--- calculated SL and TP prices must be normalized
double stoploss = NormalizeDouble( Bid - minstoplevel * Point, Digits );
double takeprofit = NormalizeDouble( Bid + minstoplevel * Point, Digits );
//--- place market order to buy 1 lot
int ticket = OrderSend( Symbol(), OP_BUY, 1, price, 3, stoploss, takeprofit, "My order", 16384, 0, clrGreen );
answered Dec 3, 2014 at 8:43
whitebloodcellwhitebloodcell
2981 gold badge4 silver badges10 bronze badges
1
OrderModify()
call may collide with not one, but two constraints
The first, being a trivial one — one cannot put SL/TP closer than your Broker allows via a MODE_STOPLEVEL
defined distance.
The second, being a less visible one — one cannot change { SL | TP } in case a Broker defined freezing distance is visited by a respective XTO price ( an eXecute-Trade-Operation price, being { Ask
for Short.SL & Short.TP | Bid
for Long.TP & Long.SL } )
MarketInfo( Symbol(), MODE_STOPLEVEL ) // returns a min allowed distance [pts]
MarketInfo( Symbol(), MODE_FREEZELEVEL ) // returns a freezing distance [pts]
OrderSend()
may be constrained on some ECN/STP account types
Another quite common condition set on STP/ECN systems ( introduced by the Broker’s inhouse Risk Management policy ) is that one is not allowed to setup TP/SL right at the OrderSend()
, but has to leave these blank and upon a positive confirmation of the OrderSend()
, submit a separate OrderModify()
instruction for the given OrderTicketNumber to add ex-post the TP and/or SL price-level(s)
A NormalizeDouble()
-whenever-possible practice is not separately commented here, as MetaQuotes Inc. publishes this as a must-do.
A recommended practice
Carefully review your Broker’s Terms & Conditions and consult with your Account Manager the complete mix of Broker-side policies that apply to your type of Trading Account.
answered Dec 13, 2014 at 18:55
When you execute a buy trade, your price is the Ask
, your stoploss and takeprofit are reference to the opposite trade, as when closing you’re subject to the Bid
price.
using this simple rule, when you buy your stoploss
and takeprofit
will be:
double stoploss = NormalizeDouble( Bid - minstoplevel * Point, Digits );
double takeprofit = NormalizeDouble( Bid + minstoplevel * Point, Digits );
int ticket = OrderSend( Symbol(),
OP_BUY,
lots,
price,
slippage,
stoploss,
takeprofit
);
the opposite, when you sell:
double stoploss = NormalizeDouble( Ask + minstoplevel * Point, Digits );
double takeprofit = NormalizeDouble( Ask - minstoplevel * Point, Digits );
int ticket = OrderSend( Symbol(),
OP_SELL,
lots,
price,
slippage,
stoploss,
takeprofit
);
answered Nov 25, 2016 at 11:58
RamzyRamzy
1512 silver badges14 bronze badges
Hello some ECN Brokers doesn’t allow send orders with SL and TP, So first send the Order without SL and TP , then Modify it and asign it SL and TP.
answered Jul 23, 2018 at 12:15
SimoSimo
112 bronze badges
Actually the real issue is that your new stop loss price although for buy side is bigger than current stop loss, you still have to check if your new stop loss is actually smaller than current Bid price. If not you will get that Order Modify 130 error. I hope I make sense. And the opposite applies for the Sell side.
answered Jun 29, 2020 at 3:57
У меня есть код модификации ордера для моих заказов на открытом рынке, который Error 130
в MT4
Журнал, я знаю, что это давняя проблема, и есть несколько источников, на которые я смотрел, как здесь, так и по всей сети — однако, похоже, ничего не работает.
1) у меня есть NormalizeDouble()
вылечить все, что имеет двойные функции на MQL4
т.е. цены и т. д. — это для того, чтобы количество цифр после запятой соответствовало паре ее торговли; некоторые из них 3 цифры, другие 5 цифр.
2) pnlPoints
& stopPoints
рассчитываются с использованием _Period
таким образом, количество точек остается неизменным независимо от количества цифр после десятичной точки графика, на котором установлен советник
3) Я знаю о наличии MarketInfo( Symbol(), MODE_STOPLEVEL )
& hasd добавил это к MarketInfo( Symbol(), MODE_SPREAD )
некоторым stoplevel
расчет.
4) Я хочу 100 баллов «В деньгах», прежде чем заказ будет изменен на безубыток.
5) Я использую пятизначный брокер, но, как вы знаете, некоторые пары, такие как EURJPY
будет иметь три цифры. Это исправлено _Period
& NormalizeDouble()
Funtions.
/*Breakeven Order Modification*/
for(int b = OrdersTotal()-1;b>=0;b--)
{
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES)==true)
{
double aBidPrice = MarketInfo(Symbol(),MODE_BID);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = NormalizeDouble(aBidPrice - anOpenPrice/_Point,Digits);
double stopPoints = NormalizeDouble(aBidPrice - aNewSLPrice/_Point,Digits);
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo(Symbol(),MODE_SPREAD));
int aTicket = OrderTicket();
if(OrderType() == OP_BUY)
if(stopPoints > stopLevel)
if(aTicket > 0)
if(pnlPoints > breakeven)
if(aNewSLPrice == aCurrentSL)continue;
{
BuyMod = OrderModify(OrderTicket(),NormalizeDouble(anOpenPrice,Digits),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
if(BuyMod = false || aTicket == 0)
{
Print("Order modification for ticket #"+IntegerToString(aTicket,10)+"Error code",GetLastError());
}
}
}
}
for(int s = OrdersTotal()-1; s>=0; s--)
{
if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES)==true)
{
double anAskPrice = MarketInfo(Symbol(),MODE_ASK);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = NormalizeDouble(anOpenPrice - anAskPrice/_Point,Digits);
double stopPoints = NormalizeDouble(aNewSLPrice - anAskPrice/_Point,Digits);
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo(Symbol(),MODE_SPREAD));
int aTicket = OrderTicket();
if(OrderType()== OP_SELL)
if(stopPoints > stopLevel)
if(aTicket > 0)
if(pnlPoints > breakeven)
if(aNewSLPrice == aCurrentSL)continue;
{
SellMod = OrderModify(OrderTicket(),NormalizeDouble(anOpenPrice,Digits),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
if(SellMod = false || aTicket == 0)
{
Print("Order modification for ticket #"+IntegerToString(aTicket,10)+"Error code",GetLastError());
}
}
}
}
Большое спасибо и привет.
Содержание
- Коды ошибок
- A) Полностью соответствуют MQL4 OrderSend() требованиям синтаксиса
- B) Ошибка 130: == «недействительная остановка»
- C) Хорошая практика не назначать в extern итераторных-переменных
MQL для чайников, программирование на MQL4, MQL5
Что значит 2010.02.01 17:00 MyExpert GBPUSD,M15: OrderModify error 130
почему обычно эта ошибка возникает?
Очень много подобных вопросов мне приходит. Поэтому публикую таблицу кодов ошибок. Например посмотрев вышеописанную ошибку error 130 становится понятно, что функция OrderModify пытается изменить стоп-лосс или тейк-профит слишком близко к текущей цене.
Коды ошибок
GetLastError() — функция, возвращающая коды ошибок. Кодовые константы ошибок определены в файле stderror.mqh. Для вывода текстовых сообщений следует использовать функцию ErrorDescription(), определенную в файле stdlib.mqh.
Коды ошибок, возвращаемые торговым сервером или клиентским терминалом:
Значение | Описание |
---|---|
Нет ошибки | |
1 | Нет ошибки, но результат неизвестен |
2 | Общая ошибка |
3 | Неправильные параметры |
4 | Торговый сервер занят |
5 | Старая версия клиентского терминала |
6 | Нет связи с торговым сервером |
7 | Недостаточно прав |
8 | Слишком частые запросы |
9 | Недопустимая операция нарушающая функционирование сервера |
64 | Счет заблокирован |
65 | Неправильный номер счета |
128 | Истек срок ожидания совершения сделки |
129 | Неправильная цена |
130 | Неправильные стопы |
131 | Неправильный объем |
132 | Рынок закрыт |
133 | Торговля запрещена |
134 | Недостаточно денег для совершения операции |
135 | Цена изменилась |
136 | Нет цен |
137 | Брокер занят |
138 | Новые цены |
139 | Ордер заблокирован и уже обрабатывается |
140 | Разрешена только покупка |
141 | Слишком много запросов |
145 | Модификация запрещена, так как ордер слишком близок к рынку |
146 | Подсистема торговли занята |
147 | Использование даты истечения ордера запрещено брокером |
148 | Количество открытых и отложенных ордеров достигло предела, установленного брокером. |
Коды ошибок выполнения MQL4 программы:
GetLastError() — функция, возвращающая коды ошибок. Кодовые константы ошибок определены в файле stderror.mqh. Для вывода текстовых сообщений следует использовать функцию ErrorDescription(), определенную в файле stdlib.mqh.
Коды ошибок, возвращаемые торговым сервером или клиентским терминалом:
Я пытаюсь вставить takeprofit и stoploss аргумент в моей SendOrder() функции, но я получаю следующее сообщение об ошибке:
Я уже проверил документацию для функции NormalizeDouble() , но я все еще получаю ошибку.
A) Полностью соответствуют MQL4 OrderSend() требованиям синтаксиса
Ваш код не на установление правильной SHORT торговли входной цены, как это следует читать , а Bid не Ask (эта ошибка скрыта , как это эффективно замаскированных на довольно космическом расстоянии 100 точек на допустимом расстоянии проскальзывания от указанной цены) ,
Ваш код не при назначении int ( 0 ) в месте, где , string как ожидается.
Вы должны проверить с вашим брокером несколько деталей:
- Допускает ли их условия и условия в OrderSend() одной стоп-инструкции, в т.ч., TP и SL, или же брокер T & C требуют , чтобы сначала открыть торгово-позицию и только после того, как это происходит , чтобы позволить OrderModify() инструкции к прайс-уровней настройки TP и SL?
- В любом случае, проверьте настройки Брокер T & C для STOPLEVEL & FREEZELEVEL расстояний, в пределах которого Брокер отвергает любые TP и SL установки (ы) или модификации (части).
C) Хорошая практика не назначать в extern итераторных-переменных
Хотя это не является корневой причиной вашей проблемы, не приживаются с передовой отраслевой практикой, один из которых не является присвоить любое значение заявленного extern . Вместо объявить собственную переменную, что вы контролируете объем & назначения их, но оставить extern (s) не-прикоснулся с вашей стороны кода.