Надёжные реализации экспертов - страница 5

 
Scriptong:
А если максимально возможное количество заранее неизвестно и указывается пользователем в настроечном параметре? 

Ну так и пользователь то не всегда может знать сколько будет ордеров, логично? Я полагаю, что этак штук 100 - 150 это уже потолок. Больше не резон устанавливать размер массива... По крайне мере, я б не оперировал и таким количеством одним экспертом. Это уж слишком. А потому, можно смело ставит размерность 100.

Но если мы не знаем, тогда размер будет динамический т.е. меняться в процессе работы совка, так?А сдвигаться ячейки массива будут же не сами. Это - дополнительная затрата ресурсов. Типа как буфер индикатора сдвигать нужно ячейки, в случает, когда меняется количество элементов рабочего массива структур ордеров, так?

 

Сделать с запасом на 1000, и перед каждым использованием проверять, не превышает ли OrdersTotal() размер массива, если превышает, увеличить с запасом на 1000.

 

Я извиняюсь за длительное отсутствие, была авария на базовой станции мегавонь...

Scriptong:

1. Заметьте - сказано, что с историей счета лучше не связываться )) Мы же говорим о списке рабочих ордеров. 


Во первых проверять OrderCloseTime() > 0 ...

AlexeyVik:

А в общем-то всё это на любителя и согласно знаниям и накопленному опыту.


Во вторых...

shanty:


Таким образом будет вестись контроль совераемых операций.

Но тут есть один недочёт. Если ордер закроется по ТП или по СТОПу, то это будет, так сказать, "автономное закрытие"


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


Мне приходилось писать советник по разруливанию локов, при тестировании открывалось до 5000 ордеров. И надо было закрывать не все, а несколько ордеров при условии что один из "главных" закрылся. Вот тогда я и решил что лучше использовать массив тикетов и соответственно OrderSelect() по тикету будет выгодней чем проверка открытых и проверка истории счёта на наличие новых закрытых ордеров. Да ещё учитывая что разруливание происходило не одну, иногда, неделю то надо иметь какую-то защиту от юзверя который может закрыть доступ дальше сегодняшнего дня.

 
Integer:

Сделать с запасом на 1000, и перед каждым использованием проверять, не превышает ли OrdersTotal() размер массива, если превышает, увеличить с запасом на 1000.

Так будет по экономичнее к ресурсам по ходу. Я про это и думал.

 
Scriptong:

Проще. Объявляется массив структур:

struct OrderInfo
{
   int            type;
   int            ticket;
   double         lots;
   double         openPrice;
   double         sl;
   double         tp;
   double         profit;
};

OrderInfo   orderArray[];

А Вам хватает такого небольшого количества членов структуры? Я как-то думал по этому поводу, хотя того ещё не примеил, т.к. не додумал всё. Так вот тогда ещё я написал такую структуру:

struct Position_Properties
{
   datetime    gdt_Expiration;      // Срок истечения отложенного ордера
   datetime    gdt_OpenTime;        // Время открытия выбранной позиции
   double      gd_OpenPrice;        // Цена открытия
   double      gd_Lots;             // Объём позиции на открытие
   double      gd_CurSL;            // Текущий Stop Loss выбранной позиции
   double      gd_NewSL;            // Новый Stop Loss выбранной позиции
   double      gd_CurTP;            // Текущий Take Profit выбранной позиции
   double      gd_NewTP;            // Новый Take Profit выбранной позиции
   int         gi_CurTicket;        // Тикет выбранного ордера
   int         gi_Type;             // Тип торговой операции
   int         gi_Slippage;         // Максимально допустимое отклонение цены для рыночных ордеров
   int         gi_Magic;            // Магический номер
   string      gs_Comment;          // Комментарий
   string      gs_Symbol;           // Наименование фин. инструмента, с которым производится операция
   ulong       gu_Duration;         // Длительность позиции в секундах
};

  В ней есть всё, что тока может понадобится. Не лучше ли сразу делать так?

 
Scriptong:

1. Заметьте - сказано, что с историей счета лучше не связываться )) Мы же говорим о списке рабочих ордеров. К тому же, какой смысл кроется в "проверить закрылся-ли ордер" относительно истории счета? Если ордер отсутствует в списке рабочих ордеров, то какие еще подтверждения нужны? Опять же, если не вести список ордеров самостоятельно, то такой вопрос попросту не возникнет. 

2. Смысл в том, чтобы за время обработки тика не проделывать работу по выявлению "своих" ордеров. Это делается один раз в начале обработки. Затем все операции производятся с массивом, который может содержать не просто собранную, а и обработанную информацию. К примеру, если в стратегии используется более одного ордера, то часто возникает вопрос об их нумерации. В итоге либо ордера массива располагаются в нужном порядке, либо для каждого ордера добавляется свойство "orderIndex". 

Всё то оно, в принципе, я понял. Тока вот как оперировать историей я не въехал. Получается, что сбор на каждом тике информации по каждому ордеру происходит. Если добавил некое свойство "orderIndex" в структуру ордера, то что нам это даст?

Ведь, мы как я понял, собираем инфу из списка рабочих ордеров. С историей не связываемся, как выше Вы говорите. Получается, что на каком-то тике, например, удаляется какой-то ордер. В рабочих ордерах его уже нет, а значит список  рабочих ордеров уменьшится на 1, и лишь потому, что мы с историей не работаем. Как быть?

Я то понимаю, что можно усложнить код и все ордера сверять на наличие, и, если какого-то нт, добавлять в другой массив - массив истории. Но это уже будет совсем параноидальный вариант. Разве не так? 

 
shanty:

 Я вот думаю по поводу того, что можно писать проще, но это, как я понимаю, не всегда будует надёжно отрабатываться в реале. Хочу обсудить данный момент. Так как написать могу всё что нужно, но не хочется избыточности кода. Потому прикидываю в плане оптимизации сразу. А думаю я о том, что торговые операции совершаются есс-но на новом баре, т.е. не то чтоб на новом, но не на каждом тике, а периодически, через N-ое количество секунд (минут). Но это касается лишь совершения сделок.

 А есть ещё и другие вещи. Например,операции удаления ордеров (если они не исполнились), траалы и тд, Их нужно, по ходу, отрабатывать на каждом тике? Я думаю, что иначе никак. Например, если ордер не удалится с первого раза, и ждать ещё какое-то время, не всегда будет толк, если торговать на не высоких ТФ. Получается, нужно это всё разруливать либо на каждом тике, либо использовать глобальные флаги типа ТРЕНД вверх или вниз. Если флаг активен, то проверяется или что-то делается, если не активен, то не делается.

Как кто выстраивает подобные конструкции? Хочу написать более гибкий код.. 

Поделюсь своим опытом. Может, пригодится.

Запросы к серверу выполнить торговую операцию (открыть или закрыть сделку, выставить отложенный ордер, модифицировать или удалить имеющийся ордер) отправляются, конечно, не на каждом тике, а когда надо. Результат исполнения этих запросов в MQL4 (в отличие от MQL5, где запросы могут быть асинхронными) становится известен в советнике на том же тике, на котором запрос был отправлен. Иногда, правда, история счета сразу после передачи управления на следующую строку еще не изменилась (в терминал еще не пришли изменения от сервера), надо подождать миллисекунд 100 для гарантии и тут же проверить. Это для надежности. Сам натыкался на то, что ордер удален успешно, а в истории он еще есть.

Исполнилась операция или не исполнилась, чаще чем раз в 2 секунды сервер запросами не беспокою, а то компания будет недовольна.

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

Заметил тут неточность в рассуждениях. Статических массивов в MQL* нет вообще. Только динамические.

И один никем не отвеченный вопрос. Что лучше, трехмерный массив или массив структур. Лучше то, что адекватно задаче, но, если можно реализовать и так и эдак, то можно учесть быстродействие. Для вычисления адреса нужного элемента типа "структура" в одномерном массиве требуется одно умножение номера элемента на его размер  (или сдвиг, если размер структуры степень 2) плюс одно сложение, смещающее адрес нулевого элемента до нужного. Для трехмерного массива соответственно три умножения или сдвига плюс три сложения.

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