MQL5交易工具(第四部分):为多周期扫描仪表盘添加动态定位与切换功能·进阶篇
(2/3)· 图表被指标面板占满、切窗口手忙脚乱?这篇教你用代码让仪表盘随手拖、一键收。
多周期面板的格子是怎么排出来的
在 MT5 里手搓一个跨周期信号面板,核心是先算清楚每个表头方块和单元格的屏幕坐标。下面这段逻辑用 panel_x、panel_y 作为面板锚点,WIDTH_TIMEFRAME 和 WIDTH_SIGNAL/WIDTH_INDICATOR 控制列宽,HEIGHT_RECTANGLE 控制行高,靠循环把矩形和文字标签逐个画出来。 表头部分对前 2 列(信号类)和后几列(指标类)用了不同的宽度与偏移算法:header_index<2 时按 SIGNAL 宽度累加,否则从 2*WIDTH_SIGNAL 起跳按 INDICATOR 宽度排。当前图表周期所在的行会被涂成 clrLimeGreen、文字改黑色,其余行灰底白字,一眼能定位自己在哪根时间框架。 单元格背景也分了类:header_index<2(买/卖摘要列)用浅灰,其余指标列用黑底。代码里用 switch 把第 0 列绑 BUY_RECTANGLE/BUY_TEXT、第 1 列绑 SELL_RECTANGLE/SELL_TEXT,后续列留作指标格子。你开 MT5 把下列代码塞进面板初始化函数,调一下 panel_y+35 和 HEIGHT_RECTANGLE 就能看到行列间距的实际渲染效果,外汇贵金属波动快,这类面板仅作辅助、杠杆风险高。
class="type">int x_offset = panel_x - WIDTH_TIMEFRAME - (header_index < class="num">2 ? header_index * WIDTH_SIGNAL : class="num">2 * WIDTH_SIGNAL + (header_index - class="num">2) * WIDTH_INDICATOR) + (class="num">1 + header_index); class=class="str">"cmt">//--- Calculate x position class="type">int width = (header_index < class="num">2 ? WIDTH_SIGNAL : WIDTH_INDICATOR); class=class="str">"cmt">//--- Set width based on header type create_rectangle(HEADER_RECTANGLE + IntegerToString(header_index), x_offset, panel_y + class="num">35, width, HEIGHT_RECTANGLE, clrGray); class=class="str">"cmt">//--- Create header rectangle create_label(HEADER_TEXT + IntegerToString(header_index), header_names[header_index], x_offset - width/class="num">2, panel_y + class="num">45, class="num">11, COLOR_WHITE); class=class="str">"cmt">//--- Create header label } class=class="str">"cmt">// Create timeframe rectangles and labels, and summary/indicator cells for(class="type">int timeframe_index = class="num">0; timeframe_index < ArraySize(timeframes_array); timeframe_index++) { class=class="str">"cmt">//--- Loop through timeframes class=class="str">"cmt">// Highlight current timeframe class="type">class="kw">color timeframe_background = (timeframes_array[timeframe_index] == _Period) ? clrLimeGreen : clrGray; class=class="str">"cmt">//--- Set background class="type">class="kw">color for current timeframe class="type">class="kw">color timeframe_text_color = (timeframes_array[timeframe_index] == _Period) ? COLOR_BLACK : COLOR_WHITE; class=class="str">"cmt">//--- Set text class="type">class="kw">color for current timeframe create_rectangle(TIMEFRAME_RECTANGLE + IntegerToString(timeframe_index), panel_x - class="num">2, (panel_y + class="num">35 + HEIGHT_RECTANGLE) + timeframe_index * HEIGHT_RECTANGLE - (class="num">1 + timeframe_index), WIDTH_TIMEFRAME, HEIGHT_RECTANGLE, timeframe_background); class=class="str">"cmt">//--- Create timeframe rectangle create_label(TIMEFRAME_TEXT + IntegerToString(timeframe_index), truncate_timeframe_name(timeframe_index), panel_x - class="num">47, (panel_y + class="num">45 + HEIGHT_RECTANGLE) + timeframe_index * HEIGHT_RECTANGLE - (class="num">1 + timeframe_index), class="num">11, timeframe_text_color); class=class="str">"cmt">//--- Create timeframe label class=class="str">"cmt">// Create summary and indicator cells for(class="type">int header_index = class="num">0; header_index < ArraySize(header_names); header_index++) { class=class="str">"cmt">//--- Loop through headers for cells class="type">class="kw">string cell_rectangle_name, cell_text_name; class=class="str">"cmt">//--- Declare cell name and label variables class="type">class="kw">color cell_background = (header_index < class="num">2) ? COLOR_LIGHT_GRAY : COLOR_BLACK; class=class="str">"cmt">//--- Set cell background class="type">class="kw">color class="kw">switch(header_index) { class=class="str">"cmt">//--- Select cell type case class="num">0: cell_rectangle_name = BUY_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = BUY_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- Buy cell case class="num">1: cell_rectangle_name = SELL_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = SELL_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- Sell cell
「多周期信号格的命名与坐标落位」
面板里 RSI、Stochastic、CCI、ADX、AO 这几类信号格,靠 switch 里的 case 2~6 来指派对象名。每个格子的矩形与文字对象名都用指标前缀拼接 timeframe_index,这样不同周期的同名指标不会互相覆盖,MT5 对象树里一眼能分清。 x 坐标不是写死的:header_index 小于 2 时按 WIDTH_SIGNAL 步进,否则先占满 2 个信号宽再按 WIDTH_INDICATOR 排指标格,最后补 1+header_index 像素缝隙。高度方向用 panel_y+35 起算,每个 timeframe_index 叠 HEIGHT_RECTANGLE 并回扣 1+index 做 1px 描边补偿。 create_rectangle 调用时格子底色传 cell_background,文字先写死 "-/-" 占位,后面刷数据时再改。标签字号 10、白色,x 偏移取 x_offset - width/2 让文字居左内缩,避免贴边。 最小化面板走另一套:头部矩形宽 617、高 27,底色 C'60,60,60',图标用 Wingdings 的 char 91,关闭钮用 Webdings 'r' 放 x-600,最大化钮用 Wingdings 'o' 放 x-570。整套画完都跟一句 ChartRedraw(0),否则 MT5 上可能看不到即时重绘。
case class="num">2: cell_rectangle_name = RSI_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = RSI_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- RSI cell case class="num">3: cell_rectangle_name = STOCH_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = STOCH_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- Stochastic cell case class="num">4: cell_rectangle_name = CCI_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = CCI_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- CCI cell case class="num">5: cell_rectangle_name = ADX_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = ADX_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- ADX cell case class="num">6: cell_rectangle_name = AO_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = AO_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- AO cell } class="type">int x_offset = panel_x - WIDTH_TIMEFRAME - (header_index < class="num">2 ? header_index * WIDTH_SIGNAL : class="num">2 * WIDTH_SIGNAL + (header_index - class="num">2) * WIDTH_INDICATOR) + (class="num">1 + header_index); class=class="str">"cmt">//--- Calculate x position class="type">int width = (header_index < class="num">2 ? WIDTH_SIGNAL : WIDTH_INDICATOR); class=class="str">"cmt">//--- Set width based on cell type create_rectangle(cell_rectangle_name, x_offset, (panel_y + class="num">35 + HEIGHT_RECTANGLE) + timeframe_index * HEIGHT_RECTANGLE - (class="num">1 + timeframe_index), width, HEIGHT_RECTANGLE, cell_background); class=class="str">"cmt">//--- Create cell rectangle create_label(cell_text_name, "-/-", x_offset - width/class="num">2, (panel_y + class="num">45 + HEIGHT_RECTANGLE) + timeframe_index * HEIGHT_RECTANGLE - (class="num">1 + timeframe_index), class="num">10, COLOR_WHITE); class=class="str">"cmt">//--- Create cell label } } ChartRedraw(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Create minimized dashboard UI | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void create_minimized_dashboard() { create_rectangle(HEADER_PANEL, panel_x, panel_y, class="num">617, class="num">27, C&class="macro">#x27;class="num">60,class="num">60,class="num">60&class="macro">#x27;, BORDER_FLAT); class=class="str">"cmt">//--- Create header panel background create_label(HEADER_PANEL_ICON, CharToString(class="num">91), panel_x - class="num">12, panel_y + class="num">14, class="num">18, clrAqua, "Wingdings"); class=class="str">"cmt">//--- Create header icon create_label(HEADER_PANEL_TEXT, "TimeframeScanner", panel_x - class="num">105, panel_y + class="num">12, class="num">13, COLOR_WHITE); class=class="str">"cmt">//--- Create header title create_label(CLOSE_BUTTON, CharToString(&class="macro">#x27;r&class="macro">#x27;), panel_x - class="num">600, panel_y + class="num">14, class="num">18, clrYellow, "Webdings"); class=class="str">"cmt">//--- Create close button create_label(TOGGLE_BUTTON, CharToString(&class="macro">#x27;o&class="macro">#x27;), panel_x - class="num">570, panel_y + class="num">14, class="num">18, clrYellow, "Wingdings"); class=class="str">"cmt">//--- Create maximize button(+) ChartRedraw(class="num">0); }
◍ 清盘时如何干净拆除仪表盘
做多品种监控面板最怕卸载脚本后留下一堆孤儿对象,图表上飘着看不见点击区的矩形和文字,下次加载直接重名冲突。下面这段清理函数把面板拆得比较彻底:先按名字逐个删主控件,再用前缀批量删动态生成的标签。 ObjectDelete 针对的是编译期写死的 6 个控件——主面板、表头、图标、标题、关闭与折叠按钮,每个都靠唯一常量名定位。剩下的 10 类用 ObjectsDeleteAll 按前缀 SYMBOL_ / TIMEFRAME_ / HEADER_ / RSI_ / STOCH_ 成组清除,覆盖矩形和文字两套对象,合计 16 行调用。 在 MT5 里跑 EA 或指标前,建议先把这段挂到 OnDeinit 里。外汇与贵金属波动剧烈、高风险,图表对象堆积会拖慢终端响应,清干净再重载参数才不容易出鬼影。
class="type">void delete_all_objects() { ObjectDelete(class="num">0, MAIN_PANEL); class=class="str">"cmt">//--- Delete main panel ObjectDelete(class="num">0, HEADER_PANEL); class=class="str">"cmt">//--- Delete header panel ObjectDelete(class="num">0, HEADER_PANEL_ICON); class=class="str">"cmt">//--- Delete header icon ObjectDelete(class="num">0, HEADER_PANEL_TEXT); class=class="str">"cmt">//--- Delete header title ObjectDelete(class="num">0, CLOSE_BUTTON); class=class="str">"cmt">//--- Delete close button ObjectDelete(class="num">0, TOGGLE_BUTTON); class=class="str">"cmt">//--- Delete toggle button ObjectsDeleteAll(class="num">0, SYMBOL_RECTANGLE); class=class="str">"cmt">//--- Delete all symbol rectangles ObjectsDeleteAll(class="num">0, SYMBOL_TEXT); class=class="str">"cmt">//--- Delete all symbol labels ObjectsDeleteAll(class="num">0, TIMEFRAME_RECTANGLE); class=class="str">"cmt">//--- Delete all timeframe rectangles ObjectsDeleteAll(class="num">0, TIMEFRAME_TEXT); class=class="str">"cmt">//--- Delete all timeframe labels ObjectsDeleteAll(class="num">0, HEADER_RECTANGLE); class=class="str">"cmt">//--- Delete all header rectangles ObjectsDeleteAll(class="num">0, HEADER_TEXT); class=class="str">"cmt">//--- Delete all header labels ObjectsDeleteAll(class="num">0, RSI_RECTANGLE); class=class="str">"cmt">//--- Delete all RSI rectangles ObjectsDeleteAll(class="num">0, RSI_TEXT); class=class="str">"cmt">//--- Delete all RSI labels ObjectsDeleteAll(class="num">0, STOCH_RECTANGLE); class=class="str">"cmt">//--- Delete all Stochastic rectangles ObjectsDeleteAll(class="num">0, STOCH_TEXT); class=class="str">"cmt">//--- Delete all Stochastic labels }
清场与面板重定位的底层调用
指标或 EA 在重绘前必须先把旧图形对象清干净,否则 MT5 图表会堆叠上一轮留下的矩形和文字标签。下面这段用 ObjectsDeleteAll 按前缀分组删除,CCI、ADX、AO 三类指标区加上买卖信号区,各自矩形与文字分开清,共 10 次调用覆盖全部面板元素。 清场之后紧接着是 update_panel_positions 函数,它用 ObjectSetInteger 改写对象的 OBJPROP_XDISTANCE 与 OBJPROP_YDISTANCE 来重定位。注意 header 图标 x 坐标是 panel_x - 12,标题文字却是 panel_x - 105,关闭按钮更拉到 panel_x - 600,这种非对称偏移说明面板各部件并非等距排列,而是按视觉锚点硬编码。 外汇与贵金属图表上跑这类面板脚本,高风险在于对象 ID 前缀若与其他指标冲突,ObjectsDeleteAll 可能误删别家物件;实盘前建议在策略测试器里先挂一个货币对验证删除范围。
ObjectsDeleteAll(class="num">0, CCI_RECTANGLE); class=class="str">"cmt">//--- Delete all CCI rectangles ObjectsDeleteAll(class="num">0, CCI_TEXT); class=class="str">"cmt">//--- Delete all CCI labels ObjectsDeleteAll(class="num">0, ADX_RECTANGLE); class=class="str">"cmt">//--- Delete all ADX rectangles ObjectsDeleteAll(class="num">0, ADX_TEXT); class=class="str">"cmt">//--- Delete all ADX labels ObjectsDeleteAll(class="num">0, AO_RECTANGLE); class=class="str">"cmt">//--- Delete all AO rectangles ObjectsDeleteAll(class="num">0, AO_TEXT); class=class="str">"cmt">//--- Delete all AO labels ObjectsDeleteAll(class="num">0, BUY_RECTANGLE); class=class="str">"cmt">//--- Delete all buy rectangles ObjectsDeleteAll(class="num">0, BUY_TEXT); class=class="str">"cmt">//--- Delete all buy labels ObjectsDeleteAll(class="num">0, SELL_RECTANGLE); class=class="str">"cmt">//--- Delete all sell rectangles ObjectsDeleteAll(class="num">0, SELL_TEXT); class=class="str">"cmt">//--- Delete all sell labels } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Update panel object positions | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void update_panel_positions() { class=class="str">"cmt">// Update header and buttons ObjectSetInteger(class="num">0, HEADER_PANEL, OBJPROP_XDISTANCE, panel_x); class=class="str">"cmt">//--- Set header panel x position ObjectSetInteger(class="num">0, HEADER_PANEL, OBJPROP_YDISTANCE, panel_y); class=class="str">"cmt">//--- Set header panel y position ObjectSetInteger(class="num">0, HEADER_PANEL_ICON, OBJPROP_XDISTANCE, panel_x - class="num">12); class=class="str">"cmt">//--- Set header icon x position ObjectSetInteger(class="num">0, HEADER_PANEL_ICON, OBJPROP_YDISTANCE, panel_y + class="num">14); class=class="str">"cmt">//--- Set header icon y position ObjectSetInteger(class="num">0, HEADER_PANEL_TEXT, OBJPROP_XDISTANCE, panel_x - class="num">105); class=class="str">"cmt">//--- Set header title x position ObjectSetInteger(class="num">0, HEADER_PANEL_TEXT, OBJPROP_YDISTANCE, panel_y + class="num">12); class=class="str">"cmt">//--- Set header title y position ObjectSetInteger(class="num">0, CLOSE_BUTTON, OBJPROP_XDISTANCE, panel_x - class="num">600); class=class="str">"cmt">//--- Set close button x position
「面板坐标的逐对象刷新逻辑」
在 MT5 自定义面板里,所有图形对象的位置都靠 ObjectSetInteger 配合 OBJPROP_XDISTANCE / OBJPROP_YDISTANCE 来重算。上面这段只处理未最小化状态:关闭按钮和折叠按钮的 Y 偏移固定为 panel_y+14,而折叠按钮的 X 直接锁在 panel_x-570,意味着它始终贴在面板左侧外部 570 像素处。 主面板本体与符号区是分开刷的。MAIN_PANEL 用 panel_x / panel_y 原值,SYMBOL_RECTANGLE 则取 panel_x-2 与 panel_y+35,SYMBOL_TEXT 再往左挪到 panel_x-47、下沉到 panel_y+45,形成符号框与文字的层叠错位。 表头循环是这段最易算错的地方。header_names 有 7 项(BUY/SELL/RSI/STOCH/CCI/ADX/AO),前两项按 WIDTH_SIGNAL 步进、后五项按 WIDTH_INDICATOR 步进,x_offset 里还夹了 (1+header_index) 的 1 像素缝隙补偿。若你改了 WIDTH_SIGNAL 或 WIDTH_INDICATOR 的宏定义,必须同步核对这里,否则表头会重叠或留出怪缝。 外汇与贵金属图表上挂这类面板属于高频重绘操作,过多 ObjectSetInteger 调用在 tick 级刷新时可能拖慢终端;建议仅在参数变更或定时器触发时跑这段,而非每笔报价都重排。
ObjectSetInteger(class="num">0, CLOSE_BUTTON, OBJPROP_YDISTANCE, panel_y + class="num">14); class=class="str">"cmt">//--- Set close button y position ObjectSetInteger(class="num">0, TOGGLE_BUTTON, OBJPROP_XDISTANCE, panel_x - class="num">570); class=class="str">"cmt">//--- Set toggle button x position ObjectSetInteger(class="num">0, TOGGLE_BUTTON, OBJPROP_YDISTANCE, panel_y + class="num">14); class=class="str">"cmt">//--- Set toggle button y position if (!panel_minimized) { class=class="str">"cmt">// Update main panel ObjectSetInteger(class="num">0, MAIN_PANEL, OBJPROP_XDISTANCE, panel_x); class=class="str">"cmt">//--- Set main panel x position ObjectSetInteger(class="num">0, MAIN_PANEL, OBJPROP_YDISTANCE, panel_y); class=class="str">"cmt">//--- Set main panel y position class=class="str">"cmt">// Update symbol rectangle and label ObjectSetInteger(class="num">0, SYMBOL_RECTANGLE, OBJPROP_XDISTANCE, panel_x - class="num">2); class=class="str">"cmt">//--- Set symbol rectangle x position ObjectSetInteger(class="num">0, SYMBOL_RECTANGLE, OBJPROP_YDISTANCE, panel_y + class="num">35); class=class="str">"cmt">//--- Set symbol rectangle y position ObjectSetInteger(class="num">0, SYMBOL_TEXT, OBJPROP_XDISTANCE, panel_x - class="num">47); class=class="str">"cmt">//--- Set symbol text x position ObjectSetInteger(class="num">0, SYMBOL_TEXT, OBJPROP_YDISTANCE, panel_y + class="num">45); class=class="str">"cmt">//--- Set symbol text y position class=class="str">"cmt">// Update header rectangles and labels class="type">class="kw">string header_names[] = {"BUY", "SELL", "RSI", "STOCH", "CCI", "ADX", "AO"}; for(class="type">int header_index = class="num">0; header_index < ArraySize(header_names); header_index++) { class=class="str">"cmt">//--- Loop through headers class="type">int x_offset = panel_x - WIDTH_TIMEFRAME - (header_index < class="num">2 ? header_index * WIDTH_SIGNAL : class="num">2 * WIDTH_SIGNAL + (header_index - class="num">2) * WIDTH_INDICATOR) + (class="num">1 + header_index); class=class="str">"cmt">//--- Calculate x position ObjectSetInteger(class="num">0, HEADER_RECTANGLE + IntegerToString(header_index), OBJPROP_XDISTANCE, x_offset); class=class="str">"cmt">//--- Set header rectangle x position ObjectSetInteger(class="num">0, HEADER_RECTANGLE + IntegerToString(header_index), OBJPROP_YDISTANCE, panel_y + class="num">35); class=class="str">"cmt">//--- Set header rectangle y position ObjectSetInteger(class="num">0, HEADER_TEXT + IntegerToString(header_index), OBJPROP_XDISTANCE, x_offset - (header_index < class="num">2 ? WIDTH_SIGNAL/class="num">2 : WIDTH_INDICATOR/class="num">2)); class=class="str">"cmt">//--- Set header text x position ObjectSetInteger(class="num">0, HEADER_TEXT + IntegerToString(header_index), OBJPROP_YDISTANCE, panel_y + class="num">45); class=class="str">"cmt">//--- Set header text y position } class=class="str">"cmt">// Update timeframe rectangles, labels, and cells for(class="type">int timeframe_index = class="num">0; timeframe_index < ArraySize(timeframes_array); timeframe_index++) { class=class="str">"cmt">//--- Loop through timeframes
◍ 把多周期面板的坐标落进对象属性
这段逻辑负责把面板里每一行(对应一个 timeframe_index)的矩形和文字按像素距离摆正。y_offset 以 panel_y 为基准,加上 35 像素顶距与行高 HEIGHT_RECTANGLE,再按 timeframe_index 逐行下移,减去 (1 + timeframe_index) 做 1px 像素纠偏,避免 MT5 对象坐标累计漂移。 时间框架标签本身用 OBJPROP_XDISTANCE / OBJPROP_YDISTANCE 写入:矩形左边距 panel_x - 2,文字左边距 panel_x - 47、上边距比矩形多 10px,肉眼看是标签左对齐贴在行首。 内层 for 循环遍历 header_names 数组(长度由 ArraySize 决定,本例为 7:买、卖、RSI、Stoch、CCI、ADX、AO),用 switch 给每种单元格拼出独立对象名(如 BUY_RECTANGLE+序号)。x_offset 的计算区分了前 two 列信号列(WIDTH_SIGNAL)与后五列指标列(WIDTH_INDICATOR),公式里 + (1 + header_index) 同样是 1px 级修正。 开 MT5 把这段塞进你面板的绘制函数,改 HEIGHT_RECTANGLE 或 WIDTH_INDICATOR 数值,就能直接看到行距和列宽变化;外汇与贵金属品种波动大,面板刷新频率过高可能拖累终端响应,调参时留意资源占用。
class="type">int y_offset = (panel_y + class="num">35 + HEIGHT_RECTANGLE) + timeframe_index * HEIGHT_RECTANGLE - (class="num">1 + timeframe_index); class=class="str">"cmt">//--- Calculate y position ObjectSetInteger(class="num">0, TIMEFRAME_RECTANGLE + IntegerToString(timeframe_index), OBJPROP_XDISTANCE, panel_x - class="num">2); class=class="str">"cmt">//--- Set timeframe rectangle x position ObjectSetInteger(class="num">0, TIMEFRAME_RECTANGLE + IntegerToString(timeframe_index), OBJPROP_YDISTANCE, y_offset); class=class="str">"cmt">//--- Set timeframe rectangle y position ObjectSetInteger(class="num">0, TIMEFRAME_TEXT + IntegerToString(timeframe_index), OBJPROP_XDISTANCE, panel_x - class="num">47); class=class="str">"cmt">//--- Set timeframe text x position ObjectSetInteger(class="num">0, TIMEFRAME_TEXT + IntegerToString(timeframe_index), OBJPROP_YDISTANCE, y_offset + class="num">10); class=class="str">"cmt">//--- Set timeframe text y position for(class="type">int header_index = class="num">0; header_index < ArraySize(header_names); header_index++) { class=class="str">"cmt">//--- Loop through cells class="type">class="kw">string cell_rectangle_name, cell_text_name; class="kw">switch(header_index) { class=class="str">"cmt">//--- Select cell type case class="num">0: cell_rectangle_name = BUY_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = BUY_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- Buy cell case class="num">1: cell_rectangle_name = SELL_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = SELL_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- Sell cell case class="num">2: cell_rectangle_name = RSI_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = RSI_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- RSI cell case class="num">3: cell_rectangle_name = STOCH_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = STOCH_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- Stochastic cell case class="num">4: cell_rectangle_name = CCI_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = CCI_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- CCI cell case class="num">5: cell_rectangle_name = ADX_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = ADX_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- ADX cell case class="num">6: cell_rectangle_name = AO_RECTANGLE + IntegerToString(timeframe_index); cell_text_name = AO_TEXT + IntegerToString(timeframe_index); class="kw">break; class=class="str">"cmt">//--- AO cell } class="type">int x_offset = panel_x - WIDTH_TIMEFRAME - (header_index < class="num">2 ? header_index * WIDTH_SIGNAL : class="num">2 * WIDTH_SIGNAL + (header_index - class="num">2) * WIDTH_INDICATOR) + (class="num">1 + header_index); class=class="str">"cmt">//--- Calculate x position