编辑市场报价列表

使用 SymbolSelect 函数,MQL 程序开发人员可以在 Market Watch 中添加或删除特定交易品种。

bool SymbolSelect(常量字符串名称, bool select)

参数 name 包含受此运算影响的交易品种名称。根据参数 select 的值,可以向 Market Watch 中添加 (true) 或移除一个交易品种。交易品种名称区分大小写:例如,“EURUSD.m”不等于“EURUSD.m”。

该函数返回成功 (true) 或错误 (false) 的指示。错误代码可在 _LastError 中找到。

如果某个交易品种有打开的图表或为平仓的头寸,则不能删除该交易品种。此外,不能删除添加到 Market Watch 的合成(自定义)金融工具的计算公式明确使用的交易品种。

应注意,即使一个交易品种没有打开的图表和未平仓的头寸,也可以被 MQL 程序间接使用:例如,它们可以读取其报价或分时报价的历史。删除此类交易品种可能会导致这些程序出现问题。

以下脚本 SymbolRemoveUnused.mq5 能够隐藏所有没有显式使用的交易品种,所以建议在一个演示账户上对其进行检查,或者首先通过上下文菜单保存当前的交易品种集。

#include <MQL5Book/MqlError.mqh>
   
#define PUSH(A,V) (A[ArrayResize(AArraySize(A) + 1) - 1] = V)
   
void OnStart()
{
   // request user confirmation for deletion
   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[];
      // go through the symbols of the Market Watch in reverse order
      for(int i = n - 1i >= 0; --i)
      {
         const string s = SymbolName(itrue);
         if(SymbolSelect(sfalse))
         {
            // remember what was deleted
            PUSH(removeds);
         }
         else
         {
            // in case of an error, display the reason
            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 数组中。日志可显示统计数据和数组本身。

如果 Market Watch 被改变,则用户可以通过在循环调用 SymbolSelect(removed[i], true) 来恢复所有被删除的交易品种。

      if(r > 0)
      {
         // it is possible to return the deleted symbols back to the Market Watch
         // (at this point, the window displays a reduced list)
         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

请注意,虽然交易品种是按照它们在 Market Watch 中的原始相对顺序恢复的,但是添加的交易品种会出现在列表的末尾,在剩余交易品种之后。因此,所有“被占用”交易品种将位于列表的开头,所有恢复的交易品种将位于其后。SymbolSelect 的具体操作如下:交易品种始终添加在列表的末尾,也就是说,不能在特定位置插入交易品种。因此,列表元素的重新排列只能通过手动编辑来进行。