Проблема перевода с МТ4 на МТ5. Или, точнее, невозможность без'ошибочного исполнения некоторых алгоритмов в МТ5. - страница 11

 

Информацию для размышдения.

Смотрю некоторые разработки советников, публикуемых в маркете. Или некоторые статьи.

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

И, на мой взгляд, МТ5 во многом затачивался для быстрого реагирования на изменения на рынке. Этим объясняется отключение всех тормозов с ожиданиями обновления котировок.

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

Такая парадигма имеет право на существование. При этом торговля ведется короткая. Быстро вошли. Собрали несколько пунктов. Быстро вышли.

Но есть другая парадигма.

Есть какие-то экстремальные ситуации на рынке, на которых образовались развороты рынка.

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

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

В этом случае можно и подождать обновления котировок без выхода из обработчика в результате прерывания доступа. И это как раз в МТ4 работает.

Несколько картинок с пояснениями сказанного.

Берем месячный тф. Экстремумы в марте 1995 года, октябре 2000 года и июле 2007 года продолжают оказывать влияние на рынок.

Даже экстремум за февраль 1985 года оказывает влияние:


Видно, что линии построенные с учетом этих экстремумов замечаются рынком.

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

Недельный тф:

D1:

H4:

M30:

M5:

M1:

Видим, экстремумы, образовавшиеся далеко в истории, оказывают влияние на текущий момент на рынке.

----------------------------------

Для таких построений должен быть непрерывный доступ к котировкам.

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

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

При этом сигналы от НС со старшего тф более приоритетные, чем с младшего.

Полученные сигналы от нейросетей подаются на вход следующей НС с каким-то учетом приоритетности. Тут могут быть варианты.

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

Суммирующая нейросеть может иметь какую-то свою архитектуру. Это уже больше инженерная задача.

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

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

Получается алгоритм чем-то похожий на то, что реализовано в Alfa Zero командой DeepMinde.

Потренировать такую сеть на всей истории по всем выбранным тф. Единственное, надо учесть, что в МТ5 все таймсерии строятся из минуток. А это неправда. Файлы NCC по евродоллару до 1993 года собраны из дневок. Должен быть алгоритм восстанавливающий истинный таймфрейм таймсерий.

Обучать можно на одной валютной паре. А тестировать на другой.

------------------------------

Резюме. Зачем в таком подходе быстрое реагирование на происходящее на рынке?

 
Eugeni Neumoin:


извините за некий оффтоп, но пока тема интересная, не могу бросить


Vict:

Ну я о том, чтобы вот так заюзать:

в MQL есть typename() - она возвращает строковое название типа, работает даже

void OnStart()
  {
   Print(typename(Txt()));      // в логе будет       string
  }
string Txt()
{
return(" Txt ");
}

осталось дело за малым - зная тип MyFunc() - написать макрос ((( , ... можно конечно написать все макросы по типам _Try_helper ... в общем я видимо не азартный, ибо не знаю как

 
Igor Makanu:

извините за некий оффтоп, но пока тема интересная, не могу бросить


Все нормально. 

 
Igor Makanu:

в MQL есть typename() - она возвращает строковое название типа, работает даже

осталось дело за малым - зная тип MyFunc() - написать макрос ((( , ... можно конечно написать все макросы по типам _Try_helper ... в общем я видимо не азартный, ибо не знаю как

typename() в мкл не поможет, не даст она во время компиляции тип, пригодный для объявления переменной, лишь принтовать ею. Остаётся лишь плодить Try_d(), Try_i(), ... . Я не знаю как в мкл получить функциональность decltype.

 
Vict:

typename() в мкл не поможет, не даст она во время компиляции тип, пригодный для объявления переменной, лишь принтовать ею. Остаётся лишь плодить Try_d(), Try_i(), ... . Я не знаю как в мкл получить функциональность decltype.

хм, чувствую себя совсем не азартным! скажу даже больше абсолютно не азартным! ))) - я не знаю как, вот так будет что то работать (я правда не понимаю как это на уровне машины "все крутится" - вроде имеем строго типизированный язык?)

void OnStart()
{
  int i = func(1);
  double d = func(1.123);
  string s = func("s");
  Print("i = ",i);
  Print("d = ",d);
  Print("s = ",s);
}

template<typename T>
T func(T invalue)
{
   string s = typename(T);
   if(s=="int") return(invalue);
   if(s=="double") return(invalue);
   if(s=="string") return("Hello word!!!");
return(NULL);
}

2019.07.31 21:07:05.304 tst2 (EURUSD,H1) i = 1

2019.07.31 21:07:05.304 tst2 (EURUSD,H1) d = 1.123

2019.07.31 21:07:05.304 tst2 (EURUSD,H1) s = Hello word!!!


можно еще описать указатель на функцию 

typedef void(*TFuncvoidPTR)(void);

и в дальнейшем использовать 

TFuncvoidPTR      func[];
....
func[0]();
 
Vict:

typename() в мкл не поможет, не даст она во время компиляции тип, пригодный для объявления переменной, лишь принтовать ею. Остаётся лишь плодить Try_d(), Try_i(), ... . Я не знаю как в мкл получить функциональность decltype.

Шаблонная функция со статической переменной T-типа.

 
Igor Makanu:

спасибо!

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

Имхо,результаты у компилятора MQL5 реально из области фантастики (он очень производителен!), а вот применение как торгового терминала... ну скажем так: он требует очень и очень хорошей технической подготовки и желания писать ~30% больше кода чем "в старом терминале" ( - даже эта фраза тут на форуме уже устоявшееся выражение)

Ай-яй... Не говорил я такого :)

Я говорил - используем то что есть для получения нужного результата.

Остальные эмоции я держу при себе.

 
Igor Makanu:

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

то бишь, я не знаю что там у кого в голове получилось, вижу только свою голову... благо пока в зеркале ))) 

Поверил бы, если бы вместо

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

было

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

А так получается, что одна голова из зеркала процитировала якобы модератора Артёма...

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

Могу озвучит моё мнение:

Делаем спокойно из того, что есть на данный момент, не ноем, помогаем в поисках багов и просим с ожиданием исправлений - они всё-таки правятся и появляются новые приятные фишки.

 
Artyom Trishkin:

Поверил бы, если бы вместо

было

А так получается, что одна голова из зеркала процитировала якобы модератора Артёма...

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

Могу озвучит моё мнение:

Делаем спокойно из того, что есть на данный момент, не ноем, помогаем в поисках багов и просим с ожиданием исправлений - они всё-таки правятся и появляются новые приятные фишки.

хм, как все сложно стало.... убирал за собой, мое мнение... да какая разница? что изменится? у разработчиков свое видение развития своих продуктов, это их бизнес и мое мнение ... ну если не апать топик, через 2 дня будет глубоко не в топе


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

ладно, помолчу, благо тут форум с историей, можно читать не перечитать  - ответов очень много на мои вопросы в поиске этого форума

 
Igor Makanu:

fxsaber верно сказал - есть один вариант

template <typename T> T Try_helper(T val, bool assign) {
   static T sval;
   if (assign)
      sval = val;
   return sval;
}
#define Try(EXPR, MES)                    \
   Try_helper(EXPR, true);                \
   if (Try_helper(EXPR, false) <= 0.0) {  \
     printf("Error: %s ", MES);           \
     return;                              \
   }

double f(double) {return DBL_MAX;}
ulong f(ulong) {return ULONG_MAX;}

void OnStart()
{

   double d = Try(f(0.), "double error");
   ulong u = Try(f(0), "ulong error");
}

Немного костыльненько - EXPR будет вычисляться дважды, но всё же гибче. Нельзя сказать, что вот прям вообще универсально (лишь для арифметических типов. Значение ошибки должно быть одинаковым, что неприятно. Пытался обойти через явную специализацию структуры/функции, но нельзя

template <typename T> bool Try_helper_is_valid(T val);
template <> bool Try_helper_is_valid<string>(string val) {val==""?false:true;}  // compile-time error

template <typename T>
struct S;
template <>
struct S<string> {...};      // compile-time error

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

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