哪位大佬帮我看一下,老是报错,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, " 个订单");
}
//+------------------------------------------------------------------+
```
|