封装添加/修改止损止盈函数 (AddStopProfit
)
为了进一步细化函数职责,我们将为现有订单添加或修改止损 (SL) 和止盈 (TP) 的操作也封装成一个独立的函数。这个函数尤其适用于配合那些为了兼容 ECN 而在下单时不设置 SL/TP 的 OpenBuyOrder
/ OpenSellOrder
函数使用。
设计要点:
- 输入: 函数接收目标订单的票号
argTicket
,以及已经过计算和验证的目标止损价argStopLoss
和止盈价argTakeProfit
。 - 前提: 函数假设传入的
argStopLoss
和argTakeProfit
价格已经是有效的(满足MODE_STOPLEVEL
要求)。函数本身不执行价格验证。 - 操作: 函数内部会选中订单,然后调用
OrderModify
来更新 SL 和 TP,同时保持订单的开仓价格和到期时间不变。 - 返回值: 返回
OrderModify
操作的结果 (true
表示指令发送成功,false
表示失败或无需修改)。
函数定义:
/**
* @brief 为指定的现有订单添加或修改止损和止盈。
* 假设传入的 SL/TP 价格已经过验证。
* @param argTicket 目标订单的订单号 (Ticket)
* @param argStopLoss 新的止损价格 (0 或负数表示移除或不设置)
* @param argTakeProfit 新的止盈价格 (0 或负数表示移除或不设置)
* @return bool true: 修改指令成功发送; false: 失败或无需修改
*/
bool AddStopProfit(int argTicket, double argStopLoss, double argTakeProfit)
{
// 1. 如果传入的 SL 和 TP 都无效 (<=0), 则认为无需操作
if (argStopLoss <= 0 && argTakeProfit <= 0) {
Print("AddStopProfit: 无有效的 SL(<=0) 或 TP(<=0) 提供给订单 #", argTicket);
return(false); // 返回 false 表示未执行有效修改
}
bool modifySuccess = false; // 初始化返回值
// 2. 选中订单
if (OrderSelect(argTicket, SELECT_BY_TICKET))
{
// 3. (可选优化) 检查传入值是否与当前值几乎相同,避免无效调用
// if (MathAbs(argStopLoss - OrderStopLoss()) < Point*0.1 && MathAbs(argTakeProfit - OrderTakeProfit()) < Point*0.1) {
// Print("AddStopProfit: 新的 SL/TP 与当前值相同,无需修改订单 #", argTicket);
// return true; // 无需修改视为成功
// }
// 4. 等待交易环境 (假设 WaitForTradeContext 已定义)
if (!WaitForTradeContext()) return(false);
// 5. 调用 OrderModify 更新 SL/TP
// 保持开仓价 (OrderOpenPrice()) 和 到期时间 (OrderExpiration()) 不变
modifySuccess = OrderModify(argTicket, OrderOpenPrice(), argStopLoss, argTakeProfit,
OrderExpiration(), // 传入当前到期时间以保持不变
clrNONE); // 不绘制修改箭头
// 6. 处理修改结果
if (!modifySuccess)
{
// 调用统一错误处理函数 (假设 HandleTradeError 已定义)
HandleTradeError(StringFormat("AddStopProfit 修改订单 #%d", argTicket), GetLastError());
}
else
{
Print("成功发送 SL/TP 修改指令 for #", argTicket);
}
}
// else { HandleTradeError(StringFormat("AddStopProfit: 无法选中订单 #%d", argTicket), 0); } // 可选:处理 OrderSelect 失败
// 返回修改指令发送结果
return(modifySuccess);
}
函数首先检查传入的 SL 和 TP 是否都无效(都小于等于 0)。如果都无效,则直接返回 false
(表示未执行有效操作)。否则,它会选中订单,等待交易环境空闲,然后调用 OrderModify
来尝试更新止损和止盈。在 OrderModify
调用中,开仓价参数传入 OrderOpenPrice()
,到期时间参数传入 OrderExpiration()
,以确保这两项在修改 SL/TP 时保持不变。函数最后返回 OrderModify
的布尔结果,并内置了错误处理逻辑(建议封装)。这个函数设计上可以用于修改任何类型的活动订单(无论是市价单还是挂单)的 SL/TP。