普乐智能

查看: 176|回复: 0

以下是根据需求编写的MQL4代码,实现在总利润回撤至30%时统一调整止盈点:

[复制链接]

338

主题

424

帖子

1670

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1670
发表于 2025-3-3 20:52:42 | 显示全部楼层 |阅读模式
[size=16.002px]以下是根据需求编写的MQL4代码,实现在总利润回撤统一调整止盈点:

//+------------------------------------------------------------------+
//|                                                      HedgeEA.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// 全局变量
double maxTotalProfit = 0;      // 记录历史最大总利润
bool adjusted = false;          // 止盈调整标志
int magicNumber = 12345;        // 订单魔术编号

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double totalProfit = 0;
   int orderCount = 0;

   // 计算总利润和订单数量
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() &&
            OrderMagicNumber() == magicNumber &&
            OrderType() == OP_BUY)
         {
            totalProfit += OrderProfit();
            orderCount++;
         }
      }
   }

   // 确保有三个多单
   if(orderCount == 3)
   {
      // 更新最大利润
      if(totalProfit > maxTotalProfit)
      {
         maxTotalProfit = totalProfit;
         adjusted = false; // 发现新高时重置标志
      }

      // 检查回撤条件
      if(!adjusted &&
         maxTotalProfit > 0 &&
         totalProfit <= maxTotalProfit * 0.3)
      {
         // 遍历所有订单调整止盈
         for(int i=OrdersTotal()-1; i>=0; i--)
         {
            if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            {
               if(OrderSymbol() == Symbol() &&
                  OrderMagicNumber() == magicNumber &&
                  OrderType() == OP_BUY)
               {
                  double newTP = CalculateValidTP(Bid);

                  // 仅当需要修改时调整
                  if(MathAbs(OrderTakeProfit() - newTP) > Point/2)
                  {
                     bool result = OrderModify(
                        OrderTicket(),
                        OrderOpenPrice(),
                        OrderStopLoss(),
                        newTP,
                        0,
                        clrNONE
                     );

                     if(result)
                     {
                        Print("订单 ", OrderTicket(), " 止盈调整成功至 ", newTP);
                     }
                     else
                     {
                        Print("错误 ", GetLastError(), ": 订单 ", OrderTicket(), " 止盈调整失败");
                     }
                  }
               }
            }
         }
         adjusted = true; // 标记已调整
      }
   }
}

//+------------------------------------------------------------------+
//| 计算符合平台要求的有效止盈价                                      |
//+------------------------------------------------------------------+
double CalculateValidTP(double desiredPrice)
{
   double minStoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   double adjustedPrice = NormalizeDouble(desiredPrice, Digits);

   // 计算与当前价格的差距
   double diff = MathAbs(adjustedPrice - Bid);

   // 如果小于最小停损水平
   if(diff < minStoplevel)
   {
      // 根据方向调整
      if(adjustedPrice > Bid)
         adjustedPrice = Bid + minStoplevel;
      else
         adjustedPrice = Bid - minStoplevel;

      adjustedPrice = NormalizeDouble(adjustedPrice, Digits);
   }

   return adjustedPrice;
}


-------------------------------------------------------------------------------
代码说明:
  • 订单识别:使用魔术编号(magicNumber)识别需要管理的订单,确保只处理特定EA开立的订单。
  • 利润计算
    • 遍历所有订单,累加符合条件订单的当前利润(OrderProfit())
    • 统计符合条件订单数量(应正好3个)

  • 动态追踪最大利润
    • 持续更新历史最大利润值(maxTotalProfit)
    • 当检测到新最大值时重置调整标志

  • 回撤条件触发
    • 当当前利润 ≤ 历史最大利润的30%时触发调整
    • 使用adjusted标志确保只执行一次调整,直到出现新利润高点

  • 止盈价调整
    • 计算符合平台要求的最小距离的有效价格
    • 批量修改所有符合条件的订单止盈价
    • 包含错误处理机制,记录操作结果

  • 价格验证
    • 考虑平台的最小停损水平(Stop Level)
    • 确保修改后的价格符合交易规则


使用注意事项:
  • 需在EA属性中设置魔术编号(magicNumber),并在开仓时使用相同编号


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|11wo.com

Copyright © 2001-2013 Comsenz Inc.Template by Comsenz Inc.All Rights Reserved.

Powered by Discuz!X3.4( 备案号:桂ICP备18000909号-1 )QQ

快速回复 返回顶部 返回列表