Редактирование списка Обзора рынка

С помощью функции SymbolSelect разработчик MQL-программы может добавить конкретный символ в Обзор рынка или удалить оттуда.

bool SymbolSelect(const string name, bool select)

Параметр name содержит имя символа, над которым выполняется действие. В зависимости от значения параметра select символ добавляется в Обзор рынка (true) или удаляется из него. В именах символов учитывается регистр: например, "EURUSD.m" не равно "EURUSD.M".

Функция возвращает признак успеха (true) или ошибки (false). Код ошибки можно узнать в _LastError.

Символ не может быть убран, если есть открытые графики с этим символом или открытые позиции по этому символу. Кроме того, нельзя удалить символ, который явным образом использован в формуле расчета синтетического (пользовательского) инструмента, добавленного в Обзор рынка.

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

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

#include <MQL5Book/MqlError.mqh>
   
#define PUSH(A,V) (A[ArrayResize(AArraySize(A) + 1) - 1] = V)
   
void OnStart()
{
   // запрашиваем подтверждение пользователя на удаление
   if(IDOK == MessageBox("This script will remove all unused symbols"
      " from the Market Watch. Proceed?""Please, confirm"MB_OKCANCEL))
   {
      const int n = SymbolsTotal(true);
      ResetLastError();
      string removed[];
      // проходим по символам Обзора рынка в обратном порядке
      for(int i = n - 1i >= 0; --i)
      {
         const string s = SymbolName(itrue);
         if(SymbolSelect(sfalse))
         {
            // запоминаем, что удалось удалить
            PUSH(removeds);
         }
         else
         {
            // в случае ошибки выводим причину
            PrintFormat("Can't remove '%s': %s (%d)"sE2S(_LastError), _LastError);
         }
      }
      const int r = ArraySize(removed);
      PrintFormat("%d out of %d symbols removed"rn);
      ArrayPrint(removed);
      ...

После того как пользователь даст согласие на анализ списка символов, программа пытается последовательно скрыть каждый символ, вызывая SymbolSelect(s, false). Это удается только для неиспользуемых явно инструментов. Перебор символов производится в обратном порядке, чтобы не нарушать индексацию. Все успешно удаленные символы собираются в массиве removed. В журнал выводится статистика и сам массив.

Если Обзор рынка был изменен, пользователю затем предоставляется возможность восстановить в нем все удаленные символы, вызвав в цикле SymbolSelect(removed[i], true).

      if(r > 0)
      {
         // есть возможность вернуть удаленные символы обратно в Обзор рынка
         // (в этот момент в окне отображается сокращенный список)
         if(IDOK == MessageBox("Do you want to restore removed symbols"
            " in the Market Watch?""Please, confirm"MB_OKCANCEL))
         {
            int restored = 0;
            for(int i = r - 1i >= 0; --i)
            {
               restored += SymbolSelect(removed[i], true);
            }
            PrintFormat("%d symbols restored"restored);
         }
      }
   }
}

Вот каким может быть результат в журнале.

Can't remove 'EURUSD': MARKET_SELECT_ERROR (4305)
Can't remove 'XAUUSD': MARKET_SELECT_ERROR (4305)
Can't remove 'BTCUSD': MARKET_SELECT_ERROR (4305)
Can't remove 'GBPUSD': MARKET_SELECT_ERROR (4305)
...
Can't remove 'USDRUB': MARKET_SELECT_ERROR (4305)
2 out of 10 symbols removed
"NZDUSD" "USDCAD"
2 symbols restored

Примите к сведению, что хотя восстановление символов и производится в исходном порядке, в каком они были в Обзоре рынка относительно друг друга, добавление происходит в конец списка, после оставшихся символов. Таким образом, все "занятые" символы окажутся в начале списка, а восстановленные — после них. Такова специфика SymbolSelect: добавление символа всегда производится в конец списка, то есть вставить символ в конкретную позицию нельзя — перестановка элементов списка доступна только для ручного редактирования.