mq5 EA模板及双均线金叉死叉买卖EAdemo

//+------------------------------------------------------------------+
//|                                                  mt5_ea_demo.mq5 |
//|                                Copyright 吕海洋 QQ交流群:157528427|
//|                            https://www.mql5.com/zh/signals/789037|
//+------------------------------------------------------------------+
#property copyright "Copyright 吕海洋 QQ交流群:157528427"
#property link      "https://www.mql5.com/zh/signals/789037"
#property version   "1.00"

#include <Trade\trade.mqh>
#include <Trade\PositionInfo.mqh>

//EA模板,封装了常用的订单操作,新建的类继承这个模板可以直接调用方法
class TradeSystem
   {
public:
   CTrade trade;
   //获取最后一笔历史订单获利
   //magic_number: 幻数(用来标记是EA建仓的单子)
   //symbol:货币名称
   //cmt: 订单注释信息
   //order_type: 订单类型 "BUY","SELL"
   double GetLastProfit(ulong magic_number, string symbol, string cmt, string order_type)
      {
         ENUM_DEAL_TYPE deal_type;
         
         if(order_type == "BUY")
            {
               deal_type = DEAL_TYPE_SELL;
            }
         else if(order_type == "SELL")
            {
               deal_type = DEAL_TYPE_BUY;
            }
         else return 0;
              
         ulong ticket;
         double last_profit = 0;
         //--- 请求交易历史记录 
         HistorySelect(0,TimeCurrent()); 
         //--- 当前挂单数量 
         int total=HistoryDealsTotal(); 
         //--- 循环检测通过订单 
         for(int i=total -1;i>=0;i--) 
           { 
            //--- 通过其列表中的位置返回订单报价 
               if((ticket=HistoryDealGetTicket(i))>0) 
                  {
                     if(HistoryDealGetInteger(ticket,DEAL_MAGIC)==magic_number && HistoryDealGetString(ticket,DEAL_SYMBOL)==symbol)
                        {
                           if(HistoryDealGetInteger(ticket,DEAL_TYPE)==deal_type && HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)
                              {
                                 last_profit = HistoryDealGetDouble(ticket,DEAL_PROFIT);
                                 break;        
                              }
                        }
                  }
           }
           
         return last_profit;
      }

   //获取连续亏损次数
   //magic_number: 幻数(用来标记是EA建仓的单子)
   //symbol:货币名称
   //cmt: 订单注释信息
   //order_type: 订单类型 "BUY","SELL"
   int GetStopLossTimes(ulong magic_number, string symbol, string cmt, string order_type)
      {
         ENUM_DEAL_TYPE deal_type;
         
         if(order_type == "BUY")
            {
               deal_type = DEAL_TYPE_SELL;
            }
         else if(order_type == "SELL")
            {
               deal_type = DEAL_TYPE_BUY;
            } 
         else return 0;
         
         ulong ticket;
         int stop_loss_times = 0;
         //--- 请求交易历史记录 
         HistorySelect(0,TimeCurrent()); 
         //--- 当前挂单数量 
         int total=HistoryDealsTotal(); 
         //--- 循环检测通过订单 
         for(int i=total;i>=0;i--) 
           { 
            //--- 通过其列表中的位置返回订单报价 
               if((ticket=HistoryDealGetTicket(i))>0) 
                  {
                     if(HistoryDealGetInteger(ticket,DEAL_MAGIC)==magic_number && HistoryDealGetString(ticket,DEAL_SYMBOL)==symbol)
                        {
                           if(HistoryDealGetInteger(ticket,DEAL_TYPE)==deal_type && HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)
                              {
                                 if(HistoryDealGetDouble(ticket,DEAL_PROFIT) < 0) stop_loss_times++;
                                 else break;        
                              }
                        }
                  }
           }
 
         return stop_loss_times;
      }

   //获取最后一笔历史订单获利
   //magic_number: 幻数(用来标记是EA建仓的单子)
   //symbol:货币名称
   //cmt: 订单注释信息
   //order_type: 订单类型 "BUY","SELL"
   double GetLastPrice(ulong magic_number, string symbol, string cmt, string order_type)
      {
         ENUM_POSITION_TYPE postion_type;
         ENUM_DEAL_TYPE deal_type;
         
         if(order_type == "BUY")
            {
               postion_type = POSITION_TYPE_BUY;
               deal_type = DEAL_TYPE_SELL;
            }
         else if(order_type == "SELL")
            {
               postion_type = POSITION_TYPE_SELL;
               deal_type = DEAL_TYPE_BUY;
            }
         else return 0;
            
         ulong ticket;
         double last_create_price = 0;

         int total = PositionsTotal();
         for(int i=total;i>=0;i--)
            {
               ticket=PositionGetTicket(i);
               if(PositionGetInteger(POSITION_MAGIC)==magic_number && PositionGetString(POSITION_SYMBOL)==symbol)
                  {
                      if(PositionGetInteger(POSITION_TYPE)==postion_type)
                           {
                              last_create_price = PositionGetDouble(POSITION_PRICE_OPEN);
                              break;    
                           }
                  }
            }
         
         return last_create_price;
      }
      
   //开立订单
   //magic_number: 幻数(用来标记是EA建仓的单子)
   //open_lots: 开仓手数
   //symbol:货币名称
   //cmt: 订单注释信息
   //order_type: 订单类型 "BUY","SELL"
   double OpenOrder(ulong magic_number, string symbol, double open_lots, string cmt, string string_order_type)
      {
         ENUM_ORDER_TYPE order_type;
         
         if(string_order_type == "BUY")
            {
               order_type = ORDER_TYPE_BUY;
            }
         else if(string_order_type == "SELL")
            {
               order_type = ORDER_TYPE_SELL;
            }
         else return 0;

         double open_price = 0;
         trade.SetExpertMagicNumber(magic_number);
         trade.PositionOpen(symbol,order_type,open_lots,0,0,0,cmt);
         string info = "【" + cmt + "】";
         if(order_type == ORDER_TYPE_BUY) info += "多单";
         else if(order_type == ORDER_TYPE_SELL) info += "空单";

         //获取返回状态描述信息      
         uint rel_code = trade.ResultRetcode();
         if(rel_code == 10009)
            {
               open_price = trade.ResultPrice();
               info += "开仓成功 : 价格 = " + string(open_price);
               info += ";仓位 = " + string(open_lots);
            }
         else
            {
               info += "开仓失败 : " + string(rel_code);
            }
            
         SendInformation(info);
         return open_price;
      }

   //平仓
   //magic_number: 幻数(用来标记是EA建仓的单子)
   //symbol:货币名称
   //cmt: 订单注释信息
   //order_type: 订单类型 "BUY","SELL"
   bool CloseOrder(ulong magic_number, string symbol, string cmt, string order_type)
      {
         ENUM_POSITION_TYPE postion_type;
         
         if(order_type == "BUY")
            {
               postion_type = POSITION_TYPE_BUY;
            }
         else if(order_type == "SELL")
            {
               postion_type = POSITION_TYPE_SELL;
            }
         else return false;

         double close_price = 0;
         trade.SetExpertMagicNumber(magic_number);
         int total = PositionsTotal();
         for(int i=total;i>=0;i--)
            {
               ulong ticket=PositionGetTicket(i);
               if(PositionGetInteger(POSITION_MAGIC)==magic_number && PositionGetString(POSITION_SYMBOL)==symbol)
                  {
                     if(PositionGetInteger(POSITION_TYPE)==postion_type)
                        {
                           trade.PositionClose(ticket);
                           
                           string info = "【" + cmt + "】";
                           if(postion_type == POSITION_TYPE_BUY) info += "多单";
                           else if(postion_type == POSITION_TYPE_SELL) info += "空单";
                           
                           //获取返回状态描述信息  
                           uint rel_code = trade.ResultRetcode();
                           if(rel_code == 10009)
                              {
                                 close_price = trade.ResultPrice();
                                 double vloume = trade.ResultVolume();
                                 info += "平仓成功 : 价格 = " + string(close_price);
                                 info += ";仓位 = " + string(vloume);
                                 SendInformation(info); 
                                 return true;
                              }
                          else
                              {
                                 info += "平仓失败 : " + string(rel_code);
                                 SendInformation(info);
                                 return false;
                              }   
                        }
                  }
            }
         return false;
      } 

   //获取仓位信息
   //magic_number: 幻数(用来标记是EA建仓的单子)
   //symbol:货币名称
   //cmt: 订单注释信息
   //order_type: 订单类型 "BUY","SELL"
    double GetTotalOrders(ulong magic_number, string symbol, string cmt, string order_type)
         {
         ENUM_POSITION_TYPE postion_type;
         
         if(order_type == "BUY")
            {
               postion_type = POSITION_TYPE_BUY;
            }
         else if(order_type == "SELL")
            {
               postion_type = POSITION_TYPE_SELL;
            }
         else return 0;
         
         ulong ticket;
         double volumes = 0;
         int total = PositionsTotal();
         for(int i=total;i>=0;i--)
            {
               ticket=PositionGetTicket(i);
               if(PositionGetInteger(POSITION_MAGIC)==magic_number && PositionGetString(POSITION_SYMBOL)==symbol)
                  {
                     if(PositionGetInteger(POSITION_TYPE)==postion_type)
                        {
                           volumes += 1;
                        }
                  }
            }
               
           return volumes;
         }
   
    //发送消息    
    //information:要推送手机端/打印的消息
    void SendInformation(string information)
        {
           Print(information);
           SendNotification(information);
        }
   };
 
//EA模板
//两根均线,金叉买入,死叉卖出
class DemoSystem: public TradeSystem
   {
public:
   double base_lots;//每次开仓的数量
   string cmt;//订单注释信息
   ulong magic;//幻数
   string symbol;//货币名字

   double buy_open_price;//多单开仓价格
   double sell_open_price;//空单开仓价格

   int ma_peroid1;//短期均线周期
   int ma_peroid2;//长期均线周期

   //初始化EA系统
   void init(ulong p_magic, double p_lots, int p_ma_period1, int p_ma_period2)
      {
         symbol = Symbol();
         base_lots = p_lots;
         cmt = symbol;
         magic = p_magic;
         ma_peroid1 = p_ma_period1;
         ma_peroid2 = p_ma_period2;

         //初始化信息
         string info = "【" + cmt + "】" + "初始化EA\n";
         info += "ma1:" + string(ma_peroid1) + ";ma2:" + string(ma_peroid2);
         SendInformation(info);
      }

   //多单开仓
   void OpenBuy()
      {
         //检查是否有多单仓位
         double buy_total_orders = GetTotalOrders(magic, symbol, cmt, "BUY");
         // 如果没有仓位就建仓
         if(buy_total_orders == 0)
            {
               buy_open_price = OpenOrder(magic, symbol, base_lots, cmt, "BUY");
            }
      }
   //多单平仓
   void CloseBuy()
      {  
         //检查是否有多单仓位
         double buy_total_orders = GetTotalOrders(magic, symbol, cmt, "BUY");
         //如果有仓位就平仓
         if(buy_total_orders > 0)
            {
               for(int i=0;i<=buy_total_orders;i++)
                  {
                     if(CloseOrder(magic, symbol, cmt, "BUY"))
                        {
                           buy_open_price = 0;
                        }
                  }
            }
      }
   //空单开仓
   void OpenSell()
      {
         //检查是否有空单仓位
         double sell_total_orders = GetTotalOrders(magic, symbol, cmt, "SELL");
         // 如果没有仓位就建仓
         if(sell_total_orders == 0)
            {
               sell_open_price = OpenOrder(magic, symbol, base_lots, cmt, "SELL");
            }
      }
   //空单平仓
   void CloseSell()
      {
         //检查是否有空单仓位
         double sell_total_orders = GetTotalOrders(magic, symbol, cmt, "SELL");
         //如果有仓位就平仓
         if(sell_total_orders > 0)
            {
               for(int i=0;i<=sell_total_orders;i++)
                  {
                     if(CloseOrder(magic, symbol, cmt, "SELL"))
                        {
                           sell_open_price = 0;
                        }
                  }
            }
      }

   //运行EA
   void run()
      {
         //获取行情数据
         double close1 = iClose(symbol, 0, 1);

          // 初始化数组存放ma1指标
         double Buffer_ma1[]; 
         // 时间序列化数组
         ArraySetAsSeries(Buffer_ma1,true);
         // 获取ma指标
         int handle_ma1 = iMA(symbol,0,ma_peroid1,0,MODE_SMA,PRICE_CLOSE);
         // 赋值指标值到数组maBuffer
			CopyBuffer(handle_ma1,0,0,10,Buffer_ma1);
         // 获取当前K线的ma值和上一根K线的ma值
			double ma1_1 = Buffer_ma1[1];
         double ma1_2 = Buffer_ma1[2];

          // 初始化数组存放ma2指标
         double Buffer_ma2[]; 
         // 时间序列化数组
         ArraySetAsSeries(Buffer_ma2,true);
         // 获取ma指标
         int handle_ma2 = iMA(symbol,0,ma_peroid2,0,MODE_SMA,PRICE_CLOSE);
         // 赋值指标值到数组maBuffer
			CopyBuffer(handle_ma2,0,0,10,Buffer_ma2);
         // 获取当前K线的ma值和上一根K线的ma值
			double ma2_1 = Buffer_ma2[1];
         double ma2_2 = Buffer_ma2[2];

         //金叉建多单
         if(ma1_2 < ma2_2 && ma1_1 > ma2_1)
            {
               CloseSell();
               OpenBuy();
            }
         //死叉建空单
         else if(ma1_2 > ma2_2 && ma1_1 < ma2_1)
            {
               CloseBuy();
               OpenSell();
            }
      }
   };

ulong input_magic = 20210101;//幻数
input double input_lots = 0.01;//仓位
input int input_ma_period1 = 10;//MA短周期
input int input_ma_period2 = 50;//MA长周期

// 实例化EA类
DemoSystem ds;

//初始化脚本的时候执行一次
int OnInit()
  {
      ds.init(input_magic, input_lots, input_ma_period1, input_ma_period2);
      return(INIT_SUCCEEDED);
  }

//价格每次变化执行一次
void OnTick()
  {
      ds.run();
  }

git项目地址:https://github.com/lvhaiyang/mql_framework

欢迎加入量化投资技术交流QQ群:157528427

上一篇:linux下使用IPython编程工具


下一篇:[题解] 2019牛客暑期多校第三场H题 Magic Line