一、为什么技术指标对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;
}
```
八、指标使用最佳实践清单
参考来源:
9. 下一步
第14篇将讲解账户与市场信息函数 – 账户余额、净值、保证金、买卖报价和市场信息的完整指南,附带实际的风险管理示例。