You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让MQL4预警EA自动运行于MetaTrader4全部市场报价品种

让MT4预警EA自动遍历所有Market Watch品种的解决方案

嘿,Patrick!你的核心预警逻辑已经很清晰了,要让它覆盖Market Watch里的所有品种,关键是遍历MT4的品种列表,然后对每个品种单独执行你的指标判断逻辑。下面是具体的实现步骤和修改后的代码:

核心思路

MT4提供了两个关键函数来获取品种列表:

  • SymbolsTotal():返回Market Watch里的品种总数
  • SymbolName(index, true):根据索引获取对应的品种名称(第二个参数true表示返回全称)

我们需要把你的指标计算和预警逻辑封装成一个独立函数,然后循环遍历所有品种,逐个调用这个函数即可。

修改后的完整代码

//+------------------------------------------------------------------+
//|                                                  MultiSymbolAlert.mq4 |
//|                        Copyright 2024, MetaQuotes Software Corp. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software Corp."
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
//| 检查单个品种的超买超卖状态并触发预警                               |
//+------------------------------------------------------------------+
void CheckSymbolAlert(string symbol)
{
    // 跳过不可交易或无效的品种
    if(!SymbolSelect(symbol, true)) return;
    
    // 获取指标值(将原代码的NULL替换为具体品种symbol)
    double RSI = iRSI(symbol, PERIOD_M15, 7, PRICE_CLOSE, 0);
    double Stoc = iStochastic(symbol, PERIOD_M15, 5, 3, 3, MODE_SMA, STO_LOWHIGH, 0, 0);
    double BoliUpper = iBands(symbol, PERIOD_M15, 20, 2, 0, PRICE_MEDIAN, 1, 1);
    double BoliLower = iBands(symbol, PERIOD_M15, 20, 2, 0, PRICE_MEDIAN, 2, 1);
    // 修正原代码的笔误:前一根K线的高低应该用iHigh/iLow,而非iOpen/iClose
    double CandlePrevHigh = iHigh(symbol, PERIOD_M15, 1);
    double CandlePrevLow = iLow(symbol, PERIOD_M15, 1);
    
    // 超买判断
    if((RSI > 75) && (Stoc > 80) && (BoliUpper < CandlePrevHigh))
    {
        Alert(symbol + " is over bought");
    }
    // 超卖判断
    else if((RSI < 25) && (Stoc < 20) && (BoliLower > CandlePrevLow))
    {
        Alert(symbol + " is over sold");
    }
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // 遍历Market Watch里的所有品种
    for(int i = 0; i < SymbolsTotal(true); i++)
    {
        string currentSymbol = SymbolName(i, true);
        CheckSymbolAlert(currentSymbol);
    }
}
//+------------------------------------------------------------------+

关键修改点说明

  • 封装判断函数:把原来的指标计算和预警逻辑放到CheckSymbolAlert()里,接收品种参数,实现逻辑复用,每个品种都能单独调用。
  • 遍历品种列表:在OnTick()里用for循环遍历所有品种,通过SymbolName()获取每个品种的名称。
  • 修正参数错误:将原代码中默认取当前图表品种的NULL替换为传入的symbol参数;同时修正了获取前一根K线高低的函数错误(原代码用了iOpen/iClose,应该用iHigh/iLow)。
  • 品种有效性检查:用SymbolSelect(symbol, true)确保品种可交易且在Market Watch中显示,避免无效品种导致运行报错。

额外优化建议

  1. 性能控制:如果Market Watch里品种较多,每次OnTick都遍历所有品种可能会占用资源,可以添加时间间隔判断,比如每5分钟批量检查一次,而非每个tick都执行。
  2. 品种过滤:如果只想针对主要/次要外汇品种,可以在循环中增加过滤逻辑,比如检查品种名称是否包含EUR/USD等关键词,或者通过SymbolInfoString函数判断品种的基础货币和报价货币是否为外汇币种。

内容的提问来源于stack exchange,提问作者Patrick Aipoh

火山引擎 最新活动