MT5入门到精通之十二(交易类)

2017/4/30
一.常用交易函数封装
1.6种挂单类型
1.1.limit是亏损方向
buy limit
sell limit

1.2.stop是盈利方向
buy stop
sell stop

1.3.buy stop limit 先突破盈利方向 在回调
sell stop limit
2.交易类实现

//+------------------------------------------------------------------+
//|                                                        Trade.mqh |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class Trade
  {
private:

public:
   //slPoint = stop loss point止损点,tpPoint = take profit Point止盈点
   int               buy(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   int               buyPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   //买入挂单
   int               buyPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   int               buyPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   //买入stop limit
   int               buyPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   int               buyPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);

   int               sell(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   int               sellPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   //卖出挂单
   int               sellPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   int               sellPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   //卖出stop limit
   int               sellPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);
   int               sellPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic);

   void              closeAllBuy(string symbol,int magic=0);
   void              closeAllSell(string symbol,int magic=0);
   void              closeALLBuyAndSell(string symbol,int magic=0);
   void              mofiyStoplossAndTakeProfit(string symbol,ENUM_POSITION_TYPE type,double sl,double tp,int magic=0);
   //修改挂单止盈止损
   void              modifyPendingOrderStoplossAndTakeProfit(string symbol,ENUM_ORDER_TYPE type,double pendingPrice,double limitPrice,double sl,double tp,int magic=0);
   void              deleteAllPendingOrders(string symbol,int magic);

   //获取指定类型的持仓单数量
   int               getPositionNum(string symbol,ENUM_POSITION_TYPE type,int magic=0);
   int               getAllPositionNum(string symbol,int magic=0);

   //获取指定类型订单累计盈利总额
   double            profit(string symbol,ENUM_POSITION_TYPE type,int magic=0);
   //所有订单累计盈利总额
   double            profitall(string symbol,int magic=0);

   //获取格式化单量(平台允许的最接近单量)
   double            formatLots(string symbol,double lots);
   //下百分比的单量
   double            percentLots(ENUM_ORDER_TYPE action,string symbol,int percent);

   //获取最新的持仓单单号
   int               getNewestPositionOrder(string symbol,ENUM_POSITION_TYPE type,double &openprice,datetime &opentime,double &openlots,double &opensl,double &opentp,int magic=0);
   //盈亏平衡点(等于这个点位BEP,就刚好不赚不亏)   
   double            breakEvenPointPrice(string symbol,ENUM_POSITION_TYPE type,int magic=0);
   //移动止损(trailingPoint:移动点)
   void              trailingStop(int trailingPoint,string symbol,ENUM_POSITION_TYPE type,int magic=0);
   //获取最近的交易类型历史订单
   void              getLastDealsHistory(string symbol,ENUM_DEAL_TYPE type,double &deal_price,datetime &deal_time,double &lots,int magic=0);
   //当前货币对小数点位数
   int               digits(string symbol);
                     Trade();
                    ~Trade();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Trade::Trade()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Trade::~Trade()
  {
  }
//+------------------------------------------------------------------+
//slPoint = stop loss point止损点,tpPoint = take profit Point止盈点
int Trade::buy(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//市价单
   request.action=TRADE_ACTION_DEAL;
   request.magic=magic;

   request.symbol=symbol;
   request.volume=lots;
   request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
   if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl=SymbolInfoDouble(symbol,SYMBOL_ASK)-slPoint*Point();
     }
   if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp=SymbolInfoDouble(symbol,SYMBOL_ASK)+tpPoint*Point();
     }

//滑点
   request.deviation=100;
//多单
   request.type=ORDER_TYPE_BUY;

   request.comment=comment;

//--- 发送请求
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // 如果不能发送请求,输出错误代码
//--- 操作信息
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
   return(result.order);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::buyPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   int a=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==comment)
           {
            //不开单
            a=1;
            return(0);
           }
        }
     }
   if(a==0)
     {
      a=buy(symbol,lots,slPoint,tpPoint,comment,magic);
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::buyPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   pendingPrice=NormalizeDouble(pendingPrice,Digits());
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   request.action=TRADE_ACTION_PENDING;
   request.magic=magic;

   request.symbol=symbol;
   request.volume=lots;
   request.price=pendingPrice;

   request.sl=pendingPrice-slPoint*Point();
   request.tp=pendingPrice+tpPoint*Point();

   request.deviation=100;

   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
   if(pendingPrice>ask)
     {
      request.type=ORDER_TYPE_BUY_STOP;
     }
   if(pendingPrice=0;i--)
     {
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT || OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
           {
            a=1;
            return(0);
           }
        }
     }
   if(a==0)
     {
      a=buyPendingOrder(pendingPrice,symbol,lots,slPoint,tpPoint,comment,magic);
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::buyPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   stopPrice=NormalizeDouble(stopPrice,Digits());
   limitPrice=NormalizeDouble(limitPrice,Digits());
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   request.action=TRADE_ACTION_PENDING;
   request.type=ORDER_TYPE_BUY_STOP_LIMIT;
   request.symbol=symbol;
   double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
   if(stopPrice<=ask)
     {
      Alert("stopPrice必须大于市价");
      return(0);
     }
   if(limitPrice>=stopPrice)
     {
      Alert("limitprice必须小于stopprice");
      return(0);
     }
   request.volume=lots;
   request.deviation=100;
   request.price=stopPrice;
   request.stoplimit=limitPrice;
   if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl=limitPrice-slPoint*Point();
     }
   if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp=limitPrice+tpPoint*Point();
     }

   request.comment=comment;
   request.magic=magic;
//--- 发送请求
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // 如果不能发送请求,输出错误代码
   return(result.order);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::buyPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   int a=0;
   int t=OrdersTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP_LIMIT) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
           {
            //不开挂单
            a=1;
            return(0);
           }
        }
     }
   if(a==0)
     {
      a=buyPendingStoplimitOrder(stopPrice,limitPrice,symbol,lots,slPoint,tpPoint,comment,magic);
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::sell(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//市价单
   request.action=TRADE_ACTION_DEAL;
   request.magic=magic;

   request.symbol=symbol;
   request.volume=lots;
   request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
   if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl=SymbolInfoDouble(symbol,SYMBOL_BID)+slPoint*Point();
     }
   if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp=SymbolInfoDouble(symbol,SYMBOL_BID)-tpPoint*Point();
     }

//滑点
   request.deviation=100;
//空单
   request.type=ORDER_TYPE_SELL;

   request.comment=comment;

//--- 发送请求
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // 如果不能发送请求,输出错误代码
//--- 操作信息
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
   return(result.order);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::sellPlus(string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   int a=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && PositionGetInteger(POSITION_MAGIC)==magic && PositionGetString(POSITION_COMMENT)==comment)
           {
            //不开单
            a=1;
            return(0);
           }
        }
     }
   if(a==0)
     {
      a=sell(symbol,lots,slPoint,tpPoint,comment,magic);
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::sellPendingOrder(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   pendingPrice=NormalizeDouble(pendingPrice,Digits());
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//市价单
   request.action=TRADE_ACTION_PENDING;
   request.magic=magic;

   request.symbol=symbol;
   request.volume=lots;
   request.price=pendingPrice;

   request.sl=pendingPrice+slPoint*Point();
   request.tp=pendingPrice-tpPoint*Point();
//滑点
   request.deviation=100;
//空单
   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
   if(pendingPricebid)
     {
      request.type=ORDER_TYPE_SELL_LIMIT;
     }

   request.comment=comment;

//--- 发送请求
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // 如果不能发送请求,输出错误代码
   return(result.order);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::sellPendingOrderPlus(double pendingPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   int a=0;
   int t=OrdersTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT || OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
           {
            //不开挂单
            a=1;
            return(0);
           }
        }
     }
   if(a==0)
     {
      a=sellPendingOrder(pendingPrice,symbol,lots,slPoint,tpPoint,comment,magic);
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::sellPendingStoplimitOrder(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   stopPrice=NormalizeDouble(stopPrice,Digits());
   limitPrice=NormalizeDouble(limitPrice,Digits());
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};

   request.action=TRADE_ACTION_PENDING;
   request.type=ORDER_TYPE_SELL_STOP_LIMIT;
   request.symbol=symbol;
   double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
   if(stopPrice>=bid)
     {
      Alert("stopPrice必须小于市价");
      return(0);
     }
   if(limitPrice<=stopPrice)
     {
      Alert("limitprice必须大于stopprice");
      return(0);
     }
   request.volume=lots;
//滑点
   request.deviation=100;
   request.price=stopPrice;
   request.stoplimit=limitPrice;
   if(slPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.sl=limitPrice+slPoint*Point();
     }
   if(tpPoint>SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL))
     {
      request.tp=limitPrice-tpPoint*Point();
     }

   request.comment=comment;
   request.magic=magic;

//--- 发送请求
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // 如果不能发送请求,输出错误代码
   return(result.order);

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Trade::sellPendingStoplimitOrderPlus(double stopPrice,double limitPrice,string symbol,double lots,int slPoint,int tpPoint,string comment,int magic)
  {
   int a=0;
   int t=OrdersTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==symbol && (OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP_LIMIT) && OrderGetInteger(ORDER_MAGIC)==magic && OrderGetString(ORDER_COMMENT)==comment)
           {
            //不开挂单
            a=1;
            return(0);
           }
        }
     }
   if(a==0)
     {
      a=sellPendingStoplimitOrder(stopPrice,limitPrice,symbol,lots,slPoint,tpPoint,comment,magic);
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trade::closeAllBuy(string symbol,int magic=0)
  {
//持仓单遍历
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      //选择持仓单
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            bool needClose=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needClose=true;
              }

            if(needClose)
              {
               MqlTradeRequest request={0};
               MqlTradeResult  result={0};
               request.action=TRADE_ACTION_DEAL;                     // 交易操作类型
               request.symbol=symbol;                              // 交易品种
               request.volume=PositionGetDouble(POSITION_VOLUME); //交易量 
               request.type=ORDER_TYPE_SELL;                        //订单类型
               request.price=SymbolInfoDouble(symbol,SYMBOL_BID); // 持仓价格                                                   
               request.deviation=100;//滑点
               request.position=PositionGetTicket(i);//平仓最好都写下,不然和sell一样了。
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误

              }

           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trade::closeAllSell(string symbol,int magic=0)
  {
//持仓单遍历
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      //选择持仓单
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            bool needClose=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needClose=true;
              }
            if(needClose)
              {
               MqlTradeRequest request={0};
               MqlTradeResult  result={0};
               request.action=TRADE_ACTION_DEAL;                     // 交易操作类型
               request.symbol=symbol;                              // 交易品种
               request.volume=PositionGetDouble(POSITION_VOLUME); // 交易量 
               request.type=ORDER_TYPE_BUY;                        // 订单类型
               request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); // 持仓价格
               request.deviation=100; //滑点
               request.position =PositionGetTicket(i);
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误

              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trade::closeALLBuyAndSell(string symbol,int magic=0)
  {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            bool needClose=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needClose=true;
              }
            if(needClose)
              {
               MqlTradeRequest request={0};
               MqlTradeResult  result={0};
               request.action=TRADE_ACTION_DEAL;                     // 交易操作类型
               request.symbol=symbol;                              // 交易品种
               request.volume=PositionGetDouble(POSITION_VOLUME); // 交易量 
               request.type=ORDER_TYPE_SELL;                        // 订单类型
               request.price=SymbolInfoDouble(symbol,SYMBOL_BID); // 持仓价格
               request.deviation=100; //滑点
               request.position =PositionGetTicket(i);
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误

              }
           }
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            bool needClose=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needClose=true;
              }
            if(needClose)
              {
               MqlTradeRequest request={0};
               MqlTradeResult  result={0};
               request.action=TRADE_ACTION_DEAL;                     // 交易操作类型
               request.symbol=symbol;                              // 交易品种
               request.volume=PositionGetDouble(POSITION_VOLUME); // 交易量 
               request.type=ORDER_TYPE_BUY;                        // 订单类型
               request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); // 持仓价格
               request.deviation=100; //滑点
               request.position =PositionGetTicket(i);
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误

              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//修改止盈止损
void Trade::mofiyStoplossAndTakeProfit(string symbol,ENUM_POSITION_TYPE type,double sl,double tp,int magic=0)
  {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol)
           {
            double old_sl=NormalizeDouble(PositionGetDouble(POSITION_SL),digits(symbol));
            double old_tp=NormalizeDouble(PositionGetDouble(POSITION_TP),digits(symbol));
            double new_sl=NormalizeDouble(sl,digits(symbol));
            double new_tp=NormalizeDouble(sl,digits(symbol));

            //PrintFormat("buysell:old_sl=%lf,old_tp=%lf,new_sl=%lf,new_tp=%lf",old_sl,old_tp,new_sl,new_tp);
            if(type==POSITION_TYPE_BUY)
              {
               bool needAction=false;
               if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
                 {
                  needAction=true;
                 }
               if(needAction)
                 {
                  MqlTradeRequest request={0};
                  MqlTradeResult  result={0};
                  //Modify Stop Loss and Take Profit values of an opened position
                  request.action=TRADE_ACTION_SLTP;
                  // Position ticket 
                  request.position=PositionGetTicket(i);
                  request.symbol=symbol;

                  if(sl>0 && new_sl!=old_sl) request.sl=new_sl;
                  if(tp>0 && new_tp!=old_tp) request.tp=new_tp;

                  if(!OrderSend(request,result))
                     PrintFormat("OrderSend error %d",GetLastError());

                 }
              }
            if(type==POSITION_TYPE_SELL)
              {
               bool needAction=false;
               if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
                 {
                  needAction=true;
                 }
               if(needAction)
                 {
                  MqlTradeRequest request={0};
                  MqlTradeResult  result={0};
                  request.action=TRADE_ACTION_SLTP;
                  request.position=PositionGetTicket(i);
                  request.symbol=symbol;

                  if(sl>0 && new_sl!=old_sl) request.sl=new_sl;
                  if(tp>0 && new_tp!=old_tp) request.tp=new_tp;

                  if(!OrderSend(request,result))
                     PrintFormat("OrderSend error %d",GetLastError());
                 }

              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trade::modifyPendingOrderStoplossAndTakeProfit(string symbol,ENUM_ORDER_TYPE type,double pendingPrice,double limitPrice,double sl,double tp,int magic=0)
  {
   int t=OrdersTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==symbol)
           {
            //1.stop 和 limit类型
            if(type==ORDER_TYPE_BUY_LIMIT || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_SELL_LIMIT || type==ORDER_TYPE_SELL_STOP)
              {
               bool needAction=false;
               if(magic==0 || OrderGetInteger(ORDER_MAGIC)==magic)
                 {
                  needAction=true;
                 }
               if(needAction)
                 {
                  MqlTradeRequest request={0};
                  MqlTradeResult  result={0};
                  //Modify Stop Loss and Take Profit values of an opened position
                  request.action=TRADE_ACTION_MODIFY;
                  request.type=type;
                  // Position ticket 
                  request.order=OrderGetTicket(i);
                  request.symbol=symbol;
                  if(sl>0)request.sl=NormalizeDouble(sl,digits(symbol));
                  if(tp>0)request.tp=NormalizeDouble(tp,digits(symbol));

                  if(pendingPrice!=0)
                    {
                     request.price=NormalizeDouble(pendingPrice,Digits());
                    }
                  if(sl<0) request.sl=NormalizeDouble(OrderGetDouble(ORDER_SL),digits(symbol));
                  if(tp<0) request.tp=NormalizeDouble(OrderGetDouble(ORDER_TP),digits(symbol));

                  if(!OrderSend(request,result))
                     PrintFormat("OrderSend error %d",GetLastError());

                 }
              }
            //2.stoplimit类型
            if(type==ORDER_TYPE_BUY_STOP_LIMIT || type==ORDER_TYPE_SELL_STOP_LIMIT)
              {
               bool needAction=false;
               if(magic==0 || OrderGetInteger(ORDER_MAGIC)==magic)
                 {
                  needAction=true;
                 }
               if(needAction)
                 {
                  MqlTradeRequest request={0};
                  MqlTradeResult  result={0};
                  //Modify Stop Loss and Take Profit values of an opened position
                  request.action=TRADE_ACTION_MODIFY;
                  request.type=type;
                  // Position ticket 
                  request.order=OrderGetTicket(i);
                  request.symbol=symbol;
                  if(sl>0)request.sl=NormalizeDouble(sl,digits(symbol));
                  if(tp>0)request.tp=NormalizeDouble(tp,digits(symbol));

                  if(pendingPrice!=0)
                    {
                     request.price=NormalizeDouble(pendingPrice,Digits());
                    }
                  if(limitPrice!=0)
                    {
                     request.stoplimit=NormalizeDouble(limitPrice,Digits());
                    }

                  if(sl<0) request.sl=NormalizeDouble(OrderGetDouble(ORDER_SL),digits(symbol));
                  if(tp<0) request.tp=NormalizeDouble(OrderGetDouble(ORDER_TP),digits(symbol));

                  if(!OrderSend(request,result))
                     PrintFormat("OrderSend error %d",GetLastError());

                 }

              }
           }
        }
     }
  }
//删除所有挂单
void Trade::deleteAllPendingOrders(string symbol,int magic)
  {
   int t=OrdersTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==symbol)
           {
            bool needAction=false;
            if(magic==0 || OrderGetInteger(ORDER_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               MqlTradeRequest request={0};
               MqlTradeResult  result={0};
               //Delete the pending order placed previously
               request.action=TRADE_ACTION_REMOVE;
               request.order=OrderGetTicket(i);
               request.symbol=symbol;
               if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
int Trade::getPositionNum(string symbol,ENUM_POSITION_TYPE type,int magic=0)
  {
   int a=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
           {
            bool needAction=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               a++;
              }
           }
        }
     }
   return(a);
  }
//+------------------------------------------------------------------+
int Trade::getAllPositionNum(string symbol,int magic=0)
  {
   int a=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL))
           {
            bool needAction=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               a++;
              }
           }
        }
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Trade::profit(string symbol,ENUM_POSITION_TYPE type,int magic=0)
  {
   double a=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
           {
            bool needAction=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               a=a+PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
              }
           }
        }
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Trade::profitall(string symbol,int magic=0)
  {
   double a=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL))
           {

            bool needAction=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               a=a+PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
              }
           }
        }
     }
   return(a);
  }
//+------------------------------------------------------------------+
double Trade::formatLots(string symbol,double lots)
  {
   double a=0;
   double miniLots=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
   double stepLots=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
   if(lots=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
           {
            bool needAction=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               openPrice=PositionGetDouble(POSITION_PRICE_OPEN);
               openTime=PositionGetInteger(POSITION_TIME);
               openLots=PositionGetDouble(POSITION_VOLUME);
               openStopLoss=PositionGetDouble(POSITION_SL);
               openTakeProfit=PositionGetDouble(POSITION_TP);
               ticket=PositionGetInteger(POSITION_TICKET);
               break;
              }
           }
        }
     }
   return(ticket);
  }
//+------------------------------------------------------------------+
double Trade::breakEvenPointPrice(string symbol,ENUM_POSITION_TYPE type,int magic=0)
  {
   double a=0;
   double totalLots=0;
   double sum=0;
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==type)
           {
            bool needAction=false;
            if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
              {
               needAction=true;
              }
            if(needAction)
              {
               if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
                 {
                  totalLots=totalLots+PositionGetDouble(POSITION_VOLUME);
                  sum=sum+PositionGetDouble(POSITION_VOLUME)*PositionGetDouble(POSITION_PRICE_OPEN);
                 }
               if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
                 {
                  totalLots=totalLots-PositionGetDouble(POSITION_VOLUME);
                  sum=sum-PositionGetDouble(POSITION_VOLUME)*PositionGetDouble(POSITION_PRICE_OPEN);
                 }
              }

           }
        }
     }
   if((totalLots!=0) && (sum!=0))
     {
      a=NormalizeDouble(sum/totalLots,SymbolInfoInteger(symbol,SYMBOL_DIGITS));
     }
   else
     {
      a=0;
     }
   return(a);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trade::trailingStop(int trailingPoint,string symbol,ENUM_POSITION_TYPE type,int magic=0)
  {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
      if(PositionGetTicket(i)>0)
        {
         if(PositionGetString(POSITION_SYMBOL)==symbol)
           {
            double bid=SymbolInfoDouble(symbol,SYMBOL_BID);
            double ask=SymbolInfoDouble(symbol,SYMBOL_ASK);
            double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
            double openPrice=PositionGetDouble(POSITION_PRICE_OPEN);
            double sl=PositionGetDouble(POSITION_SL);
            double tp=PositionGetDouble(POSITION_TP);
            if(type==POSITION_TYPE_BUY)
              {
               if((bid-openPrice)>=point*trailingPoint && (sl<(bid-point*trailingPoint) || (sl==0)))
                 {
                  bool needAction=false;
                  if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
                    {
                     needAction=true;
                    }
                  if(needAction)
                    {
                     MqlTradeRequest request={0};
                     MqlTradeResult  result={0};
                     request.action=TRADE_ACTION_SLTP;
                     request.position=PositionGetTicket(i);
                     request.symbol=symbol;
                     request.sl=bid-point*trailingPoint;
                     request.tp=tp;
                     if(!OrderSend(request,result))
                        PrintFormat("OrderSend error %d",GetLastError());
                    }
                 }
              }
            if(type==POSITION_TYPE_SELL)
              {
               if((openPrice-ask)>=point*trailingPoint && ((sl>(ask+point*trailingPoint)) || (sl==0)))
                 {
                  bool needAction=false;
                  if(magic==0 || PositionGetInteger(POSITION_MAGIC)==magic)
                    {
                     needAction=true;
                    }
                  if(needAction)
                    {
                     MqlTradeRequest request={0};
                     MqlTradeResult  result={0};
                     request.action=TRADE_ACTION_SLTP;
                     request.position=PositionGetTicket(i);
                     request.symbol=symbol;
                     request.sl=ask+point*trailingPoint;
                     request.tp=tp;
                     if(!OrderSend(request,result))
                        PrintFormat("OrderSend error %d",GetLastError());
                    }
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Trade::getLastDealsHistory(string symbol,ENUM_DEAL_TYPE type,double &deal_price,datetime &deal_time,double &lots,int magic=0)
  {
  //1.一般都要写这个
   HistorySelect(0,TimeCurrent());
   int dealsTotal=HistoryDealsTotal();
   for(int i=dealsTotal-1;i>=0;i--)
     {
      int deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0)
        {
         if(HistoryDealGetInteger(deal_ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT && HistoryDealGetString(deal_ticket,DEAL_SYMBOL)==symbol && HistoryDealGetInteger(deal_ticket,DEAL_TYPE)==type)
           {
            if(magic==0)
              {
               deal_time=HistoryDealGetInteger(deal_ticket,DEAL_TIME);
               lots=HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
               deal_price=HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
               break;
              }
            else
              {
               if(HistoryDealGetInteger(deal_ticket,DEAL_MAGIC)==magic)
                 {
                  deal_time=HistoryDealGetInteger(deal_ticket,DEAL_TIME);
                  lots=HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
                  deal_price=HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
                  break;
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
int Trade::digits(string symbol)
  {
   return SymbolInfoInteger(symbol,SYMBOL_DIGITS);
  }
//+------------------------------------------------------------------+

2.1.交易类使用

//+------------------------------------------------------------------+
//|                                              commonUseScript.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

//显示确认框
#property script_show_confirm
#include 

int magic=170430;
Trade td;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   //td.buy(Symbol(),0.1,200,200,"buy",magic);
//td.sell(Symbol(),0.1,200,200,"sell",magic);
//td.closeAllBuy(Symbol());
//td.closeAllSell(Symbol());
//td.closeALLBuyAndSell(Symbol());
//td.mofiyStoplossAndTakeProfit(Symbol(),POSITION_TYPE_BUY,1.00,1.19);
//td.deleteAllPendingOrders(Symbol());
//double lots=td.formatLots(Symbol(),1.23456);
   double openPrice=0;
   datetime openTime=0;
   double openLots=0;
   double openStopLoss=0;
   double openTakeProfit=0;
   int ticket=td.getNewestPositionOrder(Symbol(),POSITION_TYPE_SELL,openPrice,openTime,openLots,openStopLoss,openTakeProfit);
  }
//+------------------------------------------------------------------+

如果您发现本文对你有所帮助,如果您认为其他人也可能受益,请把它分享出去。

你可能感兴趣的:(MT5入门到精通之十二(交易类))