EA框架模型,大部分地方做了注释
[code]现在我学会了EA基本的东西,并且按照框架思路 建立了EA框架模型,大部分地方做了注释。希望对大家有用;程序代码如下:
//+------------------------------------------------------------------+
//| ganendexin's 模板.mq4 |
//| Copyright ?2008, MetaQuotes Software Corp. |
//| http://www.520fx.com
//+------------------------------------------------------------------+
#property copyright "ganendexin"
#property link "http://www.520fx.com"
//---- input parameters
extern double TakeProfit=250.0;
extern double Lots=0.1;
extern double TrailingStop=35.0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//信号部分,下面这部分给出的是买卖信号,这个信号可以是自己编写的,也可以是用iCustom来调用的。以后需要修改的大部分是在这里面改
int Crossed (double line1 , double line2)
{
static int last_direction = 0;
static int current_direction = 0;
if(line1>line2)current_direction = 1; //up
if(line1<line2)current_direction = 2; //down
if(current_direction != last_direction) //changed
{
last_direction = current_direction;
return (last_direction);
}
else
{
return (0);
}
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//程序开始前,先定义变量。
int cnt, ticket, total; //用于检查订单的个数及类型,cnt是按照索引来计算,ticket是按照ticket来计算。在算类型之前,要先OrderSelect
double shortEma, longEma; //这个地方是定义买卖信号的参数的,根据实际需要来定个数和类型。
int counted_bars;
//如果需要控制最低的K线个数,可用下面的
//提示获利点,这个是有的系统对最小获利点有要求的情况下使用。例如FXDD要求为10.
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return(0); // check TakeProfit
}
//信号函数里面的,参数的取得 重点
shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);
longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0);
//把计算过的信号返回,并由这个信号来选择开仓等操作。
int isCrossed = Crossed (shortEma,longEma);
//判断持仓状态,
//把仓单总数赋值给一个变量,用于下一步计算仓单情况
total = OrdersTotal();
//空仓情况开始
//如果有空仓,则计算
if(total < 1)
{
//如果出现买的信号
if(isCrossed == 1)
{
//建立buy单,即多仓,
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,
"My EA",12345,0,Green);
//判断是否建仓成功,建仓成功,ticket被赋值为个数字,不是初始的0
if(ticket>0)
{
//检查是否已经成交,重点是检查不是挂单 注意参数 MODE_TRADES
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
//打印出开仓价格
Print("已BUY,价格为: ",OrderOpenPrice());
}
//如果建仓失败,打印出错误提示
else Print("建BUY仓失败: ",GetLastError());
//建仓失败后,立即返回,并进行一下次的计算
return(0);
}
//如果卖单信号出现 ,注意,此时仍然是指在空仓状态下
if(isCrossed == 2)
{
//建立SELL单,即空头仓,
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,
Bid-TakeProfit*Point,"My EA",12345,0,Red);
//如果建仓成功
if(ticket>0)
{
//检查是否已经成交,而不是挂单
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL order opened : ",OrderOpenPrice());
}
//建仓失败,输出提示
else Print("Error opening SELL order : ",GetLastError());
//立即返回,准备下一次的计算。
return(0);
}
//如果买卖条件都没有满足,即if(isCrossed!=1&&isCrossed!=2)则直接返回
return(0);
//空仓情结束
}
//如果持仓,注意,这里省略了一个else,即if(ticket>0) else,而程序之所以不写else,是因为,当(ticket>0)时,不执行if(ticket<0);这体现出编程者对语句的熟练和深刻理解。希望看这个程序的新手多用心体会。
//开始计算仓单总数,并对所有已持仓当进行判断 ,这里用cnt=0作为开始,是以仓当的索引值开始判断的,而不是ticket。
for(cnt=0;cnt<total;cnt++) //从索引值为0的仓单开始,直到计算完所有的仓当int total=OrdersTotal;
{
//选择仓当,在使用order相关的函数时,必须先运行一次OrderSelect
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
//如果是持有的是买单
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()) //OP_SELL的值为1,OP_BUY的值为0。这里,指如果持有买、卖单,而不是挂单,并且货币兑是当前图表的货币对
{
//判断持有buy单即多头单的情况
if(OrderType()==OP_BUY) // long position is opened
{
// 卖单信号开始 should it be closed? 如果出现了卖的信号
if(isCrossed == 2)
{
//平仓buy单
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);
// close position 之后立即返回,不管平仓是否成功,如果不成功,则重新回到循环里面,并重新判断索引值为0的订单,因为不管成功与否,会一直判断索引值为0的仓单,当仓单被平后,就没有索引值了。另外,这里说的是,在有卖信号下,对buy单的处理,sell单的索引不会被这个if语句里的OrderClose所执行
return(0); // exit
}
// check for trailing stop 如果没有出新新信号,注意(此时已经是持有buy单了)检查移动止损,并修改止损和和获利点
if(TrailingStop>0) //如果追踪止损大于0,
{
if(Bid-OrderOpenPrice()>Point*TrailingStop) //如果获利(现在的买价减去开仓价格)大于 追踪止损的值
{
if(OrderStopLoss()<Bid-Point*TrailingStop) //如果单子的止损点比追踪止损点小
{
//修改订单的止损点为追踪止损点
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-
Point*TrailingStop,OrderTakeProfit(),0,Green);
//修改完后立刻返回
return(0);
}
}
}
// 卖单信号结束
}
else // go to short position
{
// 买buy单信号开始 should it be closed? 注意,此时仍处于,所有仓单的检查和循环中,即操作完成后,立刻返回到仓位检查状态,并开始执行
if(isCrossed == 1) //出现买单信号
{
//平仓卖单
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet);
// close position
//立刻返回,不管是否成功,并重新进行下一次的运算
return(0); // exit
}
// check for trailing stop 检查止损点
if(TrailingStop>0) //如果止损价大于0
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) //如果获利点(开仓价格-现在的卖价)大于追踪止损价
{ if((OrderStopLoss()>(Ask+Point*TrailingStop)) ||(OrderStopLoss()==0)) //如果止损点大于止损假
{
//修改订单的止损价个为现在的追踪止损价格
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,
OrderTakeProfit(),0,Red);
//修改后,立刻返回
return(0);
}
}
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+[/code]
页:
[1]