查找对象
有三个函数可用于在图表上搜索对象。前两个函数 ObjectsTotal和ObjectName 允许按名称遍历对象,然后在需要时使用每个对象的名称分析其他特性(下一节详述具体实现方法)。第三个函数ObjectFind允许通过已知名称验证对象是否存在。同样,也可以通过 ObjectGet函数直接请求某个特性来实现这一点:如果不存在与传入名称匹配的对象,_LastError 中将返回错误,但这种方式不如调用ObjectFind 便捷。此外,该函数会立即返回对象所在窗口编号。
int ObjectsTotal(long chartId, int window = -1, int type = -1)
该函数返回指定chartId标识符(0 表示当前图表)的图表上的对象数量。计算时仅考虑指定window编号的子窗口中的对象(0 表示主窗口,-1 表示主窗口及所有子窗口)。请注意,仅考虑type参数中指定的特定类型的对象(默认值 -1 表示所有类型)。type的值可以是 ENUM_OBJECT 枚举中的元素。
该函数采用同步执行方式,即会阻塞调用的 MQL 程序,直到获取结果。
string ObjectName(long chartId, int index, int window = -1, int type = -1)
该函数返回标识符为 chartId的图表上指定索引号index 的对象名称。在编译用于搜索对象的内部列表时,会考虑指定的子窗口编号(window)和对象类型(type)。此列表按对象名称的字典序排序,即具体按字母顺序排列且区分大小写。
与 ObjectsTotal类似,ObjectName 在执行期间会等待获取整个图表命令队列,然后从更新后的对象列表中返回对象名称。
如果发生错误,将返回空字符串,且将 OBJECT_NOT_FOUND (4202) 错误代码存储在 _LastError中。
为了测试这两个函数的功能,我们将创建一个名为ObjectFinder.mq5的脚本,用于记录所有图表上的所有对象。该脚本使用 图表迭代 函数(ChartFirst和 ChartNext),以及获取 图表特性 的函数(ChartSymbol、ChartPeriod 和 ChartGetInteger)。
#include <MQL5Book/Periods.mqh>
void OnStart()
{
int count = 0;
long id = ChartFirst();
// loop through charts
while(id != -1)
{
PrintFormat("%s %s (%lld)", ChartSymbol(id), PeriodToString(ChartPeriod(id)), id);
const int win = (int)ChartGetInteger(id, CHART_WINDOWS_TOTAL);
// loop through windows
for(int k = 0; k < win; ++k)
{
PrintFormat(" Window %d", k);
const int n = ObjectsTotal(id, k);
// loop through objects
for(int i = 0; i < n; ++i)
{
const string name = ObjectName(id, i, k);
const ENUM_OBJECT type = (ENUM_OBJECT)ObjectGetInteger(id, name, OBJPROP_TYPE);
PrintFormat(" %s %s", EnumToString(type), name);
++count;
}
}
id = ChartNext(id);
}
PrintFormat("%d objects found", count);
}
|
对于每个图表,我们确定子窗口的数量 (ChartGetInteger(id, CHART_WINDOWS_TOTAL)),为每个子窗口调用 ObjectsTotal 函数,并在内层循环中调用ObjectName。接下来,我们通过名称查找对象类型,并将它们一并显示在日志中。
下面是该脚本可能的运行结果(采用缩写形式)。
EURUSD H1 (132358585987782873)
Window 0
OBJ_FIBO H1 Fibo 58513
OBJ_TEXT H1 Text 40688
OBJ_TREND H1 Trendline 3291
OBJ_VLINE H1 Vertical Line 28732
OBJ_VLINE H1 Vertical Line 33752
OBJ_VLINE H1 Vertical Line 35549
Window 1
Window 2
EURUSD D1 (132360375330772909)
Window 0
EURUSD M15 (132544239145024745)
Window 0
OBJ_VLINE H1 Vertical Line 27032
...
XAUUSD D1 (132544239145024746)
Window 0
OBJ_EVENT ObjShow-2021.11.25 00:00:00
OBJ_TEXT ObjShow-2021.11.26 00:00:00
OBJ_ARROW_SELL ObjShow-2021.11.29 00:00:00
OBJ_ARROW_BUY ObjShow-2021.11.30 00:00:00
OBJ_ARROW_RIGHT_PRICE ObjShow-2021.12.01 00:00:00
OBJ_ARROW_LEFT_PRICE ObjShow-2021.12.02 00:00:00
OBJ_ARROW_CHECK ObjShow-2021.12.03 00:00:00
OBJ_ARROW_STOP ObjShow-2021.12.06 00:00:00
OBJ_ARROW_DOWN ObjShow-2021.12.07 00:00:00
OBJ_ARROW_UP ObjShow-2021.12.08 00:00:00
OBJ_ARROW_THUMB_DOWN ObjShow-2021.12.09 00:00:00
OBJ_ARROW_THUMB_UP ObjShow-2021.12.10 00:00:00
OBJ_HLINE ObjShow-2021.12.13 00:00:00
OBJ_VLINE ObjShow-2021.12.14 00:00:00
...
35 objects found
|
特别是,在此处可以看到,XAUUSD, D1 图表上存在由ObjectSimpleShowcase.mq5脚本生成的对象。部分图表和子窗口中没有对象。
int ObjectFind(long chartId, const string name)
该函数在指定标识符的图表上按名称搜索对象,如果成功,则返回其所在窗口编号。
如果未找到对象,该函数将返回负值。与本节前述函数类似,ObjectFind函数采用同步调用方式。
在下一节 ObjectCopy.mq5脚本中,我们将看到该函数的使用示例。