《MT4EA编程速成教程》中第33页习题:
第二题:将交易信号改成MACD交叉,金叉做多,死叉做空。
这道题的重点和难点就是获取MACD的指标值,MACD和之前的抛物线指标或者均线指标不一样,稍微复杂些。
MACD指标有两个缓存数组,一个显示的是柱体部分,一个显示的是红色虚线。
double iMACD(
string symbol, // 品种
int timeframe, // 时间周期
int fast_ema_period, // 快线周期
int slow_ema_period, // 慢线周期
int signal_period, // 信号线周期
int applied_price, // 应用于价格
int mode, // 线索引
int shift // 位移
);
系统规定,柱体部分的线索引为0,常量是,红色虚线的线索引为1。
下面是MQL4参考中的常量信息:
ID | Value | Description |
---|---|---|
MODE_MAIN | 0 | 基础指标线 |
MODE_SIGNAL | 1 | 信号线 |
获取MACD指标基础指标线和信号线的值,可以用如下参数:
//如果要获取位移为1的MACD的柱体指标值,可以用如下参数:
double macd_main1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
//如果要获取位移为2的MACD的柱体指标值,可以用如下参数:
double macd_main2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
//如果要获取位移为1的MACD的信号线指标值,可以用如下参数:
double macd_signal1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
//如果要获取位移为2的MACD的信号线指标值,可以用如下参数:
double macd_signal2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,2);
金叉和死叉就是四个数据的比较了,信号函数修改如下
int signal()
{
int res=0;
//如果要获取位移为1的MACD的柱体指标值,可以用如下参数:
double macd_main1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
//如果要获取位移为2的MACD的柱体指标值,可以用如下参数:
double macd_main2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
//如果要获取位移为1的MACD的信号线指标值,可以用如下参数:
double macd_signal1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
//如果要获取位移为2的MACD的信号线指标值,可以用如下参数:
double macd_signal2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,2);
if(macd_main1>macd_signal1 && macd_main2<macd_signal2)
{
res=1;
}
if(macd_main1<macd_signal1 && macd_main2>macd_signal2)
{
res=-1;
}
return(res);
}
//+------------------------------------------------------------------+
这个EA的完整代码如下:
//+------------------------------------------------------------------+
//| Test_EA_05_2.mq4 |
//| 云开 |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "http://www.forexmt4.cn"
#property link "http://www.forexmt4.cn"
#property description "【漆天编程】 习题EA2"
#property description " "
#property description "这是一款测试EA,作者QQ:80364276"
#property description " "
#property description "发布时间:2021.10.26"
#property strict
#property icon "//Images//sea.ico"
input double lots=0.1; //交易手数
input int SL=600; //止损点数
input int TP=200; //止盈点数
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
int buys=0; //多单持仓有几笔
int sells=0; //空单持仓有几笔
int signal=signal();
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_BUY)
{
buys++;
if(signal<0)
{
bool res=OrderClose(OrderTicket(),OrderLots(),Bid,0);
if(res)
{
Print("订单平仓成功");
}
return;
}
if(OrderStopLoss()==0)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-SL*Point,OrderOpenPrice()+TP*Point,0);
if(res)
Print("订单修改成功");
}
}
if(OrderSymbol()==Symbol() && OrderMagicNumber()==16384 && OrderType()==OP_SELL)
{
sells++;
if(OrderStopLoss()==0)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+SL*Point,OrderOpenPrice()-TP*Point,0);
if(res)
Print("订单修改成功");
}
if(signal>0)
{
bool res=OrderClose(OrderTicket(),OrderLots(),Ask,0);
if(res)
{
Print("订单平仓成功");
}
return;
}
}
}
}
//---
if(signal>0 && buys==0)
{
int ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,3,0,0,"My buy order",16384,0,clrGreen);
if(ticket<0)
{
Print("OrderSend failed with error #",GetLastError());
}
else
{
Print("OrderSend placed successfully");
}
}
if(signal<0 && sells==0)
{
int ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,3,0,0,"My sell order",16384,0,clrRed);
if(ticket<0)
{
Print("OrderSend failed with error #",GetLastError());
}
else
{
Print("OrderSend placed successfully");
}
}
}
//+------------------------------------------------------------------+
int signal()
{
int res=0;
//如果要获取位移为1的MACD的柱体指标值,可以用如下参数:
double macd_main1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
//如果要获取位移为2的MACD的柱体指标值,可以用如下参数:
double macd_main2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
//如果要获取位移为1的MACD的信号线指标值,可以用如下参数:
double macd_signal1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
//如果要获取位移为2的MACD的信号线指标值,可以用如下参数:
double macd_signal2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,2);
if(macd_main1>macd_signal1 && macd_main2<macd_signal2)
{
res=1;
}
if(macd_main1<macd_signal1 && macd_main2>macd_signal2)
{
res=-1;
}
return(res);
}
//+------------------------------------------------------------------+
一单一结的EA使用了这个模版之后,只需要修改信号函数部分,是不是很简单?