MQL5交易工具(第二部分):为交互式交易助手添加动态视觉反馈·进阶篇
◍ 挂单面板里的矩形配色随校验切换
在 MT5 自定义挂单面板里,REC1 和 REC5 通常分别代表止盈与止损区域,它们的背景色必须跟着订单校验状态走。若底层订单对象失效(例如品种停盘或手数越界),代码会直接把这两个矩形刷成灰色,避免交易者误读成有效挂单位置。 下面这段逻辑先判断 tool_visible,不可见就整体 return,省去无谓的重绘开销;随后用 isOrderValid() 决定配色分支。订单无效时 REC1/REC5 落为 clrGray,悬停时再提亮到 C'100,100,100' 做反馈。 订单有效时,无论 BUY_STOP/BUY_LIMIT 还是其余卖向类型,TP 矩形恒为绿系(悬停 C'0,100,0')、SL 矩形恒为红系(悬停 C'139,0,0');REC3 作为入场块固定浅灰、悬停转 C'105,105,105'。最后一行 ChartRedraw(0) 触发一次重画,鼠标移动才看得见颜色渐变。 外汇与贵金属杠杆高,面板颜色只是辅助提示,不代表挂单必然成交,实际以经纪商回报为准。
class="type">void updateRectangleColors() { if(!tool_visible) class="kw">return; class=class="str">"cmt">//--- Skip if tool is not visible class="type">bool is_valid = isOrderValid(); class=class="str">"cmt">//--- Check order validity if(!is_valid) { class=class="str">"cmt">//--- Gray out REC1 and REC5 if order is invalid, with hover effect ObjectSetInteger(class="num">0, REC1, OBJPROP_BGCOLOR, rec1_hovered ? C&class="macro">#x27;class="num">100,class="num">100,class="num">100&class="macro">#x27; : clrGray); ObjectSetInteger(class="num">0, REC5, OBJPROP_BGCOLOR, rec5_hovered ? C&class="macro">#x27;class="num">100,class="num">100,class="num">100&class="macro">#x27; : clrGray); } else { class=class="str">"cmt">//--- Restore original colors based on order type and hover state if(selected_order_type == "BUY_STOP" || selected_order_type == "BUY_LIMIT") { ObjectSetInteger(class="num">0, REC1, OBJPROP_BGCOLOR, rec1_hovered ? C&class="macro">#x27;class="num">0,class="num">100,class="num">0&class="macro">#x27; : clrGreen); class=class="str">"cmt">//--- TP rectangle(dark green on hover) ObjectSetInteger(class="num">0, REC5, OBJPROP_BGCOLOR, rec5_hovered ? C&class="macro">#x27;class="num">139,class="num">0,class="num">0&class="macro">#x27; : clrRed); class=class="str">"cmt">//--- SL rectangle(dark red on hover) } else { ObjectSetInteger(class="num">0, REC1, OBJPROP_BGCOLOR, rec1_hovered ? C&class="macro">#x27;class="num">0,class="num">100,class="num">0&class="macro">#x27; : clrGreen); class=class="str">"cmt">//--- TP rectangle(dark green on hover) ObjectSetInteger(class="num">0, REC5, OBJPROP_BGCOLOR, rec5_hovered ? C&class="macro">#x27;class="num">139,class="num">0,class="num">0&class="macro">#x27; : clrRed); class=class="str">"cmt">//--- SL rectangle(dark red on hover) } } ObjectSetInteger(class="num">0, REC3, OBJPROP_BGCOLOR, rec3_hovered ? C&class="macro">#x27;class="num">105,class="num">105,class="num">105&class="macro">#x27; : clrLightGray); class=class="str">"cmt">//--- Entry rectangle(darker gray on hover) ChartRedraw(class="num">0); class=class="str">"cmt">//--- Redraw chart } class="type">void updateButtonHoverState(class="type">int mouse_x, class="type">int mouse_y) { class=class="str">"cmt">// Define button names and their properties class="type">class="kw">string buttons[] = {BUY_STOP_BTN, SELL_STOP_BTN, BUY_LIMIT_BTN, SELL_LIMIT_BTN, PLACE_ORDER_BTN, CANCEL_BTN, CLOSE_BTN}; class="type">bool hover_states[] = {buy_stop_hovered, sell_stop_hovered, buy_limit_hovered, sell_limit_hovered, place_order_hovered, cancel_hovered, close_hovered};
按钮与面板的悬停染色逻辑
在 MT5 自定义面板里,悬停反馈不能靠系统自带,得用鼠标坐标和物件坐标做碰撞判定。上面这段把 7 个按钮的常态色写进 normal_colors 数组,绿/砖红交替表达多空倾向,第 5 位 clrDodgerBlue 和第 6 位 clrSlateGray 留给中性功能键,第 7 位 clrCrimson 通常对应危险操作。 核心循环里先取每个按钮的 XDISTANCE、YDISTANCE、XSIZE、YSIZE 四个整数属性,再用 mouse_x/mouse_y 判断是否落在矩形内。进入判定后把背景刷成 hover_color(clrDodgerBlue)、边框刷成 clrBlue,同时把 hover_states[i] 置真,避免下一帧重复触发。 离开时还原用 normal_colors[i] 回填背景,边框统一回到 clrBlack。这里有个细节:标题栏 PANEL_HEADER 单独处理,悬停时背景压到 C'030,030,030'(近黑),移开恢复 C'050,050,050',比按钮暗两档,视觉上能分出层级。 开 MT5 把这段塞进 OnChartEvent 的 CHARTEVENT_MOUSE_MOVE 分支,就能直接看到面板随鼠标变色的实况;外汇与贵金属波动剧烈,这类交互面板只做辅助观察,实际操作仍需自担高风险。
class="type">color normal_colors[] = {clrForestGreen, clrFireBrick, clrForestGreen, clrFireBrick, clrDodgerBlue, clrSlateGray, clrCrimson}; class="type">color hover_color = clrDodgerBlue; class=class="str">"cmt">//--- Bluish class="type">color for hover class="type">color hover_border = clrBlue; class=class="str">"cmt">//--- Bluish border for hover for(class="type">int i = class="num">0; i < ArraySize(buttons); i++) { class="type">int x = (class="type">int)ObjectGetInteger(class="num">0, buttons[i], OBJPROP_XDISTANCE); class="type">int y = (class="type">int)ObjectGetInteger(class="num">0, buttons[i], OBJPROP_YDISTANCE); class="type">int width = (class="type">int)ObjectGetInteger(class="num">0, buttons[i], OBJPROP_XSIZE); class="type">int height = (class="type">int)ObjectGetInteger(class="num">0, buttons[i], OBJPROP_YSIZE); class="type">bool is_hovered = (mouse_x >= x && mouse_x <= x + width && mouse_y >= y && mouse_y <= y + height); if(is_hovered && !hover_states[i]) { class=class="str">"cmt">// Mouse entered button ObjectSetInteger(class="num">0, buttons[i], OBJPROP_BGCOLOR, hover_color); ObjectSetInteger(class="num">0, buttons[i], OBJPROP_BORDER_COLOR, hover_border); hover_states[i] = true; } else if(!is_hovered && hover_states[i]) { class=class="str">"cmt">// Mouse left button ObjectSetInteger(class="num">0, buttons[i], OBJPROP_BGCOLOR, normal_colors[i]); ObjectSetInteger(class="num">0, buttons[i], OBJPROP_BORDER_COLOR, clrBlack); hover_states[i] = false; } } class=class="str">"cmt">// Update header hover state class="type">int header_x = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_XDISTANCE); class="type">int header_y = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_YDISTANCE); class="type">int header_width = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_XSIZE); class="type">int header_height = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_YSIZE); class="type">bool is_header_hovered = (mouse_x >= header_x && mouse_x <= header_x + header_width && mouse_y >= header_y && mouse_y <= header_y + header_height); if(is_header_hovered && !header_hovered) { ObjectSetInteger(class="num">0, PANEL_HEADER, OBJPROP_BGCOLOR, C&class="macro">#x27;class="num">030,class="num">030,class="num">030&class="macro">#x27;); class=class="str">"cmt">//--- Darken header header_hovered = true; } else if(!is_header_hovered && header_hovered) { ObjectSetInteger(class="num">0, PANEL_HEADER, OBJPROP_BGCOLOR, C&class="macro">#x27;class="num">050,class="num">050,class="num">050&class="macro">#x27;); class=class="str">"cmt">//--- Restore header class="type">color header_hovered = false; } class=class="str">"cmt">// Update tool rectangle hover states if(tool_visible) {
「用鼠标坐标判定矩形悬停状态」
在 MT5 的图表事件里做交互面板,核心是先抓出每个矩形对象的屏幕像素边界。上面这段代码对 REC1、REC3、REC5 三个对象分别取了 XDISTANCE、YDISTANCE、XSIZE、YSIZE 四个整数属性,转成 int 后就是对象左上角坐标和宽高。 悬停判定就是最朴素的包围盒测试:mouse_x 落在 [x, x+width] 且 mouse_y 落在 [y, y+height] 内,对应布尔量置真。三个矩形各算各的,互不干扰。 只有当本次悬停状态与上次记录的 rec1_hovered / rec3_hovered / rec5_hovered 任一不同,才调用 updateRectangleColors() 重刷颜色,避免每帧无用重绘。外汇与贵金属杠杆高,这类自定义面板仅用于辅助观测,不改交易决策本身。 后面把 hover_states 数组的 0~6 下标分别赋给 buy_stop_hovered、sell_stop_hovered 等七个状态变量,最后 ChartRedraw(0) 强制重绘。OnChartEvent 的 lparam 和 dparam 在鼠标事件里就是 x、y 坐标,直接拿来做上面的比对即可。
class="type">int x1 = (class="type">int)ObjectGetInteger(class="num">0, REC1, OBJPROP_XDISTANCE); class="type">int y1 = (class="type">int)ObjectGetInteger(class="num">0, REC1, OBJPROP_YDISTANCE); class="type">int width1 = (class="type">int)ObjectGetInteger(class="num">0, REC1, OBJPROP_XSIZE); class="type">int height1 = (class="type">int)ObjectGetInteger(class="num">0, REC1, OBJPROP_YSIZE); class="type">int x3 = (class="type">int)ObjectGetInteger(class="num">0, REC3, OBJPROP_XDISTANCE); class="type">int y3 = (class="type">int)ObjectGetInteger(class="num">0, REC3, OBJPROP_YDISTANCE); class="type">int width3 = (class="type">int)ObjectGetInteger(class="num">0, REC3, OBJPROP_XSIZE); class="type">int height3 = (class="type">int)ObjectGetInteger(class="num">0, REC3, OBJPROP_YSIZE); class="type">int x5 = (class="type">int)ObjectGetInteger(class="num">0, REC5, OBJPROP_XDISTANCE); class="type">int y5 = (class="type">int)ObjectGetInteger(class="num">0, REC5, OBJPROP_YDISTANCE); class="type">int width5 = (class="type">int)ObjectGetInteger(class="num">0, REC5, OBJPROP_XSIZE); class="type">int height5 = (class="type">int)ObjectGetInteger(class="num">0, REC5, OBJPROP_YSIZE); class="type">bool is_rec1_hovered = (mouse_x >= x1 && mouse_x <= x1 + width1 && mouse_y >= y1 && mouse_y <= y1 + height1); class="type">bool is_rec3_hovered = (mouse_x >= x3 && mouse_x <= x3 + width3 && mouse_y >= y3 && mouse_y <= y3 + height3); class="type">bool is_rec5_hovered = (mouse_x >= x5 && mouse_x <= x5 + width5 && mouse_y >= y5 && mouse_y <= y5 + height5); if(is_rec1_hovered != rec1_hovered || is_rec3_hovered != rec3_hovered || is_rec5_hovered != rec5_hovered) { rec1_hovered = is_rec1_hovered; rec3_hovered = is_rec3_hovered; rec5_hovered = is_rec5_hovered; updateRectangleColors(); class=class="str">"cmt">//--- Update colors based on hover state } } class=class="str">"cmt">// Update hover state variables buy_stop_hovered = hover_states[class="num">0]; sell_stop_hovered = hover_states[class="num">1]; buy_limit_hovered = hover_states[class="num">2]; sell_limit_hovered = hover_states[class="num">3]; place_order_hovered = hover_states[class="num">4]; cancel_hovered = hover_states[class="num">5]; close_hovered = hover_states[class="num">6]; ChartRedraw(class="num">0); class=class="str">"cmt">//--- Redraw chart } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert onchart event function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnChartEvent( const class="type">int id, class=class="str">"cmt">//--- Event ID const class="type">long& lparam, class=class="str">"cmt">//--- Long parameter(e.g., x-coordinate for mouse) const class="type">class="kw">double& dparam, class=class="str">"cmt">//--- Double parameter(e.g., y-coordinate for mouse)
◍ 图表按钮点击如何驱动挂单逻辑
在 MT5 自定义面板里,挂单类型不是靠下拉框选的,而是靠图表对象点击事件分流。核心入口是 OnChartEvent 里对 CHARTEVENT_OBJECT_CLICK 的判断:哪个按钮对象名被点中,就给 selected_order_type 赋成对应字符串,并刷新面板文字与矩形配色。
点 BUY_STOP_BTN 就置为 "BUY_STOP",SELL_STOP_BTN 对应 "SELL_STOP",BUY_LIMIT_BTN 与 SELL_LIMIT_BTN 同理。每次赋值后都会调 showTool() 拉出交易工具,并用 update_Text(PLACE_ORDER_BTN, "Place Buy Stop") 之类把确认键文案改成对应方向,视觉上不会点错单。
真正发单只看 PLACE_ORDER_BTN:先跑 isOrderValid() 校验价格结构,通过才 placeOrder() 并清掉辅助对象、回控制面板;不通过就 Print 报出 "Cannot place order: Invalid price setup for " 加当前类型。外汇与贵金属杠杆高,校验失败硬发单可能瞬间扩大回撤,必须让这个函数卡死关口。
把这层点击路由吃透,你就能在 MT5 里自己拼一个纯图表交互的挂单面板,不用再依赖经纪商默认订单窗。
const class="type">class="kw">string& sparam class=class="str">"cmt">//--- String parameter(e.g., object name) ) { if(id == CHARTEVENT_OBJECT_CLICK) { class=class="str">"cmt">//--- Handle object click events class=class="str">"cmt">// Handle order type buttons if(sparam == BUY_STOP_BTN) { class=class="str">"cmt">//--- Check if Buy Stop button clicked selected_order_type = "BUY_STOP"; class=class="str">"cmt">//--- Set order type to Buy Stop showTool(); class=class="str">"cmt">//--- Show trading tool update_Text(PLACE_ORDER_BTN, "Place Buy Stop"); class=class="str">"cmt">//--- Update place order button text updateRectangleColors(); class=class="str">"cmt">//--- Update rectangle colors } else if(sparam == SELL_STOP_BTN) { class=class="str">"cmt">//--- Check if Sell Stop button clicked selected_order_type = "SELL_STOP"; class=class="str">"cmt">//--- Set order type to Sell Stop showTool(); class=class="str">"cmt">//--- Show trading tool update_Text(PLACE_ORDER_BTN, "Place Sell Stop"); class=class="str">"cmt">//--- Update place order button text updateRectangleColors(); class=class="str">"cmt">//--- Update rectangle colors } else if(sparam == BUY_LIMIT_BTN) { class=class="str">"cmt">//--- Check if Buy Limit button clicked selected_order_type = "BUY_LIMIT"; class=class="str">"cmt">//--- Set order type to Buy Limit showTool(); class=class="str">"cmt">//--- Show trading tool update_Text(PLACE_ORDER_BTN, "Place Buy Limit"); class=class="str">"cmt">//--- Update place order button text updateRectangleColors(); class=class="str">"cmt">//--- Update rectangle colors } else if(sparam == SELL_LIMIT_BTN) { class=class="str">"cmt">//--- Check if Sell Limit button clicked selected_order_type = "SELL_LIMIT"; class=class="str">"cmt">//--- Set order type to Sell Limit showTool(); class=class="str">"cmt">//--- Show trading tool update_Text(PLACE_ORDER_BTN, "Place Sell Limit"); class=class="str">"cmt">//--- Update place order button text updateRectangleColors(); class=class="str">"cmt">//--- Update rectangle colors } else if(sparam == PLACE_ORDER_BTN) { class=class="str">"cmt">//--- Check if Place Order button clicked if(isOrderValid()) { placeOrder(); class=class="str">"cmt">//--- Execute order placement deleteObjects(); class=class="str">"cmt">//--- Delete tool objects showPanel(); class=class="str">"cmt">//--- Show control panel } else { Print("Cannot place order: Invalid price setup for ", selected_order_type); } } else if(sparam == CANCEL_BTN) { class=class="str">"cmt">//--- Check if Cancel button clicked
面板拖拽与鼠标事件的底层处理
在 MT5 自定义指标里,控制面板的拖拽体验依赖 CHARTEVENT_MOUSE_MOVE 事件流。当鼠标按键由松开(prevMouseState==0)变为按下(MouseState==1),且坐标落在 PANEL_HEADER 的矩形范围内,才把 panel_dragging 置真,避免误触图表其他区域。 判定范围用的是 OBJPROP_XDISTANCE / YDISTANCE 拿到的面板头左上角坐标,再叠加 XSIZE / YSIZE 算出右和下边界。实测若 header_xs 取错成图表宽度,拖拽热区会覆盖半屏,点按钮容易失灵。 一旦进入拖拽,立即用 ChartSetInteger(0, CHART_MOUSE_SCROLL, false) 关掉图表滚动,否则鼠标移动会带动行情平移,面板反而跟不上。松开后需自行复位该标志,原文未展示松开分支,但逻辑上应与 panel_dragging=false 同步。 点击 Close 按钮的分支里,deleteObjects 与 deletePanel 清场后,必须 ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, false) 注销鼠标事件,不然隐藏面板仍在吃鼠标消息,徒增 CPU 占用。
deleteObjects(); class=class="str">"cmt">//--- Delete tool objects showPanel(); class=class="str">"cmt">//--- Show control panel } else if(sparam == CLOSE_BTN) { class=class="str">"cmt">//--- Check if Close button clicked deleteObjects(); class=class="str">"cmt">//--- Delete tool objects deletePanel(); class=class="str">"cmt">//--- Delete control panel ChartSetInteger(class="num">0, CHART_EVENT_MOUSE_MOVE, false); class=class="str">"cmt">//--- Disable mouse move events } ObjectSetInteger(class="num">0, sparam, OBJPROP_STATE, false); class=class="str">"cmt">//--- Reset button state click ChartRedraw(class="num">0); class=class="str">"cmt">//--- Redraw chart } if(id == CHARTEVENT_MOUSE_MOVE) { class=class="str">"cmt">//--- Handle mouse move events class="type">int MouseD_X = (class="type">int)lparam; class=class="str">"cmt">//--- Get mouse x-coordinate class="type">int MouseD_Y = (class="type">int)dparam; class=class="str">"cmt">//--- Get mouse y-coordinate class="type">int MouseState = (class="type">int)sparam; class=class="str">"cmt">//--- Get mouse state class=class="str">"cmt">// Update button and rectangle hover states updateButtonHoverState(MouseD_X, MouseD_Y); class=class="str">"cmt">// Handle panel dragging class="type">int header_xd = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_XDISTANCE); class="type">int header_yd = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_YDISTANCE); class="type">int header_xs = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_XSIZE); class="type">int header_ys = (class="type">int)ObjectGetInteger(class="num">0, PANEL_HEADER, OBJPROP_YSIZE); if(prevMouseState == class="num">0 && MouseState == class="num">1) { class=class="str">"cmt">//--- Mouse button down if(MouseD_X >= header_xd && MouseD_X <= header_xd + header_xs && MouseD_Y >= header_yd && MouseD_Y <= header_yd + header_ys) { panel_dragging = true; class=class="str">"cmt">//--- Start dragging panel_drag_x = MouseD_X; class=class="str">"cmt">//--- Store mouse x-coordinate panel_drag_y = MouseD_Y; class=class="str">"cmt">//--- Store mouse y-coordinate panel_start_x = header_xd; class=class="str">"cmt">//--- Store panel x-coordinate panel_start_y = header_yd; class=class="str">"cmt">//--- Store panel y-coordinate ChartSetInteger(class="num">0, CHART_MOUSE_SCROLL, false); class=class="str">"cmt">//--- Disable chart scrolling } }
「拖拽时同步刷新挂单面板所有子对象坐标」
面板拖拽的核心逻辑只在鼠标按下且处于拖动态时触发:用当前鼠标位移减去按下瞬间的锚点,得到 dx、dy,再叠加初始坐标算出新的 panel_x / panel_y。 拿到新左上角坐标后,必须逐个把背景、标题栏、关闭钮以及手数编辑框等 14 个 GUI 对象用 ObjectSetInteger 重写 XDISTANCE / YDISTANCE。注意关闭钮相对 panel_x 偏移 209 像素、挂单按钮纵向落在 panel_y+140 与 +180 两排,漏掉任一个对象就会出现「底板动了按钮没动」的脱节。 在 MT5 里把这段接进 OnChartEvent 的鼠标分支,拖动流畅度通常取决于对象数量;若你面板子对象超过 20 个,拖拽时帧率可能从 60 掉到 30 上下,可考虑只在 MouseState==1 的 tick 里批量重绘。外汇与贵金属图表加载此类自定义面板存在滑点及误触高风险,参数偏移量请先在模拟盘核对。
if(panel_dragging && MouseState == class="num">1) { class=class="str">"cmt">//--- Dragging panel class="type">int dx = MouseD_X - panel_drag_x; class=class="str">"cmt">//--- Calculate x displacement class="type">int dy = MouseD_Y - panel_drag_y; class=class="str">"cmt">//--- Calculate y displacement panel_x = panel_start_x + dx; class=class="str">"cmt">//--- Update panel x-position panel_y = panel_start_y + dy; class=class="str">"cmt">//--- Update panel y-position class=class="str">"cmt">// Update all panel objects&class="macro">#x27; positions ObjectSetInteger(class="num">0, PANEL_BG, OBJPROP_XDISTANCE, panel_x); ObjectSetInteger(class="num">0, PANEL_BG, OBJPROP_YDISTANCE, panel_y); ObjectSetInteger(class="num">0, PANEL_HEADER, OBJPROP_XDISTANCE, panel_x); ObjectSetInteger(class="num">0, PANEL_HEADER, OBJPROP_YDISTANCE, panel_y+class="num">2); ObjectSetInteger(class="num">0, CLOSE_BTN, OBJPROP_XDISTANCE, panel_x + class="num">209); ObjectSetInteger(class="num">0, CLOSE_BTN, OBJPROP_YDISTANCE, panel_y + class="num">1); ObjectSetInteger(class="num">0, LOT_EDIT, OBJPROP_XDISTANCE, panel_x + class="num">70); ObjectSetInteger(class="num">0, LOT_EDIT, OBJPROP_YDISTANCE, panel_y + class="num">40); ObjectSetInteger(class="num">0, PRICE_LABEL, OBJPROP_XDISTANCE, panel_x + class="num">10); ObjectSetInteger(class="num">0, PRICE_LABEL, OBJPROP_YDISTANCE, panel_y + class="num">70); ObjectSetInteger(class="num">0, SL_LABEL, OBJPROP_XDISTANCE, panel_x + class="num">10); ObjectSetInteger(class="num">0, SL_LABEL, OBJPROP_YDISTANCE, panel_y + class="num">95); ObjectSetInteger(class="num">0, TP_LABEL, OBJPROP_XDISTANCE, panel_x + class="num">130); ObjectSetInteger(class="num">0, TP_LABEL, OBJPROP_YDISTANCE, panel_y + class="num">95); ObjectSetInteger(class="num">0, BUY_STOP_BTN, OBJPROP_XDISTANCE, panel_x + class="num">10); ObjectSetInteger(class="num">0, BUY_STOP_BTN, OBJPROP_YDISTANCE, panel_y + class="num">140); ObjectSetInteger(class="num">0, SELL_STOP_BTN, OBJPROP_XDISTANCE, panel_x + class="num">130); ObjectSetInteger(class="num">0, SELL_STOP_BTN, OBJPROP_YDISTANCE, panel_y + class="num">140); ObjectSetInteger(class="num">0, BUY_LIMIT_BTN, OBJPROP_XDISTANCE, panel_x + class="num">10); ObjectSetInteger(class="num">0, BUY_LIMIT_BTN, OBJPROP_YDISTANCE, panel_y + class="num">180); ObjectSetInteger(class="num">0, SELL_LIMIT_BTN, OBJPROP_XDISTANCE, panel_x + class="num">130); ObjectSetInteger(class="num">0, SELL_LIMIT_BTN, OBJPROP_YDISTANCE, panel_y + class="num">180);