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

 
AlexeyVik:

Уверенность именно в обратном, потому и проверяется на OrderCloseTime() > 0

Размер массива должен быть динамический.

Я тока одного не понимаю. Как мы будем знать, что тот или иной тикет нужно удалить, а какой-то нет?

Если в обычном режиме я делал проще, типа:

void OnTick()
{
   OTotal = CPosInf.FindPositions (AmountPosByType);   // Получаем количество позиций( по типам )
   
   if (LastBarTime != Time[0])
   {
      ZZ.MakeNoneEmptyArray (_Symbol, 0);              // Отбираем "непустые" значения Zig-Zag'а
      
      int signal = GetTradingSignal();                 // Получает торговый сигнал
      
      Trade (signal);                                  // Открываем позиция, при налчии сигнала
   }
}

// Внутри функции signal происходит проверка на входе:
Trade (int signal)
{
   if (signal = КУПИТЬ)
   {
      for (int OrdersTotal()-1; i>=0; i--)
      {
         // ТУТ ПРОВЕРЯЕМ ТИКЕТ, МЕЙДЖИК И ТД
         if (ИМЕЮТСЯ ОРДЕРА В ДРУГУЮ СТОРОНУ)
           PosMan.fOrderDelete (ticket);
         
         ОТКРЫВАЕМ ОРДЕРА В ТРУБУЕМОМ НАПРАВЛЕНИ
      }
   }
}

 Каким образом тикет прикрутить к типу сигнала... Чё та я не совсем понимаю.

 
Scriptong:

История счета в МТ4 это вообще отдельный вопрос )) Она, к сожалению, устроена так, что зависит от действий пользователя: он может "спрятать" всю историю, установив соответствующие даты. Поэтому с историей счета в МТ4 лучше не связываться, а вести свою бухгалтерию. Таким образом, здесь как раз лучше вести свой массив, как Вы и говорите. А еще лучше - построить логику эксперта так, чтобы история счета вообще не использовалась, потому что гарантировать круглосуточную работу эксперта никто не может. 

В чем же бесполезность локального массива? Возможно, я неоднозначно выразился. Массив объявлен как член класса и однократно (при инициализации программы) распределен на максимально разрешенное стратегией количество ордеров, что избавляет от "долгой" операции перераспределения памяти (ArrayResize) и гарантирует, что не будет ошибок при ее выделении. На каждом новом тике массив заполняется заново. Счетчик указывает количество заполненных элементов массива.

И да, конечно, при записи информации об ордерах это массив структур, что позволяет сохранять всю нужную информацию о каждом ордере. В Учебнике об этом не могли написать, т. к. тогда структур в MQL4 еще не было. 

1. Этим всё сказано. Может с историей лучше не связываться, но проверить закрылся-ли ордер никогда не мешает. Именно по этой причине я использую массив тикетов.

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

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

 
shanty:

Я тока одного не понимаю. Как мы будем знать, что тот или иной тикет нужно удалить, а какой-то нет?

Если в обычном режиме я делал проще, типа:

 Каким образом тикет прикрутить к типу сигнала... Чё та я не совсем понимаю.

Как-то так.
// Внутри функции signal происходит проверка на входе:
Trade (int signal)
{
   if (signal = КУПИТЬ)
   {
      for (int OrdersTotal()-1; i>=0; i--)               // Вместо OrdersTotal() цикл по массиву
      {
         // ТУТ ПРОВЕРЯЕМ ТИКЕТ, МЕЙДЖИК И ТД            // Тикет, магик и т.д. проверять уже не надо, они проверялись при заполнении массива
         if (ИМЕЮТСЯ ОРДЕРА В ДРУГУЮ СТОРОНУ)            // Без изменений
           PosMan.fOrderDelete (ticket);                 // Тоже без изменений
         
         ОТКРЫВАЕМ ОРДЕРА В ТРУБУЕМОМ НАПРАВЛЕНИ         // Открываем ордера и перезаполняем массив
      }
   }
}
 
AlexeyVik:

1. Этим всё сказано. Может с историей лучше не связываться, но проверить закрылся-ли ордер никогда не мешает. Именно по этой причине я использую массив тикетов.

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

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

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

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

 
Scriptong:

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

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

Хотя, опять-таки, бывают же случаи, когда история нужна. Например, когда имеется определённый алгоритм мани-менеджмента, зависящий от профитности закрытия позиции определённого индекса. Тогда как? Собирать свой массив истории? Записывать его в файл? Это типа есть самый адекватный вариант решения задачи работы с историей?

Если там заморочится, то собирается, на первый взгляд, много доп. кода.

 

Scriptong:

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

  С одной стороны да. В своём массиве, будут уже отсортированные и отобранные тикеты. Не придёцца каждый раз пробегать по ордерам и отбирать "свои" ордера.

Тока вот какой резон с нумерацией? Не проще ли по нужде отбирать из имеющихся тикетов нужные. Зачем ещё и нумеровать их? 

 
shanty:

А если вести список разве возникнет?

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

 А то что в истории нас уже не касается, в основном.

Вот и я о том же.

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

Хранить всю необходимую информацию в MagicNumber рабочих ордеров, используя это поле кумулятивно.

 Тока вот какой резон с нумерацией? Не проще ли по нужде отбирать из имеющихся тикетов нужные. Зачем ещё и нумеровать их? 

Выше Вы спрашивали, как работать при стратегии, основанной на результате закрытия предыдущих ордеров. Как раз для этого и нужна нумерация. Тогда стратегия не будет зависеть от наличия/отсутствия истории. Кроме того, при подключении эксперт по текущим ордерам сразу определяет свое состояние. К примеру, найден ордер №3 от серии №2. Его стоп такой-то. По этим данным определяем, сколько прибыли требуется получить от следующего ордера, чтобы покрыть убыток предыдущих ордеров (к примеру).
 
Scriptong:

История счета в МТ4 это вообще отдельный вопрос )) Она, к сожалению, устроена так, что зависит от действий пользователя: он может "спрятать" всю историю, установив соответствующие даты. Поэтому с историей счета в МТ4 лучше не связываться, а вести свою бухгалтерию. Таким образом, здесь как раз лучше вести свой массив, как Вы и говорите. А еще лучше - построить логику эксперта так, чтобы история счета вообще не использовалась, потому что гарантировать круглосуточную работу эксперта никто не может.  

И как же пользователь может "спрятать" историю? В настройках то не даты, а кол-во баров имеется. Разве что только так... Игорь, Вы об этом говорите.  Так это же лишь отображаемые, вроде как, бары. Или всё-таки рабочие?

 

Scriptong:

В чем же бесполезность локального массива? Возможно, я неоднозначно выразился. Массив объявлен как член класса и однократно (при инициализации программы) распределен на максимально разрешенное стратегией количество ордеров, что избавляет от "долгой" операции перераспределения памяти (ArrayResize) и гарантирует, что не будет ошибок при ее выделении.  

Массив статический? Я щяс думаю. По идее, в 1-ое измерение запихать мейджик советника, например, в 2-ое имя инструмента, а в 3-е данные уже ордеров. Поскольку массив статический, то выделение памяти только 1 раз. Видеть его будут все эксперты данного терминала. Каждый своё... т.к. у каждого эксперта свой меджик.

 

Scriptong:

На каждом новом тике массив заполняется заново. Счетчик указывает количество заполненных элементов массива. 

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

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

Но тут есть один недочёт. Если ордер закроется по ТП или по СТОПу, то это будет, так сказать, "автономное закрытие" т.е. не по запросу с последующим изменением массива данные, а само по себе, завися от установленных параметров ордера. Получается в таком случает если не собирать информацию на каждом тике, то выходит что будет продел. Логично?

Но его можно восполнять, (до)собирая всё необходимое раз в минуту, например. 

 

Scriptong:

И да, конечно, при записи информации об ордерах это массив структур, что позволяет сохранять всю нужную информацию о каждом ордере. В Учебнике об этом не могли написать, т. к. тогда структур в MQL4 еще не было.  

А по скорости лучше массив 3-измерений или массив структур? Тут такое дело, что один знакомый говорил, что у него была проблема в МТ4 при попытке использования в структурах вроде бы дат, если я не ошибаюсь, или чего-то ещё. Какой-то тип не корректно работал. Вот от туда у меня и не особо желание их использовать в данном контексте.
 
shanty:

И как же пользователь может "спрятать" историю? В настройках то не даты, а кол-во баров имеется. Разве что только так... Игорь, Вы об этом говорите.  Так это же лишь отображаемые, вроде как, бары. Или всё-таки рабочие?

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

Массив статический?

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

 Я щяс думаю. По идее, в 1-ое измерение запихать мейджик советника, например, в 2-ое имя инструмента, а в 3-е данные уже ордеров. Поскольку массив статический, то выделение памяти только 1 раз. Видеть его будут все эксперты данного терминала. Каждый своё... т.к. у каждого эксперта свой меджик.

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

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

OrderInfo   orderArray[];

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

А какой смысл заполнять массив на каждом тике?

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

Но тут есть один недочёт. Если ордер закроется по ТП или по СТОПу, то это будет, так сказать, "автономное закрытие" т.е. не по запросу с последующим изменением массива данные, а само по себе, завися от установленных параметров ордера. Получается в таком случает если не собирать информацию на каждом тике, то выходит что будет продел. Логично?

Это уже зависит только от той логики, которую будет реализовывать программист, идущий путем хранения состояний ордеров. При правильной организации никакого пробела не будет: ордер исчез из списка рабочих, значит, его нужно удалить из массива. Я почему и говорю о преимуществах сбора данных на каждом тике.

 Но его можно восполнять, (до)собирая всё необходимое раз в минуту, например. 

Лишнее. Закрытие по SL (TP) происходит вследствие тика. Поэтому, обрабатывая тик за тиком, всегда можно отследить момент закрытия ордера по SL (TP).

А по скорости лучше массив 3-измерений или массив структур?

Не стоит зацикливаться на скорости исполнения. Это последняя задача в цепочке написания программы. Главное - написать качественный, легко читаемый, стабильно работающий, код. По этой причине, конечно же, использование структур выгоднее, т. к. они легче воспринимаются человеком. Кроме того, отсутствует ограничение в измерениях.

Тут такое дело, что один знакомый говорил, что у него была проблема в МТ4 при попытке использования в структурах вроде бы дат, если я не ошибаюсь, или чего-то ещё. Какой-то тип не корректно работал. Вот от туда у меня и не особо желание их использовать в данном контексте.

На сегодняшний день ни разу не сталкивался с проблемами при использовании структур. Скорее всего Ваш знакомый не смог найти ошибку в своей программе. 
 
Scriptong:

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

Так а смысл один раз изменять? Вы может о статическом массиве имели ввиду? Вы ж говорите, что проще задать максимально возможное количество ордеров, которое может понадобится сову. А это уже не динамический массив нужен больше, а статический, как я понимаю.
 
shanty:
Так а смысл один раз изменять? Вы может о статическом массиве имели ввиду? Вы ж говорите, что проще задать максимально возможное количество ордеров, которое может понадобится сову. А это уже не динамический массив нужен больше, а статический, как я понимаю.
А если максимально возможное количество заранее неизвестно и указывается пользователем в настроечном параметре? 
Причина обращения: