Ошибки, баги, вопросы - страница 2452

 
Igor Zakharov:

Вы же сами привели цитату из мануала, где сказано, что последовательность не гарантируется. Потому и рисковано.

Я уже начал было переписывать код по совету Владимира, но споткнулся о случай, когда закрытие дольше тика - опять двойной подсчёт (узел фильтра в подсчёте уж очень тяжеловестный получился). Пока не придумал ничего лучше, чем остановка до полного закрытия, ради компромисса со скоростью оптимизации. 

Пятница же :) Может отдохнув что-то соображу.

В любом случае, спасибо за идеи - они не пропадут!

Я говорил о своей собственной последовательности.

По моим наблюдениям получается что после OnTick, когда происходит транзакция выполнение кода не дожидаясь следующего тика передаётся функции OnTradeTransaction. Следовательно нет никакой разницы обрабатывать факт закрытия собственными функциями или в OnTradeTransaction. Но мне больше нравится работать с OnTradeTransaction. Главное правильно организовать последовательность действий без зависимости от последовательности транзакций поступающих с сервера. И немаловажно правильно понимать эту последовательность. Опять-же по моим наблюдениям последовательность может быть нарушена в типе транзакции. То-есть может быть сначала TRADE_TRANSACTION_DEAL_ADD а потом TRADE_TRANSACTION_HISTORY_ADD, а по логике вроде-бы должно быть сначала добавление ордера в историю и следом за этим сделка.

ps; Потом, как я уже сказал, отсеяв транзакцию TRADE_TRANSACTION_DEAL_ADD можно отсеять по открытию позиции и по закрытию позиции. Ведь мы говорим о советнике для рынка форекс и счёте hadge так ведь? Соответственно нет никакой необходимости при каждом чихе пересчитывать все позиции. Достаточно добавить одну, если было открытие, или одну удалить из посчитанных, если было закрытие.
 
Alexey Viktorov:

рынка форекс и счёте hadge так ведь?

Сетка же :) Да.

Текущая логика такая: есть структура в которой хранится вся информация по каждой сетке: символ-количество позиций-суммарный лот-профит и ещё несколько неважных для этой беседы вещей... По таймеру пересчитывается профит, если есть ордера (мультисимвольный робот). А вот лоты и количество пересчитывалось в OnTradeTransaction (на случай, если пользователь "помог").

Я хотел проверить случай, когда одна сетка, например, в плюсе на 100$, а другая в минусе на 50 - закрыть обе с профитом 50, чтоб не дать ей расти.

На данный момент сделано так:

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,     // trade transaction structure 
   const MqlTradeRequest&        reqst,     // request structure 
   const MqlTradeResult&         reslt      // response structure 
    )
{
 int index=-1;
 for(index=0;index<symbols_total;index++)
  if(ARRAY[index].symbol==trans.symbol) break; //нашли индекс символа по которому прошла трансакция в массиве структур
 
 if(index>=0) CountOrders(index); //пересчитали элемент
}

Пока добавил CountOrders() после закрытия пары сеток. Для тестера - работает. Для реала сделаю по схеме Владимира (с массивом закрываемых тикетов)

Кстати, парное закрытие не оправдало себя - просадку не сильно уменьшает, а профит режет прилично.

[Удален]  
Vladimir Karputov:

Я бы отказался от ВСЕХ while, Sleep and OnTimer для задачи закрытия позиций. Я бы делал так: выстрелил приказы на закрытие - вышел из OnTick, на следуующем тике проверка: если позиции с нужными тикетами ещё живы - снова выстрелить приказы на закрытие и так по кругу через взход/выход в onTick.

Логика такая: закрытие позиции - первоочередая задача, поэтому цикл закрытия в самом начале OnTick. А формирование массива тикетов закрытия может быть в любом месте OnTick - хоть в самом конце.

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

 
Alexey Kozitsyn:

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

Для такого случая есть:

10036

TRADE_RETCODE_POSITION_CLOSED

Position with the specified POSITION_IDENTIFIER has already been closed

Закрывающая позиция отправляется с тикетом закрываемой, поэтому описанное вами вряд ли произойдёт.

[Удален]  
Sergey Dzyublik:

Так и не понял, где это написано, но не суть важно...
Спасибо за холивар.

Подперли костылем и побежал дальше:

Ну вообще странно массивы копируется, но кому-то даже нравится ...

Я себе сделал более менее адекватную обвёртку над массивом и бед не знаю.

https://www.mql5.com/ru/forum/221917/page26#comment_11233214

 
A100:

Это не я придумал, а Разработчики

Не припомню, чтобы они когда-либо говорили такое.

Оператор присваивания предназначен для создания идентичной копии объекта.  В этом его смысл.  Когда ты что-то приравниваешь чему-то, то очевидно в левой части должна получиться полная копия, а не чёрти что.  Поэтому здесь явный баг.

 
Alexey Navoykov:

Оператор присваивания предназначен для создания идентичной копии объекта.  В этом его смысл.  Когда ты что-то приравниваешь чему-то, то очевидно в левой части должна получиться полная копия, а не чёрти что.  Поэтому здесь явный баг.

Дело в том, что для массива - оператор присваивания не определен:

void OnStart()
{
        uchar a[], b[];
        a = b; ////Error: invalid array access
}

Его просто нет... соответственно все рассуждения для чего он предназначен, правильно работает или нет - лишены смысла

 
A100:

Дело в том, что для массива - оператор присваивания не определен:

Его просто нет... соответственно все рассуждения для чего он предназначен, правильно работает или нет - лишены смысла

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

Но оператор присваивания для массивов конечно тоже нужен.

 
Очень много жалоб о том что маркет не принимает для оплаты карты.
 
какая то проблема с Мастеркард