Ускорение работы экспертов в тестере - страница 2

 
Renat Fatkhullin:

Если не создаать кеши, то тестирование еще дольше будет. Кеши кардинально ускоряют вторые и последующие проходы.

Что кешируется? Ценовая история же дублируется? Тогда откуда гигабайты кешей или это преувеличение?

Сам тестирую не больше, чем за месяц, поэтому проблем не замечал. Ну и SSD, конечно.

 
Stanislav Korotky:

Для ускорения можно:

- перенести алгоритмы индикаторов в сам эксперт (обслуживание вызовов индикаторов занимает заметное время)

В цифрах есть данные?

 
fxsaber:

Что кешируется? Ценовая история же дублируется? Тогда откуда гигабайты кешей или это преувеличение?

Сам тестирую не больше, чем за месяц, поэтому проблем не замечал. Ну и SSD, конечно.

А вы посмотрите в локальные каталоги своего тестера во время длительного теста.

Не после теста, а во время длительного теста на большой истории.


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

 
Vladislav Andruschenko:


SSD скорее решает больше чем даже оперативная... 

после установки ssd - все терминалы, тетсирование, графика летают.... как в детстве после покупки Pentium 3 взамен 286


а если SSD установить только на диск С, а на диск D - HDD , будет хуже?

или лучше , чтобы и диск С и диск D были на SSD?

 
Максим Дмитриев:

а если SSD установить только на диск С, а на диск D - HDD , будет хуже?

или лучше , чтобы и диск С и диск D были на SSD?

Достаточно один лист ssd на втором HDD я храню там фильмы и музыку. 
 
fxsaber:

В цифрах есть данные?

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

 
Stanislav Korotky:

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

Для ускорения можно:

- реализовать стратегию торговли по барам (тогда тики не нужны)

- перенести алгоритмы индикаторов в сам эксперт (обслуживание вызовов индикаторов занимает заметное время)

- исключить работу с графикой и объектами при тестировании без визуализации

- кэшировать расчеты, если возможно

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

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


Спасибо.

 
Ekaterina Belova:

Спасибо.


А как ускорить расчеты, как именно их можно кэшировать?

 
Ekaterina Belova:

А как ускорить расчеты, как именно их можно кэшировать?

Это зависит от используемого алгоритма. В качестве тривиального примера можно, например, привести МА-шку, которую суммировать не по всем значениям периода, а со сдвигом на одно значение, сохраняя все время промежуточную сумму для N-1 значений.

Если кто-то использует нейросеть, то можно её не обучать целиком, а дообучать.

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

=====

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

// collect data about trades and calculate profits by instrument
double CalculateProfit(string CurrentSymbol)
{
  HistorySelect(0, TimeCurrent());
  int n = HistoryDealsTotal();
  
  ulong ticket;
  string symbol;
  long entry;
  double profit = 0;
  
  for(int i = 0; i < n; i++)
  {
    ticket = HistoryDealGetTicket(i);
    if(ticket != 0)
    {        
      entry  = HistoryDealGetInteger(ticket, DEAL_ENTRY);
      if(entry == DEAL_ENTRY_OUT)
      {
        symbol = HistoryDealGetString(ticket, DEAL_SYMBOL);
        if(symbol == CurrentSymbol)
        {
          profit += HistoryDealGetDouble(ticket, DEAL_PROFIT);
        }
      }
    }
  }
  
  return(profit);
}

Функция представляет собой типичный пример скрытого источника проблемы. Это бомба замедленного действия. На первый взгляд она работает корректно. И даже на второй, и на третий, потому что проблема относится не к результату, а к тому, какой ценой он получен. По мере работы эксперта эта функция тормозит все больше и больше в геометрической прогрессии, потому что история сделок увеличивается. Разумеется, более оптимальным способом подсчета прибыли было бы её накопление в массиве по символам, с добавлением изменений из свежей части истории, не обработанной с предыдущего раза (например, бара).

double SymbolProfits[];

// TODO: распределение и инициализация массива нулями в OnInit

datetime lastProfitCalculation = 0;

void CalculateProfits()
{
  datetime dt = TimeCurrent();
  if(dt == lastProfitCalculation) return;
  HistorySelect(lastProfitCalculation, dt);
  int n = HistoryDealsTotal();
  
  ulong ticket;
  string symbol;
  long entry;
  
  for(int i = 0; i < n; i++)
  {
    ticket = HistoryDealGetTicket(i);
    if(ticket != 0)
    {        
      entry  = HistoryDealGetInteger(ticket, DEAL_ENTRY);
      if(entry == DEAL_ENTRY_OUT)
      {
        symbol = HistoryDealGetString(ticket, DEAL_SYMBOL);
        int index = FindSymbolIndex(symbol);
        if(index != -1)
        {
          SymbolProfits[index] += HistoryDealGetDouble(ticket, DEAL_PROFIT);
        }
      }
    }
  }
  lastProfitCalculation = dt;
}

double CalculateProfit(int index)
{
  return(SymbolProfits[index]);
}

Все инкрементные расчеты профита выполняет теперь функция CalculateProfits, которую следует вызывать один раз на каждом баре, а CalculateProfit лишь возвращает при необходимости уже посчитанное значение по символу.

=====