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

 

Привет всем,

Это может быть действительно глупый вопрос, но я действительно не могу найти способ сделать это. Я пытаюсь создать советника. После анализа нескольких баров, он решает открыть ордер или нет. Допустим, он открывает ордер. Каким-то образом, если мой советник остановится или metatrader выключится, когда я снова открою его, я хочу найти бары, которые вызвали открытие ордера. Поэтому я ищу ордера и нахожу свой ордер (который советник только что открыл), и я хочу начать анализировать бары назад. Как мне это сделать? Как я могу найти бар открытия ордера и начать возвращаться назад по барам.

например:

Я работаю на периоде H1 и ищу бары в 12:00, 13:00, 14:00 и 15:00, затем я решаю открыть ордер в 16:00. Важные бары находятся с 12:00 до 15:00, и я хочу определить эти бары снова. Поэтому при повторном запуске советника сначала я найду ордер и найду дату его открытия, определю, какой бар принадлежит этой дате, и начну возврат назад по барам до этой даты.

Я думал использовать Time array и т.д., но, пока я пытаюсь найти бары, что произойдет, если появится новый бар? Сдвиги изменятся, и мой поиск будет нелогичным.

Я также не хочу записывать эту информацию в файл. это требует слишком много времени и много обработки исключений и т.д.

спасибо.

 
paranoyakX:

Я думал использовать массив Time и т.д., но, пока я пытался найти бары, что произойдет, если появится новый бар? Сдвиги изменятся, и мой поиск будет нелогичным.


Новый бар не должен появляться, пока советник выполняет свой код. Он работает с данными, загруженными при вызове OnTick().

Не уверен, что произойдет, если использовать RefreshRates().

 
GumRai: Однако не уверен, что произойдет, если использовать RefreshRates().

Хотя это происходит не часто (на самом деле, очень редко), при использовании RefreshRates() у меня был опыт смещения данных бара из-за формирования нового бара. Чтобы обойти эту проблему, я стараюсь копировать все необходимые данные в переменные в самом начале, а затем не полагаться на History Data Arrays или аналогичные функции в течение всего остального времени выполнения события. Таким образом, даже если в моем коде потребуется использовать RefreshRates(), я все равно смогу безопасно ссылаться на начальные условия.

@paranoyakX: Итак, независимо от использования RefreshRates() или нет, вы можете попробовать аналогичный подход. На самом деле, в MQL5 у вас нет такой возможности, как в MQL4, и вам НУЖНО копировать данные в собственные массивы, чтобы обработать их. Таким образом, сделав это таким образом, вы фактически на несколько шагов приблизитесь к тому, чтобы ваш код был совместим как с MQL4, так и с MQL5.

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

 
paranoyakX:

[...] Я думал использовать массив Time и т.д., но, пока я пытался найти бары, что произойдет, если появится новый бар? Сдвиги изменятся, и мой поиск будет нелогичным.

То, о чем вы спрашиваете, потенциально настолько просто, что я думаю, не упускаю ли я суть. Учитывая предыдущий OrderSelect(), вы можете найти сдвиг баров, связанный с его OrderOpenTime(), просто сделав следующее:

int BarShiftOfOrderOpen = iBarShift(Symbol(), Period(), OrderOpenTime(), false);

Например:

  • график H1
  • Текущее время 16:32
  • Ордер был открыт в 14:23
  • Приведенный выше код должен вернуть BarShiftOfOrderOpen = 2, т.е. бар H1 в 14:00, и Time[BarShiftOfOrderOpen] будет 14:00.
 
jjc: То, о чем вы спрашиваете, потенциально настолько просто, что я думаю, не упускаю ли я суть. Учитывая предыдущий OrderSelect(), вы можете найти сдвиг бара, связанный с его OrderOpenTime(), просто сделав следующее:

Например:

  • График H1
  • Текущее время 16:32
  • Ордер был открыт в 14:23
  • Приведенный выше код должен вернуть BarShiftOfOrderOpen = 2, т.е. бар H1 в 14:00, и Time[BarShiftOfOrderOpen] будет 14:00.

Да, это именно то, о чем говорит ОП, но его интересует не то, как это сделать, а то, как предотвратить недействительность сдвига бара, вызванного новым входящим тиком, формирующим новый бар, пока он обрабатывает данные.

Однако этого НЕ должно происходить, за исключением случаев, когда вы используете RefreshRates(). Для такой возможности (что бывает редко) я предложил альтернативные методы, аналогично тому, как это делает MQL5.

 
FMIC:

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

Где в ОП говорится об этом? Возможно, это вопрос, но я думаю, что вы слышите стук копыт и думаете о зебрах, а не о лошадях. Упоминание о сохранении состояния советника в файл при перезапуске MT4 наводит меня на мысль, что вопрос на самом деле намного, намного проще.
 

Здравствуйте, ребята,

большое спасибо за ответы,

@FMIC, интересно, что я никогда не думал использовать индикаторы, и, как вы говорите, это может быть намного проще, если я создам и использую один, но, конечно, это принесет новые вопросы, например, как найти значение индикатора, которое сопрягается с моим ордером и т.д.. Кроме того, я не буду делать этот процесс каждый раз, только OnInit() один раз. так что, возможно, использование советника подойдет для этого.

@jjc, спасибо за ваше решение. Я действительно немного беспокоился о "новом баре", но, как вы все сказали, пока советник работает, сдвиг не будет меняться (и я не использую функцию RefreshRates()), поэтому я могу использовать и ваш код. Мне просто интересно, после того, что сказал @FMIC, будет ли лучше, если я создам это как индикатор?

 
jjc:
Где в ОП говорится об этом? Возможно, это вопрос, но я думаю, что вы слышите стук копыт и думаете о зебрах, а не о лошадях. Упоминание о сохранении состояния советника в файл при перезапуске MT4 наводит меня на мысль, что вопрос на самом деле намного, намного проще.

Даже ГумРай уловил это и процитировал его, что я и сделаю здесь:

paranoyakX:

Я думал использовать Time array и т.д., но, пока я пытался найти бары, что произойдет, если появится новый бар? Сдвиги будут изменены, и мой поиск будет нелогичным.

 
paranoyakX:

@FMIC, интересно, я никогда не думал использовать индикаторы, и, как вы говорите, это может быть намного проще, если я создам и использую один, но, конечно, это принесет новые вопросы, например, как найти значение индикатора, которое сопрягается с моим ордером и т.д.. Кроме того, я не буду делать этот процесс каждый раз, только OnInit() один раз. так что, возможно, использование советника подойдет для этого.

@jjc, спасибо за ваше решение. Я действительно немного беспокоился о "новом баре", но, как вы все сказали, пока советник работает, сдвиг не будет меняться (и я не использую функцию RefreshRates()), поэтому я могу использовать и ваш код. Мне просто интересно, после того, что сказал @FMIC, будет ли лучше, если я создам это как индикатор?

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

PS! Вы не должны помещать никакой логический код в OnInit(), это только то, где вы инициализируете вещи и никогда не имеет никакого отношения к данным из массивов серии исторических данных. Вся ваша логика и основной код должны быть в OnTick() или в OnCalculate().

 
FMIC:

Даже GumRai заметил это и процитировал его, что я сделаю еще раз здесь:

Вы и Gumrai делаете огромное предположение о значении "если появляется новый бар", которое пока не подтверждается доказательствами. ОП еще не сказал "если новый бар поднимается во время OnStart".

Я подозреваю, что paranoyakX хранит детали торговли/сигналов в глобальных переменных в советнике. Проблема, как я подозреваю, заключается не в новых барах, формирующихся во время вызова OnStart(), а в новых барах, формирующихсяво время жизни советника.

 
jjc:

Вы и Gumrai делаете массивное предположение о значении "если новый бар поднимается", которое пока не подтверждается доказательствами. ОП еще не сказал "если новый бар появляется во время OnStart".

Я подозреваю, что paranoyakX хранит детали торговли/сигналов в глобальных переменных в советнике. Проблема, как я подозреваю, заключается не в новых барах, образующихся во время вызова OnStart(), а в новых барах, образующихсяво время жизни советника.

В советниках нет OnStart(), но я понял, что вы имели в виду. Однако ОП даже в ответ на ваши комментарии сказал, цитирую:

На самом деле я немного беспокоился по поводу "нового бара", но, как вы все сказали, пока советник работает, сдвиг не будет меняться (и я не использую функцию RefreshRates()).