美文网首页MT5编程知识
MT5入门到精通之十二(交易类)

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

作者: 旺仔2488 | 来源:发表于2017-04-30 16:22 被阅读0次

    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<ask)
         {
          request.type=ORDER_TYPE_BUY_LIMIT;
         }
       request.comment=comment;
    
    //--- 发送请求
       if(!OrderSend(request,result))
          PrintFormat("OrderSend error %d",GetLastError());     // 如果不能发送请求,输出错误代码
       return(result.order);
      }
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    int Trade::buyPendingOrderPlus(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_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(pendingPrice<bid)
         {
          request.type=ORDER_TYPE_SELL_STOP;
         }
       if(pendingPrice>bid)
         {
          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<miniLots) return(0);
       else
         {
          //The function returns integer numeric value closest from below.
          double a1=MathFloor(lots/miniLots)*miniLots;
          a=a1+MathFloor((lots-a1)/stepLots)*stepLots;
         }
       return(a);
      }
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    double Trade::percentLots(ENUM_ORDER_TYPE action,string symbol,int percent)
      {
       double marg=0;
       OrderCalcMargin(action,symbol,1,SymbolInfoDouble(symbol,SYMBOL_BID),marg);
    //a marg/总钱数*percent
       double a=0;
       return(formatLots(symbol,a));
      }
    //+------------------------------------------------------------------+
    int Trade::getNewestPositionOrder(string symbol,ENUM_POSITION_TYPE type,double &openPrice,datetime &openTime,double &openLots,double &openStopLoss,double &openTakeProfit,int magic=0)
      {
       openPrice=0;
       openTime=0;
       openLots=0;
       openStopLoss=0;
       openTakeProfit=0;
       int ticket=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)
                  {
                   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 <wz\Trade.mqh>
    
    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入门到精通之十二(交易类)

        本文链接:https://www.haomeiwen.com/subject/cqjxtxtx.html