MetaTrader5
利用移动止损策略优化你的交易表现
这个代码块在你使用止损的情况下也能正常工作。 需求说明 你需要包含 "Trade.mqh",以便访问 CTrade 类,这样你就可以对持仓和订单进行操作。 #include <Trade\Trade.mqh> // <<------------------------------------------ 包含这个 "Trade.mqh" 以访问 CTrade 类 你需要设置一个 输入参数,以调整你想要的移动距离。虽然这不是必需的,但为了方便,设置一个是好的。 input double Trailing_Step = 3.0; 你需要定义一个 CTrade 类的实例,名称可以随意。最好在 OnInit 事件处理程序之后定义它。 接下来,你需要创建一个 if 语句 来检查当前是否有持仓在运行。这个语句每次 tick 时调用 Check_TrailingStop(); 函数。这一点很重要,因为 EA 应该能够 顺畅而快速 地调整止损。请记得把这个语句放在 OnTick 事件处理程序的顶部,以确保正常工作。 //+------------------------------------------------------------------+ //| 专家初始化函数 | //+------------------------------------------------------------------+ int OnInit() { //--- 创建定时器 EventSetTimer(60); //--- return(INIT_SUCCEEDED); } CTrade trade; // <<------------------------------------------ 声明 "CTrade" 类,你可以用任何你想要的名字替换 "trade" void OnTick() { if(PositionsTotal() > 0) { // 如果有持仓时,每次 tick 调用移动止损函数 Check_TrailingStop(); } } 你需要声明一个自定义函数 Check_TrailingStop();(在这个例子中)。你可以用任何你想要的名字。 自定义函数会循环遍历 所有打开的持仓,并根据你设置的距离来调整它们。 void Check_TrailingStop() { int totalPositions = PositionsTotal(); for(int count = 0; count < totalPositions; count++) { ulong TicketNo = PositionGetTicket(count); // 使用持仓的 'index' 获取持仓票号 if(PositionSelectByTicket(TicketNo)) { // 使用票号选择持仓 if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { // 检查持仓类型 double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); // <<-------------------获取当前止损 double takeProfit = PositionGetDouble(POSITION_TP); double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); ulong ticket = PositionGetTicket(count); double trailingLevel = NormalizeDouble(bidPrice - (Trailing_Step * Point()), _Digits); if(stopLoss < openPrice) { // 如果没有止损 if(bidPrice > openPrice && trailingLevel > openPrice) { // 每个持仓仅运行一次,设置初始止损 trade.PositionModify(ticket, trailingLevel, takeProfit); // 使用 "CTrade.trade" 修改移动止损 } } if(bidPrice > openPrice && trailingLevel > stopLoss) { // 检查移动止损水平是否高于之前的水平 trade.PositionModify(ticket, trailingLevel, takeProfit); // 使用 "CTrade.trade" 修改移动止损 } } if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double takeProfit = PositionGetDouble(POSITION_TP); double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); ulong ticket = PositionGetTicket(count); double trailingLevel = NormalizeDouble(askPrice + (Trailing_Step * Point()), _Digits); if(stopLoss < openPrice) { // 如果没有止损 if(askPrice < openPrice && trailingLevel < openPrice) { // 每个持仓仅运行一次,设置初始止损 trade.PositionModify(ticket, trailingLevel, takeProfit); // 使用 "CTrade.trade" 修改移动止损 } } if(askPrice < openPrice && trailingLevel < stopLoss) { // 检查移动止损水平是否高于之前的水平 trade.PositionModify(ticket, trailingLevel, takeProfit); // 使用 "CTrade.trade" 修改移动止损 } } } } }
2024.04.05