龙听期货论坛's Archiver

龙听 发表于 2017-10-30 14:55

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]