现在我们来修改均线交叉EA的 OnTick()
函数,以便应用我们新创建的那些功能。首先,在建立新的买单前,我们会检查当前是否已经有买单持仓。我们不再是去平掉单个卖单,而是直接调用一个函数来平掉所有卖单。这种方法不需要用到订单号。
// 买单逻辑
if(FastMA > SlowMA && BuyTicket == 0 && BuyMarketCount(Symbol(),MagicNumber) == 0) // 条件:快线高于慢线,没有买单,且当前没有持仓买单
{
if(SellMarketCount(Symbol(),MagicNumber) > 0) // 如果有持仓卖单
{
CloseAllSellOrders(Symbol(),MagicNumber,Slippage); // 平掉所有卖单
}
SellTicket = 0; // 清除卖单
BuyTicket = OpenBuyOrder(Symbol(),LotSize,UseSlippage,MagicNumber); // 开立新买单并记录
}
这里,我们用到了之前封装的 BuyMarketCount()
函数,它能返回当前持有的买单数量。我们保留了 BuyTicket
的检查,这样就能确保EA只会交替地开立买单和卖单(即不会在已有买单时再开买单,或已有卖单时再开卖单,除非反向单被平仓)。 CloseAllSellOrders()
函数会平掉所有未平仓的卖单。我们会先通过 SellMarketCount()
检查是否有需要平仓的卖单。这个函数不像第4章中的 CloseSellOrder()
函数那样需要订单号。我们推荐您在EA中采用这种方法来平掉反向订单,因为它更加稳定可靠。 其余的买单建立代码和之前一样。相应的卖单建立代码如下:
// 卖单逻辑
if(FastMA < SlowMA && SellTicket == 0 && SellMarketCount(Symbol(),MagicNumber) == 0) // 条件:快线低于慢线,没有卖单,且当前没有持仓卖单
{
if(BuyMarketCount(Symbol(),MagicNumber) > 0) // 如果有持仓买单
{
CloseAllBuyOrders(Symbol(),MagicNumber,Slippage); // 平掉所有买单
}
BuyTicket = 0; // 清除买单
SellTicket = OpenSellOrder(Symbol(),LotSize,UseSlippage,MagicNumber); // 开立新卖单并记录
}
接下来,我们给订单添加追踪止损功能。我们会在下单之后执行追踪止损的操作。和前面一样,在调用追踪止损函数前,我们会先检查是否有持仓的买单或卖单。让我们在EA中添加以下外部可调参数:
extern int TrailingStop = 50; // 追踪止损点数,默认为50点
extern int MinimumProfit = 50; // 启用追踪止损的最小盈利点数,默认为50点
以下是检查并修改追踪止损的代码。请注意,我们会检查 TrailingStop
是否设置了有效值(即大于0)。如果它被设为0,那么追踪止损功能实际上就相当于关闭了:
if(BuyMarketCount(Symbol(),MagicNumber) > 0 && TrailingStop > 0) // 如果有持仓买单,并且追踪止损点数大于0
{
BuyTrailingStop(Symbol(),TrailingStop,MinimumProfit,MagicNumber); // 执行买单的追踪止损
}
if(SellMarketCount(Symbol(),MagicNumber) > 0 && TrailingStop > 0) // 如果有持仓卖单,并且追踪止损点数大于0
{
SellTrailingStop(Symbol(),TrailingStop,MinimumProfit,MagicNumber); // 执行卖单的追踪止损
}
这是给早前的那个简单的均线EA增加一些功能(移动止损等),让EA更完善,后续会附上完整代码。