图表对象

图表对象 OBJ_CHART 允许在图表内部为其他金融工具和时间范围创建缩略图。图表对象包含在常规 图表列表中,我们可以使用 ChartFirstChartNext 函数以编程方式获得。正如 检查主窗口状态章节所述,特殊图表特性 CHART_IS_OBJECT 可通过标识符判断该图表是完整窗口还是图表对象。在后一种情况下,调用 ChartGetInteger(id, CHART_IS_OBJECT)将返回 true

图表对象具有一组专属特性集。

标识符

说明

类型

OBJPROP_CHART_ID

图表 ID(只读)

long

OBJPROP_PERIOD

图表周期

ENUM_TIMEFRAMES

OBJPROP_DATE_SCALE

显示时间轴

bool

OBJPROP_PRICE_SCALE

显示价格轴

bool

OBJPROP_CHART_SCALE

缩放比例(值的范围是 0-5)

int

OBJPROP_SYMBOL

交易品种

string

通过 OBJPROP_CHART_ID 特性获取的标识符,允许使用 处理图表章节中的函数像管理常规图表一样管理该对象。但存在一些限制:

默认情况下,所有特性(除 OBJPROP_CHART_ID 外)均与当前窗口的对应特性一致。

图表对象的演示通过无缓冲指标ObjectChart.mq5实现。该指标会创建一个子窗口,其中包含两个图表对象,这两个对象显示与当前图表相同交易品种,但时间周期分别为当前时间范围的上一范围和下一范围。

对象会吸附到子窗口的右上角,并具有相同的预设尺寸:

#define SUBCHART_HEIGHT 150
#define SUBCHART_WIDTH  200

当然,子窗口的高度必须与对象高度匹配,直到能够自适应地响应尺寸调整事件。

#property indicator_separate_window
#property indicator_height SUBCHART_HEIGHT
#property indicator_buffers 0
#property indicator_plots   0

SetupSubChart函数中配置了一个迷你图表,该函数将对象编号、对象尺寸和所需时间范围作为输入。SetupSubChart函数的执行结果是图表对象的标识符,我们仅将其输出到日志中以供参考。

void OnInit()
{
   Print(SetupSubChart(0SUBCHART_WIDTHSUBCHART_HEIGHTPeriodUp(_Period)));
   Print(SetupSubChart(1SUBCHART_WIDTHSUBCHART_HEIGHTPeriodDown(_Period)));
}

PeriodUpPeriodDown 使用辅助函数 PeriodRelative

#define PeriodUp(PPeriodRelative(P, +1)
#define PeriodDown(PPeriodRelative(P, -1)
   
ENUM_TIMEFRAMES PeriodRelative(const ENUM_TIMEFRAMES tfconst int step)
{
   static const ENUM_TIMEFRAMES stdtfs[] =
   {
      PERIOD_M1,  // =1 (1)
      PERIOD_M2,  // =2 (2)
      ...
      PERIOD_W1,  // =32769 (8001)
      PERIOD_MN1// =49153 (C001)
   };
   const int x = ArrayBsearch(stdtfstf == PERIOD_CURRENT ? _Period : tf);
   const int needle = x + step;
   if(needle >= 0 && needle < ArraySize(stdtfs))
   {
      return stdtfs[needle];
   }
   return tf;
}

下面是主要工作函数 SetupSubChart

long SetupSubChart(const int nconst int dxconst int dy,
   ENUM_TIMEFRAMES tf = PERIOD_CURRENTconst string symbol = NULL)
{
   // create an object
   const string name = Prefix + "Chart-"
      + (symbol == NULL ? _Symbol : symbol) + PeriodToString(tf);
   ObjectCreate(0nameOBJ_CHARTChartWindowFind(), 00);
   
   // anchor to the top right corner of the subwindow
   ObjectSetInteger(0nameOBJPROP_CORNERCORNER_RIGHT_UPPER);
   // position and size
   ObjectSetInteger(0nameOBJPROP_XSIZEdx);
   ObjectSetInteger(0nameOBJPROP_YSIZEdy);
   ObjectSetInteger(0nameOBJPROP_XDISTANCE, (n + 1) * dx);
   ObjectSetInteger(0nameOBJPROP_YDISTANCE0);
   
   // specific chart settings
   if(symbol != NULL)
   {
      ObjectSetString(0nameOBJPROP_SYMBOLsymbol);
   }
   
   if(tf != PERIOD_CURRENT)
   {
      ObjectSetInteger(0nameOBJPROP_PERIODtf);
   }
   // disable the display of lines
   ObjectSetInteger(0nameOBJPROP_DATE_SCALEfalse);
   ObjectSetInteger(0nameOBJPROP_PRICE_SCALEfalse);
   // add the MA indicator to the object by its id just for demo
   const long id = ObjectGetInteger(0nameOBJPROP_CHART_ID);
   ChartIndicatorAdd(id0iMA(NULLtf100MODE_EMAPRICE_CLOSE));
   return id;
}

对于图表对象,锚点始终固定在对象的左上角,因此当锚定到窗口的右角时,需要添加对象的宽度(这通过在 OBJPROP_XDISTANCE 的表达式 (n+1)*dx中执行 +1 操作来实现)。

下图展示了该指标在 XAUUSD,H1 图表上的运行结果。

指标子窗口中的两个图表对象

指标子窗口中的两个图表对象

可以看到,迷你图表显示 M30 和 H2 时间范围。

需要特别注意,可以向图表对象添加指标并应用 tpl 模板,包括带 EA 交易的模板。但无法在图表对象内部创建对象。

当图表对象因当前时间范围或全部时间范围禁用可视化而被隐藏时,其内部图表的 CHART_WINDOW_IS_VISIBLE 特性仍会返回 true