黄金固定止盈止损交易面板
图形界面快速下单,固定点数止盈止损,一键平仓,实时显示持仓盈亏
MT5 真机运行截图 · 服务器把编译好的 EX5 挂到黄金 H1 图表上截的,你装上去看到的就是这个样子
#property copyright "XAUOF指标工坊"
#property version "1.00"
#include <Trade\Trade.mqh>
// ========== 可调参数 ==========
input double Lots = 0.1; // 每单手数
input int TakeProfitPoints = 500; // 止盈点数(500点=50美元)
input int StopLossPoints = 300; // 止损点数(300点=30美元)
input int MagicNumber = 888888; // EA魔术号(区分不同EA的单子)
input int Slippage = 30; // 允许滑点(点数)
// ========== 全局变量 ==========
CTrade trade;
// 面板控件名称前缀
string prefix = "Panel_";
// 面板位置和尺寸
int panelX = 10;
int panelY = 30;
int panelWidth = 250;
int panelHeight = 280;
int buttonWidth = 110;
int buttonHeight = 35;
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(Slippage);
trade.SetTypeFilling(ORDER_FILLING_FOK);
// 创建交易面板
CreatePanel();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 删除所有面板对象
ObjectsDeleteAll(0, prefix);
ChartRedraw();
}
//+------------------------------------------------------------------+
//| 每个tick执行 |
//+------------------------------------------------------------------+
void OnTick()
{
// 更新面板显示信息
UpdatePanelInfo();
}
//+------------------------------------------------------------------+
//| 图表事件处理 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
// 处理按钮点击事件
if(id == CHARTEVENT_OBJECT_CLICK)
{
// BUY按钮
if(sparam == prefix + "BtnBuy")
{
OpenBuy();
ObjectSetInteger(0, sparam, OBJPROP_STATE, false); // 恢复按钮状态
}
// SELL按钮
if(sparam == prefix + "BtnSell")
{
OpenSell();
ObjectSetInteger(0, sparam, OBJPROP_STATE, false);
}
// 平仓按钮
if(sparam == prefix + "BtnClose")
{
CloseAllPositions();
ObjectSetInteger(0, sparam, OBJPROP_STATE, false);
}
ChartRedraw();
}
}
//+------------------------------------------------------------------+
//| 创建交易面板 |
//+------------------------------------------------------------------+
void CreatePanel()
{
// 1. 背景面板
ObjectCreate(0, prefix + "Background", OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "Background", OBJPROP_XDISTANCE, panelX);
ObjectSetInteger(0, prefix + "Background", OBJPROP_YDISTANCE, panelY);
ObjectSetInteger(0, prefix + "Background", OBJPROP_XSIZE, panelWidth);
ObjectSetInteger(0, prefix + "Background", OBJPROP_YSIZE, panelHeight);
ObjectSetInteger(0, prefix + "Background", OBJPROP_BGCOLOR, clrDarkSlateGray);
ObjectSetInteger(0, prefix + "Background", OBJPROP_BORDER_TYPE, BORDER_FLAT);
ObjectSetInteger(0, prefix + "Background", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "Background", OBJPROP_BACK, false);
// 2. 标题
ObjectCreate(0, prefix + "Title", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "Title", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "Title", OBJPROP_YDISTANCE, panelY + 8);
ObjectSetInteger(0, prefix + "Title", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "Title", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, prefix + "Title", OBJPROP_FONTSIZE, 11);
ObjectSetString(0, prefix + "Title", OBJPROP_FONT, "Arial Black");
ObjectSetString(0, prefix + "Title", OBJPROP_TEXT, "黄金交易面板");
// 3. 参数信息标签
int labelY = panelY + 40;
ObjectCreate(0, prefix + "LabelLots", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "LabelLots", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "LabelLots", OBJPROP_YDISTANCE, labelY);
ObjectSetInteger(0, prefix + "LabelLots", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "LabelLots", OBJPROP_COLOR, clrYellow);
ObjectSetInteger(0, prefix + "LabelLots", OBJPROP_FONTSIZE, 9);
ObjectSetString(0, prefix + "LabelLots", OBJPROP_FONT, "Arial");
ObjectSetString(0, prefix + "LabelLots", OBJPROP_TEXT, "手数: " + DoubleToString(Lots, 2));
labelY += 20;
ObjectCreate(0, prefix + "LabelTP", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "LabelTP", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "LabelTP", OBJPROP_YDISTANCE, labelY);
ObjectSetInteger(0, prefix + "LabelTP", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "LabelTP", OBJPROP_COLOR, clrLime);
ObjectSetInteger(0, prefix + "LabelTP", OBJPROP_FONTSIZE, 9);
ObjectSetString(0, prefix + "LabelTP", OBJPROP_FONT, "Arial");
ObjectSetString(0, prefix + "LabelTP", OBJPROP_TEXT, "止盈: " + IntegerToString(TakeProfitPoints) + " 点");
labelY += 20;
ObjectCreate(0, prefix + "LabelSL", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "LabelSL", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "LabelSL", OBJPROP_YDISTANCE, labelY);
ObjectSetInteger(0, prefix + "LabelSL", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "LabelSL", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, prefix + "LabelSL", OBJPROP_FONTSIZE, 9);
ObjectSetString(0, prefix + "LabelSL", OBJPROP_FONT, "Arial");
ObjectSetString(0, prefix + "LabelSL", OBJPROP_TEXT, "止损: " + IntegerToString(StopLossPoints) + " 点");
// 4. BUY按钮
int btnY = panelY + 110;
ObjectCreate(0, prefix + "BtnBuy", OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_YDISTANCE, btnY);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_XSIZE, buttonWidth);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_YSIZE, buttonHeight);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_BGCOLOR, clrGreen);
ObjectSetInteger(0, prefix + "BtnBuy", OBJPROP_FONTSIZE, 12);
ObjectSetString(0, prefix + "BtnBuy", OBJPROP_FONT, "Arial Black");
ObjectSetString(0, prefix + "BtnBuy", OBJPROP_TEXT, "BUY 做多");
// 5. SELL按钮
ObjectCreate(0, prefix + "BtnSell", OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_XDISTANCE, panelX + 130);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_YDISTANCE, btnY);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_XSIZE, buttonWidth);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_YSIZE, buttonHeight);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_BGCOLOR, clrCrimson);
ObjectSetInteger(0, prefix + "BtnSell", OBJPROP_FONTSIZE, 12);
ObjectSetString(0, prefix + "BtnSell", OBJPROP_FONT, "Arial Black");
ObjectSetString(0, prefix + "BtnSell", OBJPROP_TEXT, "SELL 做空");
// 6. 平仓按钮
btnY += 45;
ObjectCreate(0, prefix + "BtnClose", OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_YDISTANCE, btnY);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_XSIZE, panelWidth - 20);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_YSIZE, buttonHeight);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_BGCOLOR, clrOrangeRed);
ObjectSetInteger(0, prefix + "BtnClose", OBJPROP_FONTSIZE, 11);
ObjectSetString(0, prefix + "BtnClose", OBJPROP_FONT, "Arial Black");
ObjectSetString(0, prefix + "BtnClose", OBJPROP_TEXT, "一键平仓");
// 7. 账户信息标签(动态更新)
int infoY = btnY + 50;
ObjectCreate(0, prefix + "InfoBalance", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "InfoBalance", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "InfoBalance", OBJPROP_YDISTANCE, infoY);
ObjectSetInteger(0, prefix + "InfoBalance", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "InfoBalance", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, prefix + "InfoBalance", OBJPROP_FONTSIZE, 8);
ObjectSetString(0, prefix + "InfoBalance", OBJPROP_FONT, "Arial");
infoY += 18;
ObjectCreate(0, prefix + "InfoEquity", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "InfoEquity", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "InfoEquity", OBJPROP_YDISTANCE, infoY);
ObjectSetInteger(0, prefix + "InfoEquity", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "InfoEquity", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, prefix + "InfoEquity", OBJPROP_FONTSIZE, 8);
ObjectSetString(0, prefix + "InfoEquity", OBJPROP_FONT, "Arial");
infoY += 18;
ObjectCreate(0, prefix + "InfoPositions", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, prefix + "InfoPositions", OBJPROP_XDISTANCE, panelX + 10);
ObjectSetInteger(0, prefix + "InfoPositions", OBJPROP_YDISTANCE, infoY);
ObjectSetInteger(0, prefix + "InfoPositions", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, prefix + "InfoPositions", OBJPROP_COLOR, clrAqua);
ObjectSetInteger(0, prefix + "InfoPositions", OBJPROP_FONTSIZE, 8);
ObjectSetString(0, prefix + "InfoPositions", OBJPROP_FONT, "Arial");
ChartRedraw();
}
//+------------------------------------------------------------------+
//| 更新面板信息 |
//+------------------------------------------------------------------+
void UpdatePanelInfo()
{
// 账户余额
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
ObjectSetString(0, prefix + "InfoBalance", OBJPROP_TEXT, "余额: $" + DoubleToString(balance, 2));
// 账户净值
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
ObjectSetString(0, prefix + "InfoEquity", OBJPROP_TEXT, "净值: $" + DoubleToString(equity, 2));
// 持仓统计
int totalPos = 0;
double totalProfit = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket > 0)
{
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber)
{
totalPos++;
totalProfit += PositionGetDouble(POSITION_PROFIT);
}
}
}
string profitText = (totalProfit >= 0) ? "+" : "";
color profitColor = (totalProfit >= 0) ? clrLime : clrRed;
ObjectSetString(0, prefix + "InfoPositions", OBJPROP_TEXT,
"持仓: " + IntegerToString(totalPos) + " 单 盈亏: " + profitText + DoubleToString(totalProfit, 2));
ObjectSetInteger(0, prefix + "InfoPositions", OBJPROP_COLOR, profitColor);
}
//+------------------------------------------------------------------+
//| 开多单 |
//+------------------------------------------------------------------+
void OpenBuy()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = (StopLossPoints > 0) ? ask - StopLossPoints * _Point : 0;
double tp = (TakeProfitPoints > 0) ? ask + TakeProfitPoints * _Point : 0;
if(trade.Buy(Lots, _Symbol, ask, sl, tp, "Panel Buy"))
{
Print("做多成功,单号: ", trade.ResultOrder());
}
else
{
Print("做多失败,错误码: ", trade.ResultRetcode());
}
}
//+------------------------------------------------------------------+
//| 开空单 |
//+------------------------------------------------------------------+
void OpenSell()
{
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = (StopLossPoints > 0) ? bid + StopLossPoints * _Point : 0;
double tp = (TakeProfitPoints > 0) ? bid - TakeProfitPoints * _Point : 0;
if(trade.Sell(Lots, _Symbol, bid, sl, tp, "Panel Sell"))
{
Print("做空成功,单号: ", trade.ResultOrder());
}
else
{
Print("做空失败,错误码: ", trade.ResultRetcode());
}
}
//+------------------------------------------------------------------+
//| 平掉所有本EA的持仓 |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
int closed = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket > 0)
{
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber)
{
if(trade.PositionClose(ticket))
{
closed++;
Print("平仓成功,单号: ", ticket);
}
else
{
Print("平仓失败,单号: ", ticket, " 错误码: ", trade.ResultRetcode());
}
}
}
}
if(closed > 0)
{
Print("共平仓 ", closed, " 单");
}
else
{
Print("当前无持仓");
}
}作品说明
这是一个带图形界面的EA交易面板,固定在图表左上角。用户可以设置手数、固定止盈止损点数,点击BUY/SELL按钮快速下单,点击平仓按钮一键平掉所有持仓。面板实时显示当前账户余额、净值、持仓数量和浮动盈亏,方便盯盘交易。
使用说明
- 安装:把代码保存为 GoldTradingPanel.mq5,放到 MT5 的 Experts 文件夹,编译后拖到黄金图表上,在弹出窗口里勾选"允许自动交易"。
- 参数设置:装载时可以调整手数(Lots)、止盈点数(TakeProfitPoints)、止损点数(StopLossPoints)。黄金 500 点约等于 50 美元盈亏,300 点约 30 美元。
- 下单操作:点击绿色"BUY 做多"按钮开多单,点击红色"SELL 做空"按钮开空单,每单自动带上设定的止盈止损。
- 平仓操作:点击橙色"一键平仓"按钮,立即平掉当前图表上本 EA 魔术号的所有持仓。
- 实时监控:面板底部实时显示账户余额、净值、当前持仓数和总浮动盈亏,盈利显示绿色,亏损显示红色。
- 魔术号隔离:MagicNumber 参数用于区分不同 EA 的单子,不同图表可以装不同魔术号的面板互不干扰。
- 面板位置:面板固定在图表左上角,不会随 K 线滚动移动,卸载 EA 后面板自动消失。
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
黄金交易面板是一个 MT5 EA,在图表左上角固定一个操作面板。你不用记复杂的参数、不用手工输入价格,直接点按钮就能开单和平仓。面板会实时显示账户余额、净值、当前持仓数和总浮动盈亏,特别适合盯盘交易时快速下单。
逻辑原理
下单逻辑:点击 BUY 按钮,EA 用当前卖价(ASK)开一个做多单,自动设置止损为「开价减去止损点数」,止盈为「开价加上止盈点数」。点击 SELL 按钮,用当前买价(BID)开做空单,止损加上止损点数,止盈减去止盈点数。这样止损和止盈都是固定的点数,不会变动。
平仓逻辑:点击一键平仓按钮,EA 会找出当前图表上、同一个魔术号的所有持仓,全部按市价平掉。如果当前没有持仓,就提示「无持仓」。
账户监控:每个 tick(价格变动时)更新面板下方的账户数据。余额、净值、持仓单数都是实时的。浮动盈亏是绿色表示赚钱,红色表示亏钱。
魔术号隔离:每个 EA 都有一个魔术号(MagicNumber),面板只平自己的单子。比如你在黄金上装一个面板魔术号 888888,在美元/日元上装另一个魔术号 777777,两个面板互不影响。
参数说明
- Lots(0.1):每单手数。改成 0.5 就是 0.5 手一单,支持小数。
- TakeProfitPoints(500):止盈点数。黄金 500 点约 50 美元盈利,到这个点自动平仓。
- StopLossPoints(300):止损点数。黄金 300 点约 30 美元亏损,亏到这个点自动平仓。
- MagicNumber(888888):EA 魔术号。用来区分你装的不同 EA 单子,改成别的数字可以在同一个账户装多个面板互不干扰。
- Slippage(30):允许滑点。下单时价格可以滑动 30 点以内还会成交,防止网络卡下不了单。
怎么用
- 把代码保存为 GoldTradingPanel.mq5,放到 MT5 安装目录的 Experts 文件夹里。
- 在 MT5 菜单栏选「工具」→「编译器」,打开 GoldTradingPanel.mq5 编译。
- 打开黄金(XAUUSD)图表,从左边的「导航器」窗口拖 GoldTradingPanel 到图表上,勾选「允许自动交易」和「允许导入外部库(如适用)」。
- 面板就固定在左上角了。设置好手数、止盈止损点数后,点绿色 BUY 做多、红色 SELL 做空,每单自动带上止损和止盈。
- 想平仓就点橙色「一键平仓」按钮,当前所有持仓立即平掉。
- 面板下方实时显示账户余额、净值、持仓单数和总浮动盈亏。
适用场景
适合:黄金(XAUUSD)的日间交易或波段交易,特别是需要快速进出场的盯盘交易。任何 MT5 支持的品种都能用这个面板,改改 MagicNumber 就能在欧美、黄金、加密币等品种上同时装多个面板。
不适合:如果你想自动化交易策略(不是手工按按钮),应该用完整的 EA;如果要复杂的仓位管理、网格交易、跟踪止损,这个面板也做不了。
风险提示
滑点风险:下单时市场可能已经跳价,实际成交价可能比你看到的价格差很多点。Slippage 参数设太小容易下不了单,设太大容易成交到很差的价格。黄金波动快时要留意。
止损不一定能成交:代码里设的是固定点数止损,但市场跳空或流动性差时,止损可能在更差的价格才能成交,这叫滑点。尤其是重大数据发布时。
网络延迟:你点按钮和 EA 真正下单之间有延迟,价格可能已经动了。高波动时段尤其明显。
没有重绘风险:这个面板不是指标,不会重绘。账户信息是真实的,但下单执行结果要看服务器反馈,有网络问题时可能失败。
多单累积:面板没有检查持仓数量上限,你一直点按钮会一直开单,可能同时有 10 单、20 单。一键平仓会全平,要小心。
止盈止损不能修改:下单后,如果想改止盈止损,这个面板做不了,必须手工在 MT5 的持仓窗口改。
常见问题
- 这个面板会重绘吗?
- 不会。这是 EA,不是指标。账户信息和持仓数据都是真实的,面板显示的余额、净值、浮动盈亏都是实时更新,不存在重绘问题。
- 可以在非黄金品种上用吗?
- 可以。代码里没有限制品种,理论上 MT5 支持的任何品种都能用。但止盈止损的点数要根据不同品种调整——欧美可能要改成 50-100 点,黄金才是 300-500 点。
- 可以改止盈止损吗?
- 可以。在装载 EA 时调参数,或者后续在 MT5 的参数窗口改 TakeProfitPoints 和 StopLossPoints,改完后面板会立即显示新的数值。但已经开过的单子止盈止损不会变,只有新开的单子用新参数。
- 同一个账户可以装多个面板吗?
- 可以。在不同图表装不同的 MagicNumber,比如黄金用 888888,欧美用 777777。一键平仓只平自己的魔术号单子,互不影响。
- 下单失败了是什么原因?
- 可能是账户余额不够、Slippage 设太小价格滑太多、服务器连接慢、市场不在交易时间、或交易品种暂时不可交易。查看 MT5 的日志窗口看 EA 报告的错误码,根据错误码排查。
Gold Trading Panel EA for MT5 with Fixed SL/TP and One-Click Close
A graphical trading panel fixed in the upper-left corner of your MT5 chart. Click BUY or SELL to open positions with predefined stop-loss and take-profit points, or close all positions instantly with one button. Real-time display of account balance, equity, position count, and floating P&L.
Source code is shown above. Compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。