Обсуждение статьи "Вычисление математических выражений (Часть 2). Парсеры Пратта и сортировочной станции"

 

Опубликована статья Вычисление математических выражений (Часть 2). Парсеры Пратта и сортировочной станции:

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

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

Пример торговли по сигналам, вычисленным по выражениям

Пример торговли по сигналам, вычисленным по выражениям

Автор: Stanislav Korotky

 
Когда быстродействие будете сравнивать, сравните его с чистым MQL.
 

Сравнение быстродействия с учетом родного MQL5 такое:

ExpresSParserS (EURUSD,D1)      Evaluation: 105109
ExpresSParserS (EURUSD,D1)      Compilation: 26090
ExpresSParserS (EURUSD,D1)      Pratt bytecode: 24030
ExpresSParserS (EURUSD,D1)      Pratt: 26567
ExpresSParserS (EURUSD,D1)      ShuntingYard: 23884
ExpresSParserS (EURUSD,D1)      MQL5: 12901

MQL5 примерно в 2 раза быстрее самых быстрых парсеров из представленных.

Добавленный тестовый код:

class FuncCalc
{
  private:
    double a;
    double b;
    double c;
  public:
    void setup(double _a, double _b, double _c)
    {
      a = _a;
      b = _b;
      c = _c;
    }
    double execute()
    {
      return (a + b) * (c > 10000 ? c / 4 : c * 4);
    }
};

ulong testMQL5(const int n)
{
  ulong ul = 0, total = 0;
  double r;
  FuncCalc f;

  for(int i = 0; i < n; i++)
  {
    f.setup(rand(), rand(), rand());
    ul = GetMicrosecondCount();
    r = f.execute();
    total += GetMicrosecondCount() - ul;
  }
  return total;
}

Это грубая оценка. Для исследований (например, с разными типами выражений) и оптимизации парсеров остается большой простор.

 

вот теперь могу только похвалить. 

Ну конечно стоило бы упомянуть Дийкстра, как бы исторично шутинг-ярд более с ним ассоциируется

вот была мысль сделать подобную статью, даже для себя набирал материал,  вы меня опередили (про часть 2),  но у меня всё привычно скатывалось в форт и стековые машины

вы смогли в него (или лисп) статью не скатить !

вишенкой на торте был бы Y-комбинатор. 

PS. а вот байт-коды у вас получились на взгляд "широковаты"и убиты классами. Можно со свистом и переносимо обойтись в 64 бита. Ну  на то хозяин-барин :-)

 
Maxim Kuznetsov:

вот теперь могу только похвалить. 

Ну конечно стоило бы упомянуть Дийкстра, как бы исторично шутинг-ярд более с ним ассоциируется

вот была мысль сделать подобную статью, даже для себя набирал материал,  вы меня опередили (про часть 2),  но у меня всё привычно скатывалось в форт и стековые машины

вы смогли в него (или лисп) статью не скатить !

вишенкой на торте был бы Y-комбинатор. 

PS. а вот байт-коды у вас получились на взгляд "широковаты"и убиты классами. Можно со свистом и переносимо обойтись в 64 бита. Ну  на то хозяин-барин :-)

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

 
Stanislav Korotky:

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

байт-код зависит от виртуальной машины. С какой-то стороны меня жаба задавила отдавать 128 бит или более под оп-код "сложение двух чисел" ..

а новых типов парсеров пока не изобретено, им всем лет эдак много ;-) и их всего-то ничего, 2 с половиной штуки

PS сортировочной станции под нужды пользователей терминала за-глаза - можно ввести привычную формулу в поле ввода и получить результат. 

 
В отличии от некоторых других статей, эти две статьи очень хороши. Четко, подробно, доступно. Спасибо.
 
Обновленная версия вычислителей 1.1 приложена к статье про оптимизацию методом роя частиц. Плюс в обсуждении есть мелкий багфикс.
Параллельная оптимизация методом роя частиц (Particle Swarm Optimization)
Параллельная оптимизация методом роя частиц (Particle Swarm Optimization)
  • www.mql5.com
Как известно, MetaTrader 5 позволяет оптимизировать торговые стратегии с помощью встроенного тестера на основе двух алгоритмов: прямого перебора входных параметров и генетики (генетический алгоритм - ГА). Генетическая оптимизация является одной из разновидностей эволюционных алгоритмов, которые предоставляют значительное ускорение процесса...
 
Просьба показать, как использовать парсер такой строки.
"(EURUSD^2) / (GBPUSD * AUDUSD)"

Сложность заключается в том, что нужно автоматически определять, в каком случае и куда подставлять bid/ask.

В примере выше должно быть так.

Value_Bid = (EURUSD_Bid * EURUSD_Bid / (GBPUSD_Ask * AUDUSD__Ask);
Value_Ask = (EURUSD_Ask * EURUSD_Ask / (GBPUSD_Bid * AUDUSD__Bid);


Алгоритм определения Bid/Ask такой. На все том же примере.

F(EURUSD, GBPUSD, AUDUSD) = (EURUSD^2) / (GBPUSD * AUDUSD);

bool EURUSD_flag = (F(1, 1, 1) < F(2, 1, 1));
bool GBPUSD_flag = (F(1, 1, 1) < F(1, 2, 1));
bool AUDUSD_flag = (F(1, 1, 1) < F(1, 1, 2));

Value_Bid = F(EURUSD_flag ? EURUSD_Bid : EURUSD_Ask,
              GBPUSD_flag ? GBPUSD_Bid : GBPUSD_Ask,
              AUDUSD_flag ? AUDUSD_Bid : AUDUSD_Ask);

Value_Ask = F(EURUSD_flag ? EURUSD_Ask : EURUSD_Bid,
              GBPUSD_flag ? GBPUSD_Ask : GBPUSD_Bid,
              AUDUSD_flag ? AUDUSD_Ask : AUDUSD_Bid);
 
fxsaber:
Просьба показать, как использовать парсер такой строки.

Основная сложность, это определить названия всех переменных в выражении. Чтобы потом можно было написать что-то подобное.

TestSuiteEvaluator evaluator("EURUSD=1.5;GBPUSD=2.5;AUDUSD=5");
 
С точки зрения парсера переменная не может иметь 2 значения: бид и аск. Вероятно, можно обернуть компоненты в функции (либо ввести функции Bid(символ), Ask(символ), либо целиком функцию "корзины", если число компонент предопределено). В принципе, не ясна исходная задача: если речь о синтетике/корзине из трех символов, то в ней каждая составляющая приобретается однозначно либо по аск, либо по бид, в зависимости от направления. Еще можно рассмотреть вариант разных выражений в зависимости от направлений сделок.