Машинное обучение в трейдинге: теория, модели, практика и алготорговля - страница 2065

 

Как-то так, вроде работает) Для экономии новый ряд собирается в rates[i].high

#property script_show_inputs
//+------------------------------------------------------------------+
input datetime tstart = D'2020.5.1 00:00';  // начало промежутка исследуемого времени
input datetime tstop = D'2020.10.1 00:00';   // конец промежутка исследуемого времени
string zztn = "dvol\\" + _Symbol + ".txt"; // text file name
//+------------------------------------------------------------------+
#define NM 1440
ulong NSM = 60;
ulong NSD = 60 * 1440;
//+------------------------------------------------------------------+
void OnStart()
{
  MqlRates rates[];
  double vol[NM] = {0.0}, d;
  int n[NM] = {0}, t;
  int nprice = CopyRates(Symbol(), PERIOD_M1, tstart, tstop, rates);
  for(int i = 0; i < nprice; ++i)
  {
    t = (int)((((ulong)rates[i].time) % NSD) / NSM);
    d = rates[i].close - rates[i].open;
    ++n[t];
    vol[t] += d * d;
  }
  for(int i = 0; i < NM; ++i)
  {
    if(n[i] > 1) vol[i] /= n[i];
    vol[i] = sqrt(vol[i]);
  }
  for(int i = 0; i < nprice; ++i)
  {
    t = (int)((((ulong)rates[i].time) % NSD) / NSM);
    if(vol[t] > 0) rates[i].high = (rates[i].close - rates[i].open) / vol[t];
    if(i > 0) rates[i].high += rates[i - 1].high;
  }
  int ft = FileOpen(zztn, FILE_WRITE | FILE_COMMON | FILE_ANSI | FILE_TXT);
  FileWriteString(ft, "t p");
  for(int i = 0; i < nprice; ++i)
    FileWriteString(ft, "\n" + (string)((ulong)rates[i].time) + " "  + (string)rates[i].high);
  FileClose(ft);
}
 
Aleksey Nikolayev:

Как-то так, вроде работает) Для экономии новый ряд собирается в rates[i].high

Вы прошлые бары, например от 2020.5.1 00:00 нормируете по барам из будущего, c  2020.10.1 00:00 и теми что между ними.
В реале вы этого не сделаете.
Надо от каждого бара делать примерно такой же расчет, но только от прошлых для него баров.

 
Aleksey Nikolayev:

Как-то так, вроде работает) Для экономии новый ряд собирается в rates[i].high

Даже если это сделать правильно, то можно очень точно эти нормированные высоты свечей восстановить сетью/лесом.
В качестве фич подаем 60 высот свечей со смещением на сутки, обучаем полученным в вашем коде нормированным высотам.
Обучение должно получиться с точностью близкой к 100%.

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

Надо конечно проверить, если эти нормированные высоты свечей улучшат результативность модели, то конечно нужно будет использовать её (либо одной вашей фичей, что предпочтительнее, либо 60-ю из которых она состоит).

 
Давайте уже проверяйте что то, а то три страницы исписали, энергии потратили , а прирост в ошибке  дай бог чтоб был в пол процента
 
elibrarius:

Странно. Интересно, как это можно объяснить?
У меня закоментирована еще одна версия, но она мне не понравилась по логическим соображениям:

Какой RandomInteger() используете?  Я XOR.

Не знаю как объяснить :)

Функцию эту брал

int RandomInteger(int max_vl)
{
   return (int)MathFloor((MathRand()+MathRand()*32767.0)/1073741824.0*max_vl);  //случайное Int от 0 до  1073741824
}
 

Максим, есть подозрение, что модель для C++ не корректно выгружается из CatBoost - можете сравнить с моделью для питона?

У меня не сходятся показатели интерпретации модели в MQL5, где показатели взяты из модели CPP, и показатели из бинарной модели. Дельта в районе 0,15 - что очень много.

 
elibrarius:

Вы прошлые бары, например от 2020.5.1 00:00 нормируете по барам из будущего, c  2020.10.1 00:00 и теми что между ними.
В реале вы этого не сделаете.
Надо от каждого бара делать примерно такой же расчет, но только от прошлых для него баров.

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

 
Aleksey Nikolayev:

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

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

Что за предварительный анализ? Подал на вход модели и сравниваешь - с этой фичей и без.

Мне кажется лучше нормировать по последним 30 минутам.
Как вариант, 30 последних минут этого дня и 5 предыдущих дней по 30 минут.

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

При нормировке за последнюю неделю, она быстрее научится новым правилам игры.
 
Aleksey Vyazmikin:

Не знаю как объяснить :)

Функцию эту брал

Попробуйте XOR
 
Aleksey Nikolayev:

В поиске внутридневных закономерностей мешают внутридневные колебания волатильности. Нужно как-то от них избавляться. Возможные способы:

1) Перенормировка приращений с учётом волатильности времени суток.

2) Переход к новому внутридневному времени, в котором дисперсия растёт равномерно.

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

Пункта 1 достаточно? Или 2 тоже надо? Что это? Поясните.
Причина обращения: