MQL5 向导实战:编写未平仓位的追踪止损模块
一、追踪模块的作用
CExpertTrailing 只负责“是否该修改保护性订单”,最终决策仍归 CExpert。把它独立出来,可以让同一信号搭配不同的护利策略。
二、核心虚方法
Trailing 模块暴露 CheckTrailingStopLong/Short,返回是否需要上移/下移止损。Profit 与 StopLevel 是两个关键参数。
class CExpertTrailing : public CObject
{
public:
virtual bool Init(...) { return false; }
virtual bool CheckTrailingStopLong(void) { return false; }
virtual bool CheckTrailingStopShort(void) { return false; }
};
class CSampleTrailing : public CExpertTrailing
{
protected:
double m_profit; // 触发盈利阈值
double m_stoplevel; // 追踪距离
};
三、实现移动止损逻辑
只有盈利超过阈值才启动追踪,且新止损必须高于(多头)现有止损,遵循“只增不减”原则,避免把止损往不利方向拉。
bool CSampleTrailing::CheckTrailingStopLong(void)
{
double pos = PositionGetDouble(POSITION_PRICE_OPEN);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(bid - pos < m_profit) return false; // 未达盈利阈值
double new_sl = bid - m_stoplevel;
if(new_sl > PositionGetDouble(POSITION_SL))
return true; // 允许上移止损
return false;
}
四、参数:Profit / StopLevel
Profit 设触发线(盈利多少才开始护利),StopLevel 设回撤距离(从现价回撤多少锁利)。二者配合可避免过早锁定利润,也避免利润回吐过多。
五、常见坑
六、模块参数怎么设
向导的追踪止损模块主要两个参数:回调距离(盈利回吐容忍,用点数或 ATR 倍数)和起始触发(盈利多少后才启动追踪)。距离太小被噪音扫出、太大回吐利润,要按品种波动调。
推荐用 ATR 倍数而非固定点数,这样跨周期跨品种行为一致。起始触发设成「覆盖交易成本加少许缓冲」,避免刚盈利就被手续费吃掉还倒贴。
七、与信号模块协作
追踪模块独立于信号:信号只负责「何时进」,追踪负责「进了之后怎么护利润」。两者解耦后,同一套追踪可以配不同信号,信号坏了换信号、追踪逻辑不动。
八、常见误用
两个坑:一是回调距离设成 0(等于不追踪,盈利单常被扫);二是把追踪启动阈值设太高,等启动价格已回吐一大截。还有人每 tick 都改止损刷爆订单——模块内部应只在「更优」时才改。
另一个隐蔽坑:追踪只在持仓期间有效,平仓逻辑要独立,别让追踪函数误把想持有的单平掉。
九、追踪与信号的生命周期配合
追踪模块要感知信号的「平仓意图」:若信号模块判定趋势结束,追踪应立即平仓而非继续护利;若信号只暂歇,则追踪继续持有。两者通过共享状态协商,避免一个想走一个想留的冲突。
实现上,信号模块写一个「期望持仓」标志,追踪模块读它决定是否平仓。把「谁有权结束这笔交易」定义清楚,是追踪与信号协作不打架的前提。
实盘里常见 bug 是追踪和信号都尝试平仓,导致重复操作或状态错乱。统一由一方(通常追踪/风控层)执行平仓,信号只提建议,职责单一才好维护。
十、追踪止损的参数寻优
回调距离用 ATR 倍数时,倍数本身要寻优:太低在噪音里被洗、太高回吐利润。做法是在样本内扫几个倍数、用样本外选「被扫次数与利润回吐权衡」最优的,而非拍脑袋定 2 倍或 3 倍。
寻优时观察「扫掉止损后价格是否真反转」:若常反转说明止损太紧该放宽;若扫掉后继续原方向说明追踪有效。用这个反馈调参,比盯着权益曲线更直观,也更能避免过拟合到某个幸运值。
实盘前在模拟账户跑两周,记录被噪音扫出的次数与回吐利润的比例,据此微调 ATR 倍数而非拍脑袋定。追踪不是越紧越好——留一点波动呼吸空间,才能吃到趋势中段而非刚启动就被甩下车。把起始触发设成覆盖交易成本加缓冲,避免盈利单刚冒头就被手续费吃掉还倒贴。
记住一条经验法则:追踪止损只护已经到手的利润,从不试图猜顶;它该跟着价格走,而不是提前跑。把这条写进模块注释,提醒自己别手痒去「优化」出场点。