设为首页 收藏本站 切换语言 切换语言

哪位大佬帮我看一下,老是报错,EA交叉平均线嵌入风控 ```mql4 //+--------------------------------------------------------- ...

| 发表于 昨天 23:31 来自手机 | 显示全部楼层 |复制链接
哪位大佬帮我看一下,老是报错,EA交叉平均线嵌入风控

```mql4
//+------------------------------------------------------------------+
//|                                                  SmartMA_EA.mq4 |
//|                                  Copyright 2024, Your Name Here |
//|                                              https://www.yoururl.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Your Name Here"
#property link      "https://www.yoururl.com"
#property version   "1.00"
#property strict

//--- 输入参数
input int FastMAPeriod = 10;           // 快速MA周期
input int SlowMAPeriod = 22;           // 慢速MA周期  
input int MAPeriod = 14;               // 辅助MA周期
input double RiskPercent = 1.0;        // 单笔风险百分比
input int StopLossPoints = 50;         // 止损点数
input int TakeProfitPoints = 100;      // 止盈点数
input double DailyLossLimit = 3.0;     // 每日最大亏损百分比
input double WeeklyLossLimit = 8.0;    // 每周最大亏损百分比
input double EquityDrawdownLimit = 5.0;// 净值回撤熔断百分比
input int MaxOpenOrders = 3;           // 最大持仓单数
input double MaxSymbolExposure = 0.05; // 单品种最大风险敞口
input bool UseTrailingStop = true;     // 使用移动止损
input int TrailingStart = 50;          // 移动止损启动点数
input int TrailingStep = 20;           // 移动止损步长点数

//--- 全局变量
double InitialBalance;           // 初始余额
double DailyLossLevel;           // 当日亏损底线
double WeeklyLossLevel;          // 当周亏损底线
double EquityDrawdownLevel;      // 净值回撤熔断线
datetime LastTradeTime = 0;      // 最后交易时间
int MagicNumber = 12345;         // 魔术码,用于标识EA订单

//+------------------------------------------------------------------+
//| 专家初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   InitialBalance = AccountInfoDouble(ACCOUNT_BALANCE);
   UpdateLossLevels();
   
   Print("=== 智能MA EA已启动 ===");
   Print("账户余额: ", InitialBalance);
   Print("单笔风险: ", RiskPercent, "%");
   Print("每日亏损限制: ", DailyLossLimit, "%");
   Print("每周亏损限制: ", WeeklyLossLimit, "%");
   Print("净值回撤熔断: ", EquityDrawdownLimit, "%");
   Print("最大持仓单数: ", MaxOpenOrders);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 专家逆初始化函数                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Print("EA已卸载,原因: ", reason);
}

//+------------------------------------------------------------------+
//| 专家订单处理函数                                                 |
//+------------------------------------------------------------------+
void OnTick()
{
   if(TimeCurrent() - LastTradeTime < 60) return;
   
   if(!GlobalRiskCheck()) return;
   
   int signal = CheckMASignal();
   
   if(signal != 0 && RiskManagementCheck(signal))
   {
      if(ExecuteTrade(signal))
      {
         LastTradeTime = TimeCurrent();
         Print("交易执行成功,信号: ", signal);
      }
   }
   
   ManageOpenOrders();
}

//+------------------------------------------------------------------+
//| 移动平均线交叉信号检测                                           |
//+------------------------------------------------------------------+
int CheckMASignal()
{
   double fastMA_current = iMA(NULL, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double fastMA_prev = iMA(NULL, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   double slowMA_current = iMA(NULL, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double slowMA_prev = iMA(NULL, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   
   if(fastMA_prev <= slowMA_prev && fastMA_current > slowMA_current)
   {
      Print("生成买入信号: 快速MA(", FastMAPeriod, ")上穿慢速MA(", SlowMAPeriod, ")");
      return 1;
   }
   
   if(fastMA_prev >= slowMA_prev && fastMA_current < slowMA_current)
   {
      Print("生成卖出信号: 快速MA(", FastMAPeriod, ")下穿慢速MA(", SlowMAPeriod, ")");
      return -1;
   }
   
   return 0;
}

//+------------------------------------------------------------------+
//| 综合风控检查(开仓前)                                           |
//+------------------------------------------------------------------+
bool RiskManagementCheck(int signal)
{
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   
   if(equity < EquityDrawdownLevel)
   {
      Print("风控触发:净值回撤达到熔断线");
      return false;
   }
   
   if(equity < DailyLossLevel)
   {
      Print("风控触发:当日亏损已达上限");
      return false;
   }
   
   if(equity < WeeklyLossLevel)
   {
      Print("风控触发:当周亏损已达上限");
      return false;
   }
   
   int openOrders = CountOpenOrders();
   if(openOrders >= MaxOpenOrders)
   {
      Print("风控触发:持仓单数已达上限");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 全局风控检查(每次报价都执行)                                    |
//+------------------------------------------------------------------+
bool GlobalRiskCheck()
{
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   
   if(equity < EquityDrawdownLevel)
   {
      Print("风控熔断触发:净值回撤超过限制,平仓所有订单!");
      CloseAllOrders();
      return false;
   }
   
   MqlDateTime currentTime;
   TimeToStruct(TimeCurrent(), currentTime);
   MqlDateTime lastTime;
   TimeToStruct(LastTradeTime, lastTime);
   
   if(currentTime.day != lastTime.day)
   {
      UpdateLossLevels();
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| 更新亏损限额水平                                                  |
//+------------------------------------------------------------------+
void UpdateLossLevels()
{
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   DailyLossLevel = balance * (1 - DailyLossLimit / 100);
   WeeklyLossLevel = balance * (1 - WeeklyLossLimit / 100);
   EquityDrawdownLevel = InitialBalance * (1 - EquityDrawdownLimit / 100);
}

//+------------------------------------------------------------------+
//| 执行交易                                                         |
//+------------------------------------------------------------------+
bool ExecuteTrade(int signal)
{
   string symbol = Symbol();
   int ticket = -1;
   double price = 0;
   double stoploss = 0;
   double takeprofit = 0;
   double lotsize = CalculateLotSize(StopLossPoints);
   
   if(lotsize <= 0)
   {
      Print("错误:计算的手数无效");
      return false;
   }
   
   if(signal > 0)
   {
      price = Ask;
      stoploss = NormalizeDouble(price - StopLossPoints * Point, Digits);
      takeprofit = NormalizeDouble(price + TakeProfitPoints * Point, Digits);
      
      ticket = OrderSend(symbol, OP_BUY, lotsize, price, 3, stoploss, takeprofit,
                        "MA Buy", MagicNumber, 0, clrGreen);
   }
   else if(signal < 0)
   {
      price = Bid;
      stoploss = NormalizeDouble(price + StopLossPoints * Point, Digits);
      takeprofit = NormalizeDouble(price - TakeProfitPoints * Point, Digits);
      
      ticket = OrderSend(symbol, OP_SELL, lotsize, price, 3, stoploss, takeprofit,
                        "MA Sell", MagicNumber, 0, clrRed);
   }
   
   if(ticket > 0)
   {
      Print("订单执行成功: ", symbol, " ", lotsize, "手,订单号: ", ticket);
      return true;
   }
   else
   {
      Print("订单执行失败,错误代码: ", GetLastError());
      return false;
   }
}

//+------------------------------------------------------------------+
//| 计算合适的手数(基于风险百分比)                                 |
//+------------------------------------------------------------------+
double CalculateLotSize(double stoplossPoints)
{
   if(stoplossPoints <= 0) return 0.01;
   
   double riskMoney = AccountInfoDouble(ACCOUNT_EQUITY) * RiskPercent / 100;
   double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   double pointValue = MarketInfo(Symbol(), MODE_POINT);
   
   if(tickValue <= 0 || pointValue <= 0) return 0.01;
   
   double lotSize = riskMoney / (stoplossPoints * pointValue * tickValue);
   lotSize = NormalizeDouble(lotSize, 2);
   
   double minLot = MarketInfo(Symbol(), MODE_MINLOT);
   double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   
   if(lotSize < minLot) lotSize = minLot;
   if(lotSize > maxLot) lotSize = maxLot;
   
   lotSize = MathRound(lotSize / lotStep) * lotStep;
   
   return lotSize;
}

//+------------------------------------------------------------------+
//| 管理已有订单(移动止损等)                                       |
//+------------------------------------------------------------------+
void ManageOpenOrders()
{
   if(!UseTrailingStop) return;
   
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) &&
         OrderMagicNumber() == MagicNumber &&
         OrderSymbol() == Symbol())
      {
         double newStopLoss = 0;
         double currentProfit = 0;
         bool modifyResult = false;  // 在这里声明一次
         
         if(OrderType() == OP_BUY)
         {
            currentProfit = (Bid - OrderOpenPrice()) / Point;
            if(currentProfit >= TrailingStart)
            {
               newStopLoss = OrderOpenPrice() + (currentProfit - TrailingStep) * Point;
               newStopLoss = NormalizeDouble(newStopLoss, Digits);
               
               if(newStopLoss > OrderStopLoss() || OrderStopLoss() == 0)
               {
                  modifyResult = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss,
                             OrderTakeProfit(), 0, clrBlue);
                  if(modifyResult)
                     Print("移动止损更新成功 - 订单: ", OrderTicket(), ",新止损: ", newStopLoss);
               }
            }
         }
         else if(OrderType() == OP_SELL)
         {
            currentProfit = (OrderOpenPrice() - Ask) / Point;
            if(currentProfit >= TrailingStart)
            {
               newStopLoss = OrderOpenPrice() - (currentProfit - TrailingStep) * Point;
               newStopLoss = NormalizeDouble(newStopLoss, Digits);
               
               if(newStopLoss < OrderStopLoss() || OrderStopLoss() == 0)
               {
                  modifyResult = OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss,
                             OrderTakeProfit(), 0, clrBlue);
                  if(modifyResult)
                     Print("移动止损更新成功 - 订单: ", OrderTicket(), ",新止损: ", newStopLoss);
               }
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| 统计开仓订单数量                                                 |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) &&
         OrderMagicNumber() == MagicNumber)
      {
         count++;
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| 平仓所有订单                                                     |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
   int closedCount = 0;
   bool result = false;
   
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) &&
         OrderMagicNumber() == MagicNumber)
      {
         result = false;
         if(OrderType() == OP_BUY)
            result = OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrYellow);
         else if(OrderType() == OP_SELL)
            result = OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrYellow);
         else
            result = OrderDelete(OrderTicket());
            
         if(result) closedCount++;
      }
   }
   Print("熔断平仓完成,共平仓 ", closedCount, " 个订单");
}
//+------------------------------------------------------------------+
```
最近访问 头像模式
举报

评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

 简体中文国旗 简体中文
 繁體中文国旗 繁體中文
 English国旗 English(英语)
 日本語国旗 日本語(日语)
 Deutsch国旗 Deutsch(德语)
 Русский язык国旗 Русский язык(俄语)
 بالعربية国旗 بالعربية(阿拉伯语)
 Türkçe国旗 Türkçe(土耳其语)
 Português国旗 Português(葡萄牙语)
 ภาษาไทย国旗 ภาษาไทย(泰国语)
 한어国旗 한어(朝鲜语/韩语)
 Français国旗 Français(法语)
翻译