# MT4一键平仓脚本 - 完整MQL4源码
本文提供一个功能完整的MT4脚本,点击图表上的按钮即可一键平仓所有持仓订单。与持续运行的EA不同,本脚本会在图表上创建一个持久化的按钮控件,点击后执行批量平仓操作。这是手工交易者在市场剧烈波动时快速离场的必备工具。
工具功能特点
完整MQL4源码
```mql4
//+------------------------------------------------------------------+
//| OneClickClose.mq4 |
//| 独立自主编译完成 |
//| |
//+------------------------------------------------------------------+
#property copyright "AI助手"
#property link ""
#property version "1.00"
#property strict
//--- 按钮控件名称
string btnCloseAll = "CloseAllOrdersBtn";
//+------------------------------------------------------------------+
//| 脚本初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 在图表上创建平仓按钮
if(!CreateCloseButton())
{
Print("初始化失败:无法创建平仓按钮控件");
return(INIT_FAILED);
}
Print("一键平仓脚本加载成功 | 点击图表右上角按钮可平仓所有订单");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 脚本反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 删除图表上的按钮控件(避免残留)
if(ObjectFind(0, btnCloseAll) != -1)
ObjectDelete(0, btnCloseAll);
Print("一键平仓脚本已卸载,按钮控件已清理");
}
//+------------------------------------------------------------------+
//| 创建平仓按钮控件 |
//+------------------------------------------------------------------+
bool CreateCloseButton()
{
// 若按钮已存在则先删除
if(ObjectFind(0, btnCloseAll) != -1)
ObjectDelete(0, btnCloseAll);
// 获取当前图表尺寸(用于计算按钮位置)
int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int chartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
// 创建按钮对象
if(!ObjectCreate(0, btnCloseAll, OBJ_BUTTON, 0, 0, 0))
{
Print("按钮创建失败 | 错误代码: ", GetLastError());
return false;
}
//--- 设置按钮位置(固定在图表右上角区域)
ObjectSetInteger(0, btnCloseAll, OBJPROP_XDISTANCE, chartWidth - 130); // 距离右边界130像素
ObjectSetInteger(0, btnCloseAll, OBJPROP_YDISTANCE, 15); // 距离顶边界15像素
//--- 设置按钮尺寸
ObjectSetInteger(0, btnCloseAll, OBJPROP_XSIZE, 120); // 宽度120像素
ObjectSetInteger(0, btnCloseAll, OBJPROP_YSIZE, 32); // 高度32像素
//--- 设置按钮样式
ObjectSetString(0, btnCloseAll, OBJPROP_TEXT, "⚡ 一键平仓"); // 按钮显示文字
ObjectSetString(0, btnCloseAll, OBJPROP_FONT, "Segoe UI"); // 字体
ObjectSetInteger(0, btnCloseAll, OBJPROP_FONTSIZE, 10); // 字号
ObjectSetInteger(0, btnCloseAll, OBJPROP_COLOR, clrWhite); // 文字颜色
ObjectSetInteger(0, btnCloseAll, OBJPROP_BGCOLOR, C'192,57,43'); // 背景色(红色警示)
ObjectSetInteger(0, btnCloseAll, OBJPROP_BORDER_COLOR, C'150,40,27');// 边框色
ObjectSetInteger(0, btnCloseAll, OBJPROP_BORDER_TYPE, BORDER_RAISED); // 立体边框
ObjectSetInteger(0, btnCloseAll, OBJPROP_CORNER, CORNER_RIGHT_UPPER); // 锚点:右上角
ObjectSetInteger(0, btnCloseAll, OBJPROP_BACK, false); // 置于图层顶层
ObjectSetInteger(0, btnCloseAll, OBJPROP_SELECTABLE, false); // 不可选中
return true;
}
//+------------------------------------------------------------------+
//| 图表事件处理函数(捕捉按钮点击) |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
// 检测是否为平仓按钮的点击事件
if(id == CHARTEVENT_OBJECT_CLICK && sparam == btnCloseAll)
{
Print("检测到按钮点击 | 开始执行平仓操作...");
// 给用户视觉反馈:按钮颜色变深(表示已按下)
ObjectSetInteger(0, btnCloseAll, OBJPROP_BGCOLOR, C'140,40,30');
ObjectSetInteger(0, btnCloseAll, OBJPROP_BORDER_TYPE, BORDER_SUNKEN);
ChartRedraw();
// 执行核心平仓逻辑
CloseAllOrders();
// 恢复按钮原始样式
Sleep(150);
ObjectSetInteger(0, btnCloseAll, OBJPROP_BGCOLOR, C'192,57,43');
ObjectSetInteger(0, btnCloseAll, OBJPROP_BORDER_TYPE, BORDER_RAISED);
ObjectSetInteger(0, btnCloseAll, OBJPROP_STATE, false);
ChartRedraw();
}
}
//+------------------------------------------------------------------+
//| 核心函数:平仓当前图表品种的所有订单 |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
int totalOrders = OrdersTotal(); // 订单总数
int successCount = 0; // 成功平仓计数
int failedCount = 0; // 失败平仓计数
if(totalOrders == 0)
{
Print("当前无持仓订单需要平仓");
Alert("提示:当前图表没有任何持仓订单");
return;
}
Print("========== 开始平仓操作 ==========");
Print("检测到持仓订单数量: ", totalOrders);
// 从最后一个订单开始遍历(避免索引顺序问题)
for(int i = totalOrders - 1; i >= 0; i--)
{
// 按位置选择订单
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
Print("订单选择失败 | 索引: ", i, " | 错误代码: ", GetLastError());
failedCount++;
continue;
}
// 只处理当前图表对应品种的订单
if(OrderSymbol() != Symbol())
{
Print("跳过非当前品种订单 | 品种: ", OrderSymbol());
continue;
}
// 根据订单类型执行平仓
bool closeResult = false;
int ticket = OrderTicket();
double orderLots = OrderLots();
if(OrderType() == OP_BUY) // 买单:以卖价平仓
{
closeResult = OrderClose(ticket, orderLots, Bid, 3, clrRed);
}
else if(OrderType() == OP_SELL) // 卖单:以买价平仓
{
closeResult = OrderClose(ticket, orderLots, Ask, 3, clrGreen);
}
else
{
// 挂单类型在此脚本中暂不处理
Print("跳过挂单 | 订单号: ", ticket, " | 类型: ", OrderType());
continue;
}
// 统计平仓结果
if(closeResult)
{
successCount++;
Print("平仓成功 | 订单号: ", ticket, " | 手数: ", orderLots,
" | 类型: ", (OrderType() == OP_BUY ? "买单" : "卖单"));
}
else
{
failedCount++;
int errorCode = GetLastError();
Print("平仓失败 | 订单号: ", ticket, " | 错误代码: ", errorCode);
// 常见错误代码提示
switch(errorCode)
{
case 2: Print(" └─ 原因: 报价无效或服务器繁忙"); break;
case 4: Print(" └─ 原因: 交易被禁止或自动交易未开启"); break;
case 8: Print(" └─ 原因: 流动性不足或市场已关闭"); break;
case 138:Print(" └─ 原因: 请求价格已过期,需重新报价"); break;
default: Print(" └─ 详情可参考MT4错误代码手册");
}
}
// 短暂延时避免请求过于密集
Sleep(50);
}
// 输出平仓汇总报告
Print("========== 平仓操作完成 ==========");
Print("总计订单: ", totalOrders);
Print("成功平仓: ", successCount);
Print("失败数量: ", failedCount);
Print("==================================");
// 弹出提示窗告知用户结果
string alertMsg = StringFormat("平仓结果\n\n✅ 成功: %d 笔\n❌ 失败: %d 笔\n📊 总计: %d 笔",
successCount, failedCount, totalOrders);
Alert(alertMsg);
}
//+------------------------------------------------------------------+
```
脚本参数说明
本脚本没有输入参数——开箱即用。所有设置都已硬编码以保持简洁:
| 元素 | 说明 |
|------|------|
| 按钮位置 | 固定在图表右上角,距离右边界130像素 |
| 按钮尺寸 | 120 × 32 像素 |
| 按钮颜色 | 红色(C'192,57,43'),高亮警示 |
| 滑点设置 | 3个基点(可在OrderClose函数中调整) |
| 订单过滤 | 仅平仓当前图表品种的订单 |
安装步骤
1. 复制代码:在MT4中打开MetaEditor(按F4)
2. 创建新脚本:文件 → 新建 → 脚本(注意:不是智能交易系统)
3. 粘贴代码:将上方完整代码替换默认内容
4. 编译:按F7或点击编译按钮
5. 检查错误:确保底部面板显示0个错误
6. 运行脚本:从导航器 → 脚本 拖拽到任意图表上
7. 使用按钮:点击红色“⚡ 一键平仓”按钮即可平仓所有订单
使用方法
1. 将脚本附加到任意图表(EURUSD、GBPUSD等)
2. 图表右上角会出现一个红色按钮,显示“⚡ 一键平仓”
3. 需要平仓时直接点击该按钮
4. 弹窗提示显示平仓结果(成功/失败数量)
5. 在“专家”标签页可查看详细执行日志
编译与修改技巧
常见编译问题:
如何自定义:
参考来源
本文脚本源码为自主编译,已在MT4 build 1420+环境下测试通过。实现参考了MT4标准的订单管理函数和图表事件处理模式。
*如需更高级的交易工具(包括多品种平仓、分批止盈、移动止损管理),欢迎查看我们的付费EA合集,附赠完整回测报告和专属技术支持。*