Нужна помощь с ошибкой #130 недействительный стоплосс - страница 2

 

Лучший способ правильно установить стоплосс - это правильно продумать спред. Спред - это расстояние между Ask и Bid. Поэтому, когда вы добавляете стоплосс к ордеру на покупку, используя Bid - SL, он автоматически включает спред, и вам не нужно кодировать его, вы можете полностью игнорировать спред. Для сделки на продажу использование Ask + SL дает тот же эффект. Однако, будьте осторожны - в периоды низкого объема торгов спред становится больше, и вы можете оказаться с SL далеко от того места, где вы ожидаете его увидеть - поэтому вы можете добавить некоторый код для предотвращения добавления SL выше установленного размера спреда.

Теперь вопрос о спреде снят, следующая основная причина ошибки 130s заключается в том, что цены изменились, пока ваш советник еще выполнялся. Это может быть вызвано тем, что советнику требуется много времени для исполнения или сервер очень занят обслуживанием сделок, что задерживает исполнение советника. В результате один тик заставил советника начать выполнение, но другой тик наступил до завершения выполнения, и цены теперь недействительны.

В любом случае вам нужно обновлять цены с помощью RefreshRates: while (RefrshRates() == 1) Sleep(5); ------ или любое другое время ожидания.

 
BigAl:


В любом случае вам нужно обновить цены, используя RefreshRates: while (RefrshRates() == 1) Sleep(5); ------ или любое другое время ожидания.

Это верно только в том случае, если в коде используются предопределенные переменные https://docs.mql4.com/predefined/variables, если в коде используется MarketInfo для Bid и Ask, то RefreshRates не будет иметь никакого значения....
 
qjol:
AFAIK RefreshRates() не имеет никакого отношения к ошибке 130

RaptorUK, и я согласен, что использование MODE_ASK и т.д. устранит необходимость в RefreshRates(), но я предполагал, что как в примере кода shinobi .....

Я отправляю заказ, например:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

используется предопределенная переменная ASK и поэтому ask/bid, а также значение спреда могло измениться, что и привело к ошибке 130. В таком случае RefreshRates() можно было бы использовать непосредственно перед отправкой ордера.

 
BigAl:

RaptorUK, и я согласен, что использование MODE_ASK и т.д. устранит необходимость в RefreshRates(), но я предполагал, что как в примере кода шиноби .....

Я отправляю заказ, например:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

используется предопределенная переменная ASK и поэтому ask/bid, а также значение спреда могло измениться, что и привело к ошибке 130. В таком случае RefreshRates() можно было бы использовать непосредственно перед отправкой ордера.

Спасибо всем за ваши замечательные советы!
Сейчас я немного занят, но как только у меня появится возможность, я попробую все ваши предложения, а затем напишу обобщающее сообщение для всех, кто может наткнуться на эту тему с такой же проблемой.

Спасибо, и берегите себя!

shinobi
 
BigAl: Я посылаю ордер, например:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

не говорит всего. Как вы вычисляете initial_stop - используя Bid?

Как вы вычисляете SLIPPAGE - с поправкой на 4/5-значных брокеров?

 
Привет, ребята!

Мне пришлось сделать перерыв на некоторое время (переезд в новый город, новая работа).
Но теперь я хотел бы взяться за эту тему, и наконец найти решение для этой проклятой ошибки #130 stoploss.

Я благодарен за все ваши советы и постарался учесть все из них:

1: Спред.
Чтобы устранить спред как возможную причину ошибки, я установил стоплосс как
Bid-stoploss (Long)
Ask+stoploss (Short)

2: Changing Market Rates
Чтобы устранить возможную причину изменения рыночных курсов до отправки ордера,
Я изменил свой код и заменил все вхождения Ask и Bid на
MarketInfo(Symbol(), MODE_ASK) и MarketInfo(Symbol(), MODE_BID)

3: 4-5 Digits-Broker
Чтобы устранить возможную причину неправильного количества цифр, я округлил стоплосс в соответствии с кодом WHRoeders:
int     pips2points;    // slippage  3 pips    3=points    30=points
double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)

//init digit adjustment
if (Digits % 2 == 1) {      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
} else {
    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; 
}

OrderSend(Symbol(), OP_BUY, position_size, MarketInfo(Symbol(), MODE_ASK), SLIPPAGE, (MarketInfo(Symbol(), MODE_BID) - stoploss) * pips2dbl, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);
Как упоминалось ранее, переменные SLIPPAGE и TAKEPROFIT в моем случае всегда равны 0. Поэтому они также не должны вызывать проблем.


Итак, я выполнил все рекомендации, но ошибка все еще сохраняется. Насколько я могу судить, она возникает так же часто, как и раньше, поэтому должна быть другая причина.
Вот недавний лог:

tickvalue: 12.50000000
pos size: 37.00000000
Ask/Bid 1262.00000000/1261.75000000
stoploss:12.59610000
position_size: 37
Spread 0.25000000

Error could not take long position. Error is: #130 invalid stops

Приведенная выше строка кода OrderSend была использована с записанными значениями, чтобы попытаться занять длинную позицию.
Есть ли у вас еще какие-нибудь идеи, что может быть причиной?

Спасибо!
shinobi
 

Является ли это ECN брокером?

WHRoeder 2011.09.15 20:36

У ECN брокеров вы должны открыть и ПОТОМ установить стопы.

 
shinobi:
чтобы устранить возможную причину неправильного количества цифр, я округлил стоплосс в соответствии с кодом WHRoeders:
  1. В коде, который я разместил, не было округления.
  2. На ECN брокерах вы должны открыть и ПОТОМ установить стопы.
  3. На металлах (где TICKSIZE != Point) цена открытия для отложенных ордеров должна быть округлена
    double TS=MarketInfo(pair, MODE_TICKSIZE);
    OOP = MathRound(OOP/TS)*TS;
    Я не знаю о стопах.

  4. Хватит рассказывать нам о значениях и о том, что, по вашему мнению, вы сделали. Опублику йте код.
 

Просто сделайте

extern double StopLoss = 50;

extern double TakeProfit = 50;

затем для покупок:

double SL=Bid - StopLoss *Point;

double TP=Bid + TakeProfit*Point;

int Ticket=OrderSend(Symbol(),0,1,Ask,2,SL,TP,"",12345);

if( Ticket<0) print("error="GetLastError()");

для продаж:

double SL=Ask + StopLoss*Point;

double TP=Ask - TakeProfit*Point;

int Ticket=OrderSend(Symbol(),1,1,Bid,2,SL,TP,"",12345);

if( Ticket<0) print("error="GetLastError()");

затем опубликуйте файл журнала, если он не работает.

 
Спасибо Raptor, WHRoeder и SDC за ваши ответы.

SDC:
Я попробовал ваш код следующим образом:
   int result_ticket = -1;
   double stoploss            = 50;
   double takeprofit          = 50;
   double SL = 0.0;
   double TP = 0.0;
   if(long) {   //take long position
      SL = MarketInfo(Symbol(), MODE_BID) - stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_BID) + takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 0, 1, MarketInfo(Symbol(), MODE_ASK), 2, SL, TP, "", 12345);
   } else {     //take short position
      SL = MarketInfo(Symbol(), MODE_ASK) + stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_ASK) - takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 1, 1, MarketInfo(Symbol(), MODE_BID), 2, SL, TP, "", 12345);
   }

   //check for errors
   if(result_ticket == -1) {
      Log("error="+GetLastError());
      return(-1);
   }
Единственное отличие в том, что я заменил Point, Ask и Bid на MarketInfo, чтобы избежать проблемы RefreshRates, о которой говорили Raptor и BigAI.
Проблема сохраняется и на этом простом примере. Я все еще получаю

#ESZ1,M5: Открытая позиция
#ESZ1,M5: tickvalue: 12.50000000
#ESZ1,M5: размер позиции: 1.00000000
#ESZ1,M5: Ask/Bid 1244.50000000/1244.25000000
#ESZ1,M5: спред 0.25000000
#ESZ1,M5: SL: 1244.00000000
#ESZ1,M5: TP: 1245.00000000
#ESZ1,M5: error=130

Раптор:
В настоящее время я использую UWC-Trader с демо-счетом для тестирования.
Как упоминалось ранее, я торгую фьючерсами. Например, ESZ1 и FDXZ1.

WHRoeder:
Извините, я тоже не округляю. Замените "округлять" на "корректировать для 4/5-значных брокеров". Т.е. я просто применил ваш код.
Я также разместил OrderSend так, как я его использую в моем предыдущем ответе. И значения всех задействованных переменных. Я не уверен, какая другая часть кода была бы интересна.
Как показал мини-пример, предложенный SDC, ошибка может быть разложена до этого простого кода. Значит, она должна быть более фундаментальной.

Я не торгую металлами, поэтому округление не должно быть важным.

Я попробую следующее:
открытие (без стоплосса) и последующая модификация (установка стоплосса).

Еще раз спасибо за ваши мысли,

шиноби
Причина обращения: