有您的持续关注
我们会做得更好

带中文说明的均线EA



Moving Average EA程序简短精悍,带有中文注释,在编程参考上面很是值得借鉴。

本网收集整理智能交易EA仅为MQL4编程爱好者提供语法及相关编程技巧的学习研究之用,智能交易存在极高的风险测试请用模拟盘,请勿用于实盘。Moving Average EA源码:

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                                     Copyright 2014, QQ:125808047 |
//+------------------------------------------------------------------+
#property copyright "www.125808047.com"
#property link      "http://www.125808047.com/"

#define MAGICMA   20050610                                                            // 定义本EA操作的订单的唯一标识号码

extern double Lots               = 0.01;                                              // 每单的交易量
extern double MaximumRisk        = 0.02;                                              // 作者定义的最大风险参数
extern double DecreaseFactor     = 3;                                                 // 作者定义的参数,作用要看程序中的用法
extern double MovingPeriod       = 10;                                                // EA中使用的均线的周期
extern double MovingShift        = 3;                                                 // EA中使用的均线向左的K线偏移量

//+------------------计算当前持仓单数量 子函数()------------------------------------+

int CalculateCurrentOrders(string symbol)                                             // 函数作用,计算当前持仓订单的数量
   {
   int buys=0,sells=0;                                                                // 定义两个临时变量,准备用于后面的多空订单的个数计算
   for(int i=0;i<OrdersTotal();i++)                                                   // 循环检测当前的订单队列
     {
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;                       // 挑出持仓单的每一个订单位置 。如果没有,则中断循环
     if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)                       // 根据订单位置,比较是否是当前K线商品 以及订单唯一标识号是否和本程序设置的一致
         {
         if(OrderType()==OP_BUY)   buys++;                                            // 找到符合条件的持仓单后,如果是多单,则临时变量buys增加1
         if(OrderType()==OP_SELL) sells++;                                            // 找到符合条件的持仓单后,如果是空单,则临时变量sells增加1
         }
     }

   if(buys>0) return(buys);                                                           // 如果买>0,则返回值为(buys)
   else    return(-sells);                                                            // 否则为带符号的sells个数值      本函数返回查询计算结束时的持仓单的个数。
   }
   
//+--------------------计算出订单交易量 子函数()------------------------------------+

double LotsOptimized()
   {
   double lot =Lots;
   int    orders =HistoryTotal();                                                     //  历史出场订单的个数
   int    losses =0;                                                                  //  number of losses orders without a break

   lot = NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);                   // 通过风险系数的计算获得当前入场单应该采用的交易量

   if(DecreaseFactor>0)                                                               // 减小因子
     {
      for(int i=orders-1; i>=0; i--)
        {
        if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) 
           { Print("Error in history!"); break; }                                     // 循环查询出场单队列
        if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;//
        if(OrderProfit()>0) break;
        if(OrderProfit()<0) losses++;                                                 // 循环计算所有出场亏损单的亏损总和
        }
      if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);              // 如果亏损额大于1,则下一入场单的交易量修正为新的计算结果。
     }

   if(lot<0.01) lot=0.01;                                                             // 如果计算出的交易量小于帐户最小手数0.1,则下一入场单的交易手数使用0.1作为交易量
   return(lot);
   }
//+------------------检查入场条件的情况并作处理 子函数--------------------------------+

void CheckForOpen()//
   {
    double ma;
    int   res;
   // ---- go trading only for first tiks of new bar
    if(Volume[0]>1) return;                                                           // 如果当前K线持仓量大于1,说明不是K线的开盘时间点,则直接返回 否则是K线第一个价格,则继续下面的过程

    ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);                   // 当前的均线(周期参数,平移值参数)的数值

    if(Open[1]>ma && Close[1]<ma)                                                     // 如果当前K开盘价大于均线,而前一K收盘价小于均线
      {
      res =OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);    // 则发出入场多单
      return;                                                                         // 发送后马上返回
      }

    if(Open[1]<ma && Close[1]>ma)                                                     // 如当前K开盘价小于均线,而前一K收盘价大于均线,
      {
      res =OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);    // 则发出入场空单
      return;                                                                         // 发送后马上返回
      }

   } 

//+------------------------------------------------------------------+
void CheckForClose()                                                                  //  作用:检查出场条件的情况并作处理
   {
double ma;
if(Volume[0]>1) return;
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);

for(int i=0;i<OrdersTotal();i++)
     {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)        break;
    if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
    if(OrderType()==OP_BUY)
       {
       if(Open[1]>ma && Close[1]<ma) 
       OrderClose(OrderTicket(),OrderLots(),Bid,3,White);                             // 如果持仓是多单,则当当前K开盘价小于均线,而前一K收盘价大于均线,则发出平仓指令
       break;
       }
    if(OrderType()==OP_SELL)
       {
       if(Open[1]<ma && Close[1]>ma) 
       OrderClose(OrderTicket(),OrderLots(),Ask,3,White);                              // 如果持仓是空单,则当当前K开盘价大于均线,而前一K收盘价小于均线,则发出平仓指令

       break;
       }
     }
   }
//+--------------------------主循环----------------------------------------+ 

void start()
   {
   if(Bars<100 || IsTradeAllowed()==false) return;
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();                            //  
   else  CheckForClose();

   }
//+------------------------------------------------------------------+(转)

 

如您喜欢此文章请点下面分享按钮↴峰汇在线 » 带中文说明的均线EA
上一篇:
下一篇:
分享到:更多 ()