// 黄金专用交易系统
#property copyright "Gold Quantum Professional EA"
#property version "1.0"
#property strict
#property description "专为XAUUSD设计的智能交易系统"
// 输入参数
input group "===== 黄金核心参数 ====="
input double GoldLotSize = 0.01; // 基础手数(黄金波动大)
input int GoldMaxSpread = 50; // 最大允许点差(黄金点差较大)
input bool UseGoldVolatility = true; // 启用黄金波动率适配
input group "===== 黄金多时间框架分析 ====="
input ENUM_TIMEFRAMES GoldPrimaryTF = PERIOD_M30; // 主要时间框架
input ENUM_TIMEFRAMES GoldConfirmTF = PERIOD_H4; // 确认时间框架
input group "===== 黄金趋势系统 ====="
input int GoldFastMA = 8; // 快速EMA周期
input int GoldSlowMA = 21; // 慢速EMA周期
input int GoldTrendMA = 55; // 趋势EMA周期
input group "===== 黄金动量系统 ====="
input int GoldRSI = 11; // RSI周期(黄金用较短周期)
input int GoldStochK = 5; // 随机指标K期
input int GoldStochD = 3; // 随机指标D期
input double GoldOverbought = 75; // 黄金超买区
input double GoldOversold = 25; // 黄金超卖区
input group "===== 黄金波动率系统 ====="
input int GoldATR = 14; // ATR周期
input double GoldATRMultiplier = 2.2; // ATR乘数(黄金波动大)
input int GoldADXPeriod = 14; // ADX趋势强度周期
input int GoldADXThreshold = 25; // ADX阈值
input group "===== 黄金资金管理 ====="
input double GoldRiskPercent = 0.5; // 风险百分比(黄金风险较高)
input bool UseGoldPyramid = false; // 启用金字塔加仓
input int MaxPyramidLevel = 2; // 最大金字塔层级
input double PyramidStep = 150; // 加仓间距(点)
input group "===== 黄金风险控制 ====="
input int GoldStopLoss = 500; // 基础止损点数
input int GoldTakeProfit = 200; // 基础止盈点数
input int GoldTrailingStart = 100; // 移动启动点数
input int GoldTrailingStep = 50; // 移动步长
input bool UseBreakEven = true; // 启用保本止损
input int BreakEvenAt = 80; // 保本触发点数
input group "===== 黄金时间过滤 ====="
input bool UseTimeFilter = true; // 启用时间过滤
input string StartTime = "08:00"; // 交易开始时间
input string EndTime = "22:00"; // 交易结束时间
input bool AvoidNews = true; // 避开重大新闻
// 全局变量声明
int GoldMagicNumber = 2025;
datetime LastBarTime;
int Spread;
bool DebugMode = true;
// 初始化函数
int OnInit()
{
Print("黄金量子专业版EA启动 - 专为XAUUSD优化");
Spread = (int)MarketInfo(Symbol(), MODE_SPREAD);
return(INIT_SUCCEEDED);
}
// 主执行函数
void OnTick()
{
if(!IsTradingAllowed()) return;
if(IsNewGoldBar())
{
ManageGoldPositions();
ExecuteGoldTrading();
}
}
// 黄金交易执行逻辑
void ExecuteGoldTrading()
{
int currentPositions = CountGoldPositions();
if(currentPositions >= (UseGoldPyramid ? MaxPyramidLevel : 1)) return;
int currentSpread = (int)((Ask - Bid) / Point);
if(currentSpread > GoldMaxSpread)
{
if(DebugMode) Print("点差过高: ", currentSpread, " > ", GoldMaxSpread);
return;
}
if(UseTimeFilter && !IsGoldTradingTime())
{
if(DebugMode) Print("非交易时间");
return;
}
if(AvoidNews && IsMajorNewsTime())
{
if(DebugMode) Print("重大新闻时间,暂停交易");
return;
}
bool buySignal = GenerateGoldBuySignal();
bool sellSignal = GenerateGoldSellSignal();
if(buySignal && !sellSignal)
{
OpenGoldOrder(ORDER_TYPE_BUY);
}
else if(sellSignal && !buySignal)
{
OpenGoldOrder(ORDER_TYPE_SELL);
}
}
// 黄金买入信号生成
bool GenerateGoldBuySignal()
{
// 计算必要指标
double fastEMA = iMA(NULL, PERIOD_M30, GoldFastMA, 0, MODE_EMA, PRICE_TYPICAL, 0);
double slowEMA = iMA(NULL, PERIOD_M30, GoldSlowMA, 0, MODE_EMA, PRICE_TYPICAL, 0);
double trendEMA = iMA(NULL, PERIOD_H4, GoldTrendMA, 0, MODE_EMA, PRICE_TYPICAL, 0);
double rsi = iRSI(NULL, PERIOD_M30, GoldRSI, PRICE_TYPICAL, 0);
double stochMain = iStochastic(NULL, PERIOD_M30, GoldStochK, GoldStochD, 3, MODE_SMA, 0, MODE_MAIN, 0);
double stochSignal = iStochastic(NULL, PERIOD_M30, GoldStochK, GoldStochD, 3, MODE_SMA, 0, MODE_SIGNAL, 0);
double adx = iADX(NULL, PERIOD_M30, GoldADXPeriod, PRICE_TYPICAL, MODE_MAIN, 0);
double plusDI = iADX(NULL, PERIOD_M30, GoldADXPeriod, PRICE_TYPICAL, MODE_PLUSDI, 0);
double minusDI = iADX(NULL, PERIOD_M30, GoldADXPeriod, PRICE_TYPICAL, MODE_MINUSDI, 0);
int signalScore = 0;
// 趋势确认 (2分)
bool strongUptrend = (fastEMA > slowEMA) && (slowEMA > trendEMA) && (Bid > fastEMA);
if(strongUptrend) signalScore += 2;
else if(fastEMA > slowEMA) signalScore += 1;
// ADX趋势强度 (1分)
if(adx > GoldADXThreshold && plusDI > minusDI) signalScore += 1;
// RSI动量 (1分)
double prevRSI = iRSI(NULL, PERIOD_M30, GoldRSI, PRICE_TYPICAL, 1);
if(rsi > 40 && rsi < 65 && rsi > prevRSI) signalScore += 1;
// 随机指标 (1分)
if(stochMain < 80 && stochMain > stochSignal && stochSignal > 20) signalScore += 1;
// 价格位置过滤 (1分)
double currentLow = MathMin(iLow(NULL, PERIOD_M30, 0), iLow(NULL, PERIOD_M30, 1));
if(currentLow > slowEMA) signalScore += 1;
if(DebugMode && signalScore >= 4)
{
Print("买入信号评分: ", signalScore, "/6");
}
return (signalScore >= 5);
}
// 黄金卖出信号生成
bool GenerateGoldSellSignal()
{
// 计算必要指标
double fastEMA = iMA(NULL, PERIOD_M30, GoldFastMA, 0, MODE_EMA, PRICE_TYPICAL, 0);
double slowEMA = iMA(NULL, PERIOD_M30, GoldSlowMA, 0, MODE_EMA, PRICE_TYPICAL, 0);
double trendEMA = iMA(NULL, PERIOD_H4, GoldTrendMA, 0, MODE_EMA, PRICE_TYPICAL, 0);
double rsi = iRSI(NULL, PERIOD_M30, GoldRSI, PRICE_TYPICAL, 0);
double stochMain = iStochastic(NULL, PERIOD_M30, GoldStochK, GoldStochD, 3, MODE_SMA, 0, MODE_MAIN, 0);
double stochSignal = iStochastic(NULL, PERIOD_M30, GoldStochK, GoldStochD, 3, MODE_SMA, 0, MODE_SIGNAL, 0);
double adx = iADX(NULL, PERIOD_M30, GoldADXPeriod, PRICE_TYPICAL, MODE_MAIN, 0);
double plusDI = iADX(NULL, PERIOD_M30, GoldADXPeriod, PRICE_TYPICAL, MODE_PLUSDI, 0);
double minusDI = iADX(NULL, PERIOD_M30, GoldADXPeriod, PRICE_TYPICAL, MODE_MINUSDI, 0);
int signalScore = 0;
// 趋势确认 (2分)
bool strongDowntrend = (fastEMA < slowEMA) && (slowEMA < trendEMA) && (Bid < fastEMA);
if(strongDowntrend) signalScore += 2;
else if(fastEMA < slowEMA) signalScore += 1;
// ADX趋势强度 (1分)
if(adx > GoldADXThreshold && minusDI > plusDI) signalScore += 1;
// RSI动量 (1分)
double prevRSI = iRSI(NULL, PERIOD_M30, GoldRSI, PRICE_TYPICAL, 1);
if(rsi < 60 && rsi > 35 && rsi < prevRSI) signalScore += 1;
// 随机指标 (1分)
if(stochMain > 20 && stochMain < stochSignal && stochSignal < 80) signalScore += 1;
// 价格位置过滤 (1分)
double currentHigh = MathMax(iHigh(NULL, PERIOD_M30, 0), iHigh(NULL, PERIOD_M30, 1));
if(currentHigh < slowEMA) signalScore += 1;
if(DebugMode && signalScore >= 4)
{
Print("卖出信号评分: ", signalScore, "/6");
}
return (signalScore >= 5);
}
// 黄金开单管理
void OpenGoldOrder(ENUM_ORDER_TYPE orderType)
{
double lot = CalculateGoldLotSize();
double sl = CalculateGoldStopLoss(orderType);
double tp = CalculateGoldTakeProfit(orderType);
if(lot <= 0)
{
Print("错误: 无效手数 ", lot);
return;
}
string comment = "GOLD-Q";
if(UseGoldPyramid)
{
int pyramidLevel = CountGoldPositions();
comment = StringFormat("GOLD-Q-L%d", pyramidLevel + 1);
}
int ticket = -1;
double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
if(orderType == ORDER_TYPE_BUY)
{
ticket = OrderSend(Symbol(), ORDER_TYPE_BUY, lot, price, 30, sl, tp, comment, GoldMagicNumber, 0, clrGreen);
}
else
{
ticket = OrderSend(Symbol(), ORDER_TYPE_SELL, lot, price, 30, sl, tp, comment, GoldMagicNumber, 0, clrRed);
}
if(ticket > 0)
{
Print("黄金订单开仓成功: 类型=", EnumToString(orderType), " 手数=", lot, " 价格=", price, " 止损=", sl, " 止盈=", tp);
}
else
{
int error = GetLastError();
Print("黄金订单开仓失败: 类型=", EnumToString(orderType), " 错误=", error, " - ", ErrorDescription(error));
}
}
// 黄金动态仓位计算
double CalculateGoldLotSize()
{
double baseLot = GoldLotSize;
// 根据账户余额计算风险
if(GoldRiskPercent > 0)
{
double riskAmount = AccountBalance() * GoldRiskPercent / 100.0;
double slPoints = (double)GoldStopLoss;
double pointValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE);
if(slPoints > 0 && pointValue > 0 && tickSize > 0)
{
baseLot = riskAmount / (slPoints * pointValue * Point / tickSize);
baseLot = NormalizeDouble(baseLot, 2);
}
}
// 金字塔加仓调整
if(UseGoldPyramid)
{
int currentLevel = CountGoldPositions();
if(currentLevel > 0 && currentLevel <= MaxPyramidLevel)
{
baseLot = NormalizeDouble(baseLot * MathPow(1.5, currentLevel), 2);
}
}
// 验证手数范围
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
double stepLot = MarketInfo(Symbol(), MODE_LOTSTEP);
baseLot = MathMax(baseLot, minLot);
baseLot = MathMin(baseLot, maxLot);
// 调整到手数步长的整数倍
if(stepLot > 0)
{
baseLot = stepLot * MathRound(baseLot / stepLot);
}
return NormalizeDouble(baseLot, 2);
}
// 黄金止损计算
double CalculateGoldStopLoss(ENUM_ORDER_TYPE orderType)
{
double atr = iATR(NULL, PERIOD_M30, GoldATR, 0);
double atrSL = atr * GoldATRMultiplier / Point;
double baseSL = (double)MathMax(GoldStopLoss, (int)atrSL);
if(orderType == ORDER_TYPE_BUY)
return NormalizeDouble(Bid - baseSL * Point, Digits);
else
return NormalizeDouble(Ask + baseSL * Point, Digits);
}
// 黄金止盈计算
double CalculateGoldTakeProfit(ENUM_ORDER_TYPE orderType)
{
double atr = iATR(NULL, PERIOD_M30, GoldATR, 0);
double atrTP = atr * 1.8 / Point;
double baseTP = (double)MathMax(GoldTakeProfit, (int)atrTP);
if(orderType == ORDER_TYPE_BUY)
return NormalizeDouble(Ask + baseTP * Point, Digits);
else
return NormalizeDouble(Bid - baseTP * Point, Digits);
}
// 黄金仓位管理
void ManageGoldPositions()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == GoldMagicNumber && OrderSymbol() == Symbol())
{
if(!ManageGoldTrailingStop(OrderTicket()))
{
Print("移动止损修改失败");
}
if(!ManageGoldBreakEven(OrderTicket()))
{
Print("保本止损修改失败");
}
}
}
}
}
// 黄金移动止损 - 返回是否成功
bool ManageGoldTrailingStop(int ticket)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET)) return false;
double newSl = 0;
bool needModify = false;
if(OrderType() == ORDER_TYPE_BUY)
{
if(Bid - OrderOpenPrice() > GoldTrailingStart * Point)
{
newSl = NormalizeDouble(Bid - GoldTrailingStep * Point, Digits);
if(newSl > OrderStopLoss() || MathAbs(OrderStopLoss()) < Point)
{
needModify = true;
}
}
}
else if(OrderType() == ORDER_TYPE_SELL)
{
if(OrderOpenPrice() - Ask > GoldTrailingStart * Point)
{
newSl = NormalizeDouble(Ask + GoldTrailingStep * Point, Digits);
if(newSl < OrderStopLoss() || MathAbs(OrderStopLoss()) < Point)
{
needModify = true;
}
}
}
if(needModify)
{
bool result = OrderModify(ticket, OrderOpenPrice(), newSl, OrderTakeProfit(), 0, clrBlue);
if(result && DebugMode)
{
Print("移动止损修改成功: 订单=", ticket, " 新止损=", newSl);
}
return result;
}
return true;
}
// 黄金保本止损 - 返回是否成功
bool ManageGoldBreakEven(int ticket)
{
if(!UseBreakEven) return true;
if(!OrderSelect(ticket, SELECT_BY_TICKET)) return false;
bool needModify = false;
double newSl = OrderOpenPrice();
if(OrderType() == ORDER_TYPE_BUY)
{
if(Bid - OrderOpenPrice() > BreakEvenAt * Point)
{
if(OrderStopLoss() < OrderOpenPrice())
{
needModify = true;
}
}
}
else if(OrderType() == ORDER_TYPE_SELL)
{
if(OrderOpenPrice() - Ask > BreakEvenAt * Point)
{
if(OrderStopLoss() > OrderOpenPrice())
{
needModify = true;
}
}
}
if(needModify)
{
bool result = OrderModify(ticket, OrderOpenPrice(), newSl, OrderTakeProfit(), 0, clrGreen);
if(result && DebugMode)
{
Print("保本止损修改成功: 订单=", ticket, " 保本价=", newSl);
}
return result;
}
return true;
}
// 错误描述函数
string ErrorDescription(int error)
{
switch(error)
{
case 0: return "成功";
case 1: return "没有错误,但结果未知";
case 2: return "通用错误";
case 3: return "无效参数";
case 4: return "服务器忙";
case 5: return "旧版本";
case 6: return "没有连接";
case 7: return "权限不足";
case 8: return "太频繁的请求";
case 9: return "违规操作";
case 64: return "账户被禁用";
case 65: return "无效账户";
case 128: return "交易超时";
case 129: return "无效价格";
case 130: return "无效止损";
case 131: return "无效交易量";
case 132: return "市场关闭";
case 133: return "交易被禁用";
case 134: return "资金不足";
case 135: return "价格已变化";
case 136: return "没有价格";
case 137: return "经纪人忙";
case 138: return "请求重新报价";
case 139: return "订单被锁定";
case 140: return "只允许买多";
case 141: return "交易请求过多";
case 145: return "修改被拒绝";
case 146: return "交易上下文忙";
case 147: return "过期时间被拒绝";
default: return "未知错误";
}
}
// 工具函数
int CountGoldPositions()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderMagicNumber() == GoldMagicNumber && OrderSymbol() == Symbol())
{
count++;
}
}
}
return count;
}
bool IsNewGoldBar()
{
datetime currentBarTime = iTime(NULL, PERIOD_M30, 0);
if(currentBarTime != LastBarTime)
{
LastBarTime = currentBarTime;
return true;
}
return false;
}
bool IsGoldTradingTime()
{
if(!UseTimeFilter) return true;
datetime current = TimeCurrent();
int hour = TimeHour(current);
int minute = TimeMinute(current);
// 交易时间: 08:00 - 22:00
int currentMinutes = hour * 60 + minute;
int startMinutes = 8 * 60; // 08:00
int endMinutes = 22 * 60; // 22:00
return (currentMinutes >= startMinutes && currentMinutes <= endMinutes);
}
bool IsMajorNewsTime()
{
if(!AvoidNews) return false;
datetime current = TimeCurrent();
int dayOfWeek = TimeDayOfWeek(current);
int hour = TimeHour(current);
int minute = TimeMinute(current);
// 简单新闻过滤
if(dayOfWeek == 5 && hour >= 13 && hour <= 15) return true; // 周五非农
if((hour == 14 || hour == 19) && (minute <= 30)) return true;
return false;
}
bool IsTradingAllowed()
{
if(IsStopped())
{
Comment("EA已停止");
return false;
}
if(IsTradeContextBusy())
{
Sleep(100);
return false;
}
if(!IsTradeAllowed())
{
Comment("自动交易未允许");
return false;
}
if(!IsConnected())
{
Comment("没有连接到服务器");
return false;
}
return true;
}
// 逆初始化函数
void OnDeinit(const int reason)
{
Print("黄金量子专业版EA停止运行,原因: ", reason);
}
logo
|