1. 程式人生 > 其它 >mq5 EA模板及雙均線金叉死叉買賣EAdemo

mq5 EA模板及雙均線金叉死叉買賣EAdemo

技術標籤:K線技術分析量化交易mq5EA

//+------------------------------------------------------------------+
//|                                                  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