MetaTrader 4 的 EA 代码分享,对开仓的订单自动追加止损
自动止损.mq4
需要打开自动交易功能
// 开仓自动止损EA.mq4
#property copyright "Copyright 2025."
#property link "https://zgcwkj.cn/"
#property version "1.00"
#property strict
// 输入参数(可在EA设置中调整)
input int MagicNumber = 0; // 管理的订单魔术数字
input double 止损点数 = 400; // 固定止损点数
input bool 覆盖已有止损 = false; // 是否覆盖订单已有的止损(false=只给无止损的订单设置)
// 初始化函数:打印启动信息
int OnInit()
{
Print("=== 开仓自动止损EA启动 ===");
Print("监控品种:", Symbol(), ",时间周期:", Period());
Print("管理魔术数字:", MagicNumber, "(0=所有订单)");
Print("止损点数:", 止损点数, "点,是否覆盖已有止损:", 覆盖已有止损 ? "是" : "否");
return(INIT_SUCCEEDED);
}
// 实时监测:每 tick 检查订单,为符合条件的订单设置止损
void OnTick()
{
// 遍历所有未平仓订单
for(int i = 0; i < OrdersTotal(); i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
Print("订单选择失败(索引:", i, "),错误码:", GetLastError());
continue;
}
// 过滤条件:当前品种 + 魔术数字匹配 + 多/空单
if(OrderSymbol() != Symbol())
{
// 跳过非当前品种的订单(仅监控当前图表品种)
continue;
}
if(OrderMagicNumber() != MagicNumber)
{
// 跳过魔术数字不匹配的订单
continue;
}
if(OrderType() != OP_BUY && OrderType() != OP_SELL)
{
// 只处理多单和空单(跳过挂单等)
continue;
}
// 检查是否需要设置(已有止损且不允许覆盖,则跳过)
if(OrderStopLoss() != 0 && !覆盖已有止损) // 存在止损
{
// Print("订单", OrderTicket(), "存在止损(", OrderStopLoss(), "),跳过处理");
continue;
}
if(OrderTakeProfit() != 0 && !覆盖已有止损) // 存在止盈
{
// Print("订单", OrderTicket(), "存在止盈(", OrderTakeProfit(), "),跳过处理");
continue;
}
// 计算止损价格
double openPrice = OrderOpenPrice(); // 开仓价格
double stopLoss = 0; // 止损价格
string orderType = (OrderType() == OP_BUY) ? "多单" : "空单";
// 多单止损:开仓价 - 止损点数;空单止损:开仓价 + 止损点数
if(OrderType() == OP_BUY)
{
stopLoss = openPrice - 止损点数 * Point;
}
else // OP_SELL
{
stopLoss = openPrice + 止损点数 * Point;
}
// 标准化价格(对齐平台最小报价单位,避免价格无效)
stopLoss = NormalizeDouble(stopLoss, Digits);
// 打印开仓信息和止损计算日志
// Print("\n--- 检测到订单需设置止损 ---");
Print("订单号:", OrderTicket(), ",类型:", orderType);
// Print("开仓时间:", TimeToString(OrderOpenTime(), TIME_DATE|TIME_SECONDS));
// Print("开仓价格:", openPrice);
// Print("止损点数:", 止损点数, "点,计算止损价:", stopLoss);
// 修改订单设置止损
bool modifySuccess = OrderModify(
OrderTicket(), // 订单号
OrderOpenPrice(), // 保持开仓价不变
stopLoss, // 新止损价
OrderTakeProfit(), // 保持止盈价不变(若有)
0 // 立即生效(无延迟)
);
// 打印设置结果日志
if(modifySuccess)
{
Print("订单", OrderTicket(), "止损设置成功!最终止损价:", stopLoss);
}
else
{
Print("订单", OrderTicket(), "止损设置失败!错误码:", GetLastError());
Print("失败可能原因:价格超出平台限制/网络延迟/订单已关闭");
}
}
}
// 销毁函数:打印停止信息
void OnDeinit(const int reason)
{
Print("=== 开仓自动止损EA已停止 ===");
}