Summary: 本文全面讲解MQL4中最核心的三个技术指标函数:iMA移动平均线、iRSI相对强弱指标和iMACD指数平滑异同移动平均线,包括正确的语法格式、参数配置和实际EA应用示例。




一、为什么技术指标对EA开发至关重要

技术指标是智能交易系统(EA)的眼睛。它们将原始价格数据转化为可执行的交易信号。没有指标,你的EA只能对基础的价格变动做出反应。掌握iMA、iRSI和iMACD,你就能实现全球成功交易者使用的大多数专业交易策略。

二、技术指标完整速查表

| 指标 | 函数名 | 核心参数 | 返回值 | 主要用途 |
|------|--------|----------|--------|----------|
| iMA(移动平均线) | iMA() | symbol, timeframe, period, shift, method, applied price, shift index | double(MA值) | 判断趋势方向和强度 |
| iRSI(相对强弱指数) | iRSI() | symbol, timeframe, period, applied price, shift index | double(0-100) | 识别超买超卖状态 |
| iMACD(指数平滑异同移动平均线) | iMACD() | symbol, timeframe, fast period, slow period, signal period, applied price, mode, shift | double(MACD线或信号线) | 判断动量和趋势变化 |

三、iMA - 移动平均线(趋势跟踪)

移动平均线是外汇交易中使用最广泛的指标。它平滑价格数据,帮助识别趋势方向和潜在的反转点。

iMA函数语法和参数详解
```mql4
double iMA(
string symbol, // 品种名称(NULL表示当前品种)
int timeframe, // 时间周期(0表示当前图表周期)
int period, // MA周期(如14、20、50、200)
int ma_shift, // MA水平偏移(通常为0)
int ma_method, // MA计算方法(SMA、EMA、SMMA、LWMA)
int applied_price, // 应用价格(收盘价、开盘价等)
int shift // 偏移索引(0=当前K线,1=上一根K线)
);
```

MA计算方法常量
| 常量 | 值 | 说明 |
|------|-----|------|
| MODE_SMA | 0 | 简单移动平均线 |
| MODE_EMA | 1 | 指数移动平均线 |
| MODE_SMMA | 2 | 平滑移动平均线 |
| MODE_LWMA | 3 | 线性加权移动平均线 |

应用价格常量
| 常量 | 值 | 说明 |
|------|-----|------|
| PRICE_CLOSE | 0 | 收盘价 |
| PRICE_OPEN | 1 | 开盘价 |
| PRICE_HIGH | 2 | 最高价 |
| PRICE_LOW | 3 | 最低价 |
| PRICE_MEDIAN | 4 | 中间价(最高+最低)/2 |
| PRICE_TYPICAL | 5 | 典型价(最高+最低+收盘)/3 |
| PRICE_WEIGHTED | 6 | 加权收盘价(最高+最低+2×收盘)/4 |

完整iMA代码示例
```mql4
// 基础移动平均线交叉检测
int CheckMACrossover() {
// 获取当前和之前的MA值
double maFastCurrent = iMA(NULL, 0, 10, 0, MODE_EMA, PRICE_CLOSE, 0);
double maSlowCurrent = iMA(NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0);
double maFastPrevious = iMA(NULL, 0, 10, 0, MODE_EMA, PRICE_CLOSE, 1);
double maSlowPrevious = iMA(NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 1);

// 检查交叉
if(maFastCurrent > maSlowCurrent && maFastPrevious <= maSlowPrevious) {
return SIGNAL_BUY; // 金叉
}
else if(maFastCurrent < maSlowCurrent && maFastPrevious >= maSlowPrevious) {
return SIGNAL_SELL; // 死叉
}
return SIGNAL_NONE;
}

// 多周期移动平均线分析
void AnalyzeMultiTimeframeMA() {
int timeframes[] = {PERIOD_M15, PERIOD_H1, PERIOD_H4, PERIOD_D1};
string tfNames[] = {"M15", "H1", "H4", "D1"};

for(int i = 0; i < 4; i++) {
double ma50 = iMA(NULL, timeframes[i], 50, 0, MODE_SMA, PRICE_CLOSE, 0);
double ma200 = iMA(NULL, timeframes[i], 200, 0, MODE_SMA, PRICE_CLOSE, 0);

string trend = (ma50 > ma200) ? "上涨" : "下跌";
Print(tfNames[i], " - MA50: ", ma50, " MA200: ", ma200, " 趋势: ", trend);
}
}

// 移动平均线斜率(方向和强度)
double GetMASlope(int period, int lookbackBars = 5) {
double maNow = iMA(NULL, 0, period, 0, MODE_EMA, PRICE_CLOSE, 0);
double maPast = iMA(NULL, 0, period, 0, MODE_EMA, PRICE_CLOSE, lookbackBars);

// 计算每根K线的斜率(点数)
double slope = (maNow - maPast) / lookbackBars / Point();
return slope;
}

// 价格与移动平均线的距离
double GetPriceToMADistance(int period, double &distancePercent) {
double ma = iMA(NULL, 0, period, 0, MODE_SMA, PRICE_CLOSE, 0);
double currentPrice = Close[0];

double distancePoints = (currentPrice - ma) / Point();
distancePercent = (currentPrice - ma) / ma * 100;

return distancePoints;
}

// 使用多条MA进行趋势强度评估
int AssessTrendStrength() {
double ma20 = iMA(NULL, 0, 20, 0, MODE_EMA, PRICE_CLOSE, 0);
double ma50 = iMA(NULL, 0, 50, 0, MODE_EMA, PRICE_CLOSE, 0);
double ma100 = iMA(NULL, 0, 100, 0, MODE_EMA, PRICE_CLOSE, 0);
double ma200 = iMA(NULL, 0, 200, 0, MODE_EMA, PRICE_CLOSE, 0);

// 统计多头排列数量
int bullishCount = 0;
if(ma20 > ma50) bullishCount++;
if(ma50 > ma100) bullishCount++;
if(ma100 > ma200) bullishCount++;

// 统计空头排列数量
int bearishCount = 0;
if(ma20 < ma50) bearishCount++;
if(ma50 < ma100) bearishCount++;
if(ma100 < ma200) bearishCount++;

if(bullishCount >= 3) return TREND_STRONG_BULLISH;
if(bearishCount >= 3) return TREND_STRONG_BEARISH;
if(bullishCount >= 2) return TREND_WEAK_BULLISH;
if(bearishCount >= 2) return TREND_WEAK_BEARISH;
return TREND_SIDEWAYS;
}
```

四、iRSI - 相对强弱指数(动量震荡指标)

RSI通过测量近期价格变动的幅度来评估超买或超卖状态。70以上表示超买,30以下表示超卖。

iRSI函数语法和参数详解
```mql4
double iRSI(
string symbol, // 品种名称(NULL表示当前品种)
int timeframe, // 时间周期(0表示当前图表周期)
int period, // RSI周期(通常为14)
int applied_price, // 应用价格(通常使用PRICE_CLOSE)
int shift // 偏移索引(0=当前K线,1=上一根K线)
);
```

完整iRSI代码示例
```mql4
// 基础RSI信号生成
int GenerateRSISignal(int rsiPeriod = 14, int overbought = 70, int oversold = 30) {
double rsi = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 0);
double rsiPrevious = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 1);

// 超买/超卖水平判断
if(rsi < oversold && rsiPrevious >= oversold) {
return SIGNAL_BUY; // 离开超卖区 - 买入信号
}
else if(rsi > overbought && rsiPrevious <= overbought) {
return SIGNAL_SELL; // 离开超买区 - 卖出信号
}

// 极端水平
if(rsi < 20) return SIGNAL_STRONG_BUY;
if(rsi > 80) return SIGNAL_STRONG_SELL;

return SIGNAL_NONE;
}

// RSI背离检测(高级)
int DetectRSIDivergence(int rsiPeriod = 14) {
// 获取当前和之前的价格及RSI值
double priceCurrent = Close[0];
double pricePrevious = Close[1];
double priceTwoBarsAgo = Close[2];

double rsiCurrent = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 0);
double rsiPrevious = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 1);
double rsiTwoBarsAgo = iRSI(NULL, 0, rsiPeriod, PRICE_CLOSE, 2);

// 底背离:价格创新低,RSI未创新低
bool bullishDivergence = (priceCurrent < pricePrevious &&
pricePrevious < priceTwoBarsAgo &&
rsiCurrent > rsiPrevious &&
rsiPrevious > rsiTwoBarsAgo);

// 顶背离:价格创新高,RSI未创新高
bool bearishDivergence = (priceCurrent > pricePrevious &&
pricePrevious > priceTwoBarsAgo &&
rsiCurrent < rsiPrevious &&
rsiPrevious < rsiTwoBarsAgo);

if(bullishDivergence) return SIGNAL_BUY;
if(bearishDivergence) return SIGNAL_SELL;
return SIGNAL_NONE;
}

// RSI失败摆动(经典反转形态)
int DetectRSIFailureSwing() {
double rsi0 = iRSI(NULL, 0, 14, PRICE_CLOSE, 0);
double rsi1 = iRSI(NULL, 0, 14, PRICE_CLOSE, 1);
double rsi2 = iRSI(NULL, 0, 14, PRICE_CLOSE, 2);
double rsi3 = iRSI(NULL, 0, 14, PRICE_CLOSE, 3);

// 底部失败摆动:RSI跌破30后反弹,再次下跌未触及30
if(rsi2 < 30 && rsi1 < 30 && rsi0 > 30 && rsi0 > rsi1) {
return SIGNAL_BUY;
}

// 顶部失败摆动:RSI突破70后回落,再次上涨未触及70
if(rsi2 > 70 && rsi1 > 70 && rsi0 < 70 && rsi0 < rsi1) {
return SIGNAL_SELL;
}

return SIGNAL_NONE;
}

// 多周期RSI确认
bool IsMultiTimeframeRSIConfirmed(int higherTimeframe = PERIOD_H1) {
double rsiCurrent = iRSI(NULL, 0, 14, PRICE_CLOSE, 0);
double rsiHigher = iRSI(NULL, higherTimeframe, 14, PRICE_CLOSE, 0);

// 两个周期必须同向(都超卖或都超买)
bool bothOversold = (rsiCurrent < 30 && rsiHigher < 30);
bool bothOverbought = (rsiCurrent > 70 && rsiHigher > 70);

return (bothOversold || bothOverbought);
}

// RSI趋势线突破检测
bool IsRSITrendLineBroken(int lookback = 10, bool isUptrend = true) {
double rsiValues[];
ArrayResize(rsiValues, lookback);

for(int i = 0; i < lookback; i++) {
rsiValues[i] = iRSI(NULL, 0, 14, PRICE_CLOSE, i);
}

if(isUptrend) {
// 检查RSI是否跌破上涨趋势线
// 简化版:检查当前RSI是否低于近期低点
double recentLow = rsiValues[ArrayMinimum(rsiValues, 1, lookback-1)];
return (rsiValues[0] < recentLow);
} else {
double recentHigh = rsiValues[ArrayMaximum(rsiValues, 1, lookback-1)];
return (rsiValues[0] > recentHigh);
}
}
```

五、iMACD - 指数平滑异同移动平均线(趋势和动量)

MACD显示两条移动平均线之间的关系。它由MACD线(快线-慢线)、信号线(MACD线的EMA)和柱状图(MACD-信号线)组成。

iMACD函数语法和参数详解
```mql4
double iMACD(
string symbol, // 品种名称
int timeframe, // 时间周期
int fast_ema_period, // 快线EMA周期(通常为12)
int slow_ema_period, // 慢线EMA周期(通常为26)
int signal_period, // 信号线周期(通常为9)
int applied_price, // 应用价格(通常为PRICE_CLOSE)
int mode, // MODE_MAIN或MODE_SIGNAL
int shift // 偏移索引
);
```

MACD模式常量
| 常量 | 值 | 说明 |
|------|-----|------|
| MODE_MAIN | 0 | MACD主线(快线-慢线) |
| MODE_SIGNAL | 1 | MACD信号线(主线的EMA) |

完整iMACD代码示例
```mql4
// 基础MACD交叉信号
int GenerateMACDSignal() {
double macdMain = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
double macdSignal = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 0);
double macdMainPrev = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
double macdSignalPrev = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);

// 金叉:MACD线上穿信号线
if(macdMain > macdSignal && macdMainPrev <= macdSignalPrev) {
return SIGNAL_BUY;
}
// 死叉:MACD线下穿信号线
else if(macdMain < macdSignal && macdMainPrev >= macdSignalPrev) {
return SIGNAL_SELL;
}
return SIGNAL_NONE;
}

// MACD柱状图(MACD线 - 信号线),用于零轴穿越检测
double GetMACDHistogram() {
double macdMain = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
double macdSignal = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 0);
return macdMain - macdSignal;
}

// MACD零轴穿越
int CheckMACDZeroLine() {
double macdCurrent = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
double macdPrevious = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);

if(macdCurrent > 0 && macdPrevious <= 0) {
return SIGNAL_BUY; // 上穿零轴 - 看涨
}
else if(macdCurrent < 0 && macdPrevious >= 0) {
return SIGNAL_SELL; // 下穿零轴 - 看跌
}
return SIGNAL_NONE;
}

// MACD背离检测
int DetectMACDDivergence() {
// 价格数据
double priceCurrent = Close[0];
double pricePrevious = Close[1];
double priceTwoBarsAgo = Close[2];

// MACD数据
double macdCurrent = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
double macdPrevious = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
double macdTwoBarsAgo = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 2);

// 底背离:价格创新低,MACD未创新低
bool bullishDiv = (priceCurrent < pricePrevious &&
pricePrevious < priceTwoBarsAgo &&
macdCurrent > macdPrevious &&
macdPrevious > macdTwoBarsAgo);

// 顶背离:价格创新高,MACD未创新高
bool bearishDiv = (priceCurrent > pricePrevious &&
pricePrevious > priceTwoBarsAgo &&
macdCurrent < macdPrevious &&
macdPrevious < macdTwoBarsAgo);

if(bullishDiv) return SIGNAL_BUY;
if(bearishDiv) return SIGNAL_SELL;
return SIGNAL_NONE;
}

// MACD斜率(动量强度)
double GetMACDSlope(int lookbackBars = 3) {
double macdNow = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
double macdPast = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, lookbackBars);

return (macdNow - macdPast) / lookbackBars;
}
```

六、完整EA示例(同时使用三种指标)

```mql4
//+------------------------------------------------------------------+
//| MultiIndicatorEA.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property version "1.00"
#property strict

input double InpLotSize = 0.1;
input int InpMagic = 12345;
input int InpStopLoss = 50;
input int InpTakeProfit = 100;

// 信号常量
#define SIGNAL_NONE 0
#define SIGNAL_BUY 1
#define SIGNAL_SELL 2

//+------------------------------------------------------------------+
//| 结合三种指标的综合信号生成函数 |
//+------------------------------------------------------------------+
int GenerateCombinedSignal() {
// 获取指标值
double maFast = iMA(NULL, 0, 10, 0, MODE_EMA, PRICE_CLOSE, 0);
double maSlow = iMA(NULL, 0, 30, 0, MODE_EMA, PRICE_CLOSE, 0);
double rsi = iRSI(NULL, 0, 14, PRICE_CLOSE, 0);
double macdMain = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0);
double macdSignal = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 0);
double macdPrev = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
double signalPrev = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_SIGNAL, 1);

// 趋势条件(MA)
bool bullishTrend = (maFast > maSlow);
bool bearishTrend = (maFast < maSlow);

// 动量条件(RSI)
bool oversold = (rsi < 30);
bool overbought = (rsi > 70);

// MACD条件
bool macdBullish = (macdMain > macdSignal && macdPrev <= signalPrev);
bool macdBearish = (macdMain < macdSignal && macdPrev >= signalPrev);

// 综合信号(至少2个指标确认)
if(bullishTrend && oversold && macdBullish) {
return SIGNAL_BUY;
}
else if(bearishTrend && overbought && macdBearish) {
return SIGNAL_SELL;
}

// 回退到简单信号
if(bullishTrend && oversold) return SIGNAL_BUY;
if(bearishTrend && overbought) return SIGNAL_SELL;
if(macdBullish) return SIGNAL_BUY;
if(macdBearish) return SIGNAL_SELL;

return SIGNAL_NONE;
}

//+------------------------------------------------------------------+
//| EA主执行函数 |
//+------------------------------------------------------------------+
void OnTick() {
static datetime lastBarTime = 0;
if(Time[0] == lastBarTime) return;
lastBarTime = Time[0];

int signal = GenerateCombinedSignal();

if(signal == SIGNAL_BUY && CountOrders(InpMagic) == 0) {
OpenBuyOrder();
}
else if(signal == SIGNAL_SELL && CountOrders(InpMagic) == 0) {
OpenSellOrder();
}
}

//+------------------------------------------------------------------+
//| 开立买入订单 |
//+------------------------------------------------------------------+
void OpenBuyOrder() {
double sl = Ask - InpStopLoss * Point();
double tp = Ask + InpTakeProfit * Point();
int ticket = OrderSend(Symbol(), OP_BUY, InpLotSize, Ask, 30, sl, tp, "MultiIndicator EA", InpMagic, 0, clrGreen);
if(ticket > 0) Print("买入订单已开立:", ticket);
}

//+------------------------------------------------------------------+
//| 开立卖出订单 |
//+------------------------------------------------------------------+
void OpenSellOrder() {
double sl = Bid + InpStopLoss * Point();
double tp = Bid - InpTakeProfit * Point();
int ticket = OrderSend(Symbol(), OP_SELL, InpLotSize, Bid, 30, sl, tp, "MultiIndicator EA", InpMagic, 0, clrRed);
if(ticket > 0) Print("卖出订单已开立:", ticket);
}

//+------------------------------------------------------------------+
//| 按魔术号统计订单数量 |
//+------------------------------------------------------------------+
int CountOrders(int magic) {
int count = 0;
for(int i = 0; i < OrdersTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderMagicNumber() == magic) count++;
}
}
return count;
}
```

七、多周期指标策略

```mql4
// 多周期确认策略
int GetMultiTimeframeSignal() {
int buyVotes = 0;
int sellVotes = 0;

int timeframes[] = {PERIOD_M15, PERIOD_H1, PERIOD_H4};

for(int i = 0; i < 3; i++) {
int tf = timeframes[i];

double rsi = iRSI(NULL, tf, 14, PRICE_CLOSE, 0);
double maFast = iMA(NULL, tf, 10, 0, MODE_EMA, PRICE_CLOSE, 0);
double maSlow = iMA(NULL, tf, 30, 0, MODE_EMA, PRICE_CLOSE, 0);

bool bullish = (maFast > maSlow && rsi < 40);
bool bearish = (maFast < maSlow && rsi > 60);

if(bullish) buyVotes++;
if(bearish) sellVotes++;
}

if(buyVotes >= 2) return SIGNAL_BUY;
if(sellVotes >= 2) return SIGNAL_SELL;
return SIGNAL_NONE;
}
```

八、指标使用最佳实践清单

  • [ ] 始终验证指标返回值(非零为有效值)

  • [ ] 使用偏移索引0表示当前K线,1表示上一根K线,避免未来函数偏差

  • [ ] 在同一Tick中重复调用相同指标时,应缓存指标值

  • [ ] 使用多周期分析获得更强的信号确认

  • [ ] 组合多个指标过滤假信号

  • [ ] 根据市场环境(趋势市vs震荡市)调整指标参数

  • [ ] 实盘部署前在历史数据上测试指标策略

  • [ ] 注意:大周期指标可能存在重绘现象

  • [ ] 内置指标不足时使用iCustom()调用自定义指标


  • 参考来源:

  • MetaQuotes Ltd.《MQL4官方文档 - 技术指标》(2024)

  • Wilder, J. Welles.《技术交易系统新概念》(1978)

  • Murphy, John J.《金融市场技术分析》(1999)

  • 张强.《MQL4指标编程从入门到精通》(2023)


  • 9. 下一步

    第14篇将讲解账户与市场信息函数 – 账户余额、净值、保证金、买卖报价和市场信息的完整指南,附带实际的风险管理示例。