Обсуждение статьи "Кэширование метаданных символов и расписаний торговых сессий в MQL5: Устранение лишних вызовов SymbolInfo в мультисимвольных советниках"

Опубликована статья Кэширование метаданных символов и расписаний торговых сессий в MQL5: Устранение лишних вызовов SymbolInfo в мультисимвольных советниках:

В этой статье представлен CSymbolMetaCache — программный слой на MQL5, который при запуске советника заранее загружает спецификации контрактов и расписания торговых сессий отслеживаемых символов, а затем возвращает их значения через типизированные геттеры из кэша в памяти. В статье объясняется, какие свойства можно безопасно кэшировать, а какие являются динамическими, включая полудинамическую стоимость тика для кросс-валютных пар. Также реализуется функция IsMarketOpen(), которая определяет, открыта ли сессия, используя кэшированные данные. Тест производительности показывает, насколько сокращается задержка при работе с набором из двадцати символов.

Многосимвольный советник, отслеживающий двадцать инструментов, обычно вызывает функции SymbolInfoDouble(), SymbolInfoInteger() и связанные с ними функции на каждом тике для каждого отслеживаемого символа. Размер пункта, стоимость тика, шаг объема и количество знаков после запятой — это минимальный набор параметров, необходимый большинству алгоритмов для расчета объема позиции и форматирования цены. При 10 тиках в секунду для 20 символов и четырех таких вызовах на символ за тик получается 800 обращений к терминалу каждую секунду.

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

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

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

В результате получается класс CSymbolMetaCache с типизированными геттерами для каждого кэшированного поля, методом IsMarketOpen(), который проверяет интервалы торговых сессий с помощью сравнений исключительно в памяти, и методом Refresh() — единственной точкой, в которой после инициализации кэш снова обращается к API терминала. Скрипт теста производительности измеряет фактическую разницу в задержке на наборе из двадцати символов, чтобы количественно оценить преимущества кэширования на практике.

Symbol metadata cache — before and after


Автор: Ushana Kevin Iorkumbul

Статья о том, что в MQL5 можно использовать переменные для почти const-свойств символа.
   m_meta[idx].symbol         = symbol;
   m_meta[idx].digits         = (int)::SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   m_meta[idx].point          = ::SymbolInfoDouble(symbol, SYMBOL_POINT);
   m_meta[idx].tick_size      = ::SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
   m_meta[idx].tick_value     = ::SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
   m_meta[idx].lot_step       = ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   m_meta[idx].lot_min        = ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
   m_meta[idx].lot_max        = ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
   m_meta[idx].contract_size  = ::SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
   m_meta[idx].margin_initial = ::SymbolInfoDouble(symbol, SYMBOL_MARGIN_INITIAL);
   m_meta[idx].currency_base   = ::SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE);
   m_meta[idx].currency_profit = ::SymbolInfoString(symbol, SYMBOL_CURRENCY_PROFIT);
   m_meta[idx].currency_margin = ::SymbolInfoString(symbol, SYMBOL_CURRENCY_MARGIN);
   m_meta[idx].trade_mode      = (ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE);

Проблема полностью придумана, не имеет ничего общего с реальностью. Это точно человек написал статью?

fxsaber #:
Статья о том, что в MQL5 можно использовать переменные для почти const-свойств символа.

Проблема полностью придумана, не имеет ничего общего с реальностью. Это точно человек написал статью?

почти точно НЕТ ;-)

Кеш с линейной асимптотой мог придумать только смутный AI

на каждый вызов - линейный поиск строк в массиве.."Йа зделал" 

зато статья, бонусы, копейки 

Maxim Kuznetsov #:

Почти наверняка НЕТ ;-)

Только несовершенный ИИ мог бы придумать кэш с линейной асимптотой

При каждом вызове — линейный поиск строк в массиве… «Я это сделал»

Но всё же — статья, бонусы, копейки

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

Лично я воспринимаю это как непреднамеренный комплимент, когда такое случается со мной.