征得高手付费给予的MT5交易函数分享出来,还有需要完善的地方么?敬请指点,谢谢!

 
#include <Trade\Trade.mqh>



ENUM_ORDER_TYPE_FILLING  Type_fills;

ulong   Magic1=123, Magic2=321, Magic3=1234567, Magicx=0;
//=============================================================================================================================
//-----------------------------------------------------------------------------------------------------------------------------
void OnTick(void)
  {
   // 不属于同品可同时持有多个单子的账户 则此EA不运行
   ENUM_ACCOUNT_MARGIN_MODE mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
   if(mode!=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      idisplay("00","该账户对于同品不可存在多个持仓,此版EA不适合使用!",1000,150,16,clrRed);
      return;
     }
   // 获取现价单开仓的交易命令类型 ( 如果一个交易品种同时允许SYMBOL_FILLING_FOK和SYMBOL_FILLING_IOC成交指令,则交易命令类型为ORDER_FILLING_FOK )
   //                            ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
   if(SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE)==SYMBOL_FILLING_IOC)  Type_fills=ORDER_FILLING_IOC;
   if(SymbolInfoInteger(_Symbol,SYMBOL_FILLING_MODE)==SYMBOL_FILLING_FOK)  Type_fills=ORDER_FILLING_FOK;





  }
//==============================================================================================================================
// 下单
bool OrderSends(ENUM_TRADE_REQUEST_ACTIONS action, ENUM_ORDER_TYPE type, double Lot, double price, double sL, string com, ulong Magic)
  {
   bool eg=false;
 //--- 声明并初始化交易请求和交易请求结果
   MqlTradeRequest request={};
   MqlTradeResult   result={};
 //--- 请求参数
   request.action         =action;              // 操作类型    TRADE_ACTION_DEAL 或 TRADE_ACTION_PENDING  ( 前者用于现价单 后者用于挂单 )
   request.symbol         =_Symbol;             // 品种为本图表打开的品种
   request.type           =type;                // 订单类型
   request.volume         =Lot;                 // 手数
   request.price          =price;               // 价格 ( 现价单SELL时 price应为SYMBOL_BID  现价单BUY时 price应为SYMBOL_ASK )
   request.sl             =sL;                  // 止损位
   request.tp             =0;                   // 0 即未设置止赢位
   request.deviation      =30;                  // 价格允许偏差为30点 ( 30是以黄金交易为例 )
   if(action==TRADE_ACTION_PENDING)             // 根据下单类型设置交易命令执行类型
   request.type_filling   =ORDER_FILLING_RETURN;
   if(action==TRADE_ACTION_DEAL)
   request.type_filling   =Type_fills;
   request.comment        =com;                 // 注释
   request.magic          =Magic;               // EA交易 ID (幻数)
 //--- 发送请求
   eg=OrderSend(request,result);
 //--- 不能发送请求,则输出错误代码
   if(!eg) PrintFormat("OrderSend error %d",GetLastError());
 //--- 返回eg值
   return(eg);
  }
//=================================================================================
// 平仓
bool OrderClose(ENUM_POSITION_TYPE type, ulong P_ticket, double Lot, ulong Magic)
  {
   bool eg=false;
 //--- 声明并初始化交易请求和交易请求结果
   MqlTradeRequest  request;
   MqlTradeResult   result;
 //--- 归零请求和结果值
   ZeroMemory(request);
   ZeroMemory(result);
 //--- 设置操作参数
   request.action         =TRADE_ACTION_DEAL;   // 交易操作类型 市场命令
   request.position       =P_ticket;            // 持仓单号
   request.symbol         =_Symbol;
   request.volume         =Lot;
   request.deviation      =30;
   request.type_filling   =Type_fills;
   request.magic          =Magic;
   if(type==POSITION_TYPE_BUY)                  // 根据持仓类型设置平仓价格和类型
     {
      request.price       =SymbolInfoDouble(Symbol(),SYMBOL_BID);
      request.type        =ORDER_TYPE_SELL;
     }
   else
     {
      request.price       =SymbolInfoDouble(Symbol(),SYMBOL_ASK);
      request.type        =ORDER_TYPE_BUY;
     }
 //--- 发送请求
   eg=OrderSend(request,result);
   if(!eg) PrintFormat("OrderSend error %d",GetLastError());
 //--- 返回eg值
   return(eg);
  }
//=================================================================================
// 损盈位设置修改 ( 仅针对现价单 )
bool Modify_sltp(ulong P_ticket, double sL, double tp, ulong Magic)
  {
   bool eg=false;
 // 当账户属于锁仓系统的账户时,修改损盈或平仓时,要确保指明其单号(MqlTradeRequest::position)。在单边系统 虽通过品名来确定持仓 也可指明单号。
   MqlTradeRequest  request;
   MqlTradeResult   result;
 //--- 归零请求和结果值
   ZeroMemory(request);
   ZeroMemory(result);
 //--- 设置操作参数
   request.action         =TRADE_ACTION_SLTP;   // 类型为设置修改损盈位
   request.position       =P_ticket;            // 持有单号 只对position..类单 即非挂单
   request.symbol         =_Symbol;
   request.sl             =sL;                  // 止损位
   request.tp             =tp;                  // 止盈位
   request.magic          =Magic;
 //--- 发送请求
   eg=OrderSend(request,result);
   if(!eg) PrintFormat("OrderSend error %d",GetLastError());
 //--- 返回eg值
   return(eg);
  }
//=================================================================================
// 挂单修改 ( 所有挂单的挂价和损盈位修改,一律用此函数 )
bool Modify_GuaDan(ulong ticket, double price, double sL, double tp, ulong Magic)
  {
   bool eg=false;
 //--- 声明并初始化交易请求和交易请求结果
   MqlTradeRequest request={};
   MqlTradeResult   result={};
 //--- 设置操作参数
   request.action         =TRADE_ACTION_MODIFY; // 操作类型为调整修改
   request.order          =ticket;              // 订单号
   request.symbol         =_Symbol;
   request.price          =price;
   request.sl             =sL;                  // 止损位
   request.tp             =tp;                  // 止盈位
   request.deviation      =30;
   request.magic          =Magic;
 //--- 发送请求
   eg=OrderSend(request,result);
   if(!eg) PrintFormat("OrderSend error %d",GetLastError());
 //--- 归零请求和结果值
   ZeroMemory(request);
   ZeroMemory(result);
 //--- 返回eg值
   return(eg);
  }
//=================================================================================
// 删挂
bool OrderRemove(ulong ticket)
  {
   bool eg=false;
   MqlTradeRequest request={};
   MqlTradeResult   result={};
 //--- 归零请求和结果值
   ZeroMemory(request);
   ZeroMemory(result);
 //--- 设置持仓参数
   request.action         =TRADE_ACTION_REMOVE; // 交易操作的类型为删除
   request.order          =ticket;
 //--- 发送请求
   eg=OrderSend(request,result);
   if(!eg) PrintFormat("OrderSend error %d",GetLastError());
 //--- 返回eg值
   return(eg);
  }
//==============================================================================================================================
到包裹 | 议论 | 回复
新评论

 
貌似不错,列入几个EA幻数,可实现同品多策略下单及分类管理。
 

.

由于挂单有几种到期模式的执行命令。个人觉得,手动挂单无论哪种模式均可 ,但EA自动化挂单若非锁仓,则务必指定到期时间更好了。

为此,则需先确定命令模式是否适合自己的策略,然后再加挂。

因此,挂单的下单函数与现价单下单函数分开,也许更好了。

还望路过的高手指点,给予宝贵意见,谢谢。


ENUM_ORDER_TYPE_TIME     Type_time, Type_T;
//=================================================================================
void OnTick(void)
  {

   // 查看该品的订单到期模式可否指定到期时间
   bool Time_gtc=false, Time_day=false, specified_T=false, specified_D=false;
   long tmp_long;
   int  flags=0;
   if(SymbolInfoInteger(_Symbol,SYMBOL_EXPIRATION_MODE,tmp_long))  flags=(int)tmp_long;

   if(Type_time==ORDER_TIME_GTC && (flags&SYMBOL_EXPIRATION_GTC)!=0)   Time_gtc=true;
   if(Type_time==ORDER_TIME_DAY && (flags&SYMBOL_EXPIRATION_DAY)!=0)          Time_day=true;
   if(Type_time==ORDER_TIME_SPECIFIED && (flags&SYMBOL_EXPIRATION_SPECIFIED)!=0)    specified_T=true;
   if(Type_time==ORDER_TIME_SPECIFIED_DAY && (flags&SYMBOL_EXPIRATION_SPECIFIED_DAY)!=0)    specified_D=true;

   if(Time_gtc)      Type_T=ORDER_TIME_GTC;
   if(Time_day)      Type_T=ORDER_TIME_DAY;
   if(specified_D)   Type_T=ORDER_TIME_SPECIFIED_DAY;

   if(specified_T) { Type_T=ORDER_TIME_SPECIFIED;  idisplay("B", "挂单可指定到期时间",   520,2,10, Clr); }
   else                                            idisplay("B", "挂单不可指定到期时间", 520,2,10, Clr);





   datetime  miao=0;
   if(...  )  miao=10000;   else   miao=3000; 

   if(...  && specified_T)
     {
      if(gua<1) reg=OrderSendg( ...... ,TimeCurrent()+miao, ....);
     }



//=================================================================================
// 挂单
bool OrderSendg(ENUM_ORDER_TYPE type, double Lot, double price, double sL, datetime expiration, string com, ulong Magic)
  {
   bool eg=false;
 //--- 声明并初始化交易请求和交易请求结果
   MqlTradeRequest request={};
   MqlTradeResult   result={};
 //--- 请求参数
   request.action         =TRADE_ACTION_PENDING;// 操作类型     
   request.symbol         =_Symbol;             // 品种为本图表打开的品种
   request.type           =type;                // 订单类型
   request.volume         =Lot;                 // 手数
   request.price          =price;               // 价格
   request.sl             =sL;                  // 止损位
   request.tp             =0;                   // 0 即未设置止赢位
   request.deviation      =0;                   // 价格允许偏差为0点 (挂单可设为0)
   request.type_filling   =ORDER_FILLING_RETURN;
   request.type_time      = Type_T;
   request.expiration     =expiration;   
   request.comment        =com;                 // 注释
   request.magic          =Magic;               // EA交易 ID (幻数)
 //--- 发送请求
   eg=OrderSend(request,result);
 //--- 若请求失败 输出错误代码
   if(!eg) PrintFormat("OrderSend error %d",GetLastError());
 //--- 返回eg值
   return(eg);
  }
 

试了试很多平台, 暂不能直接用EA指定 ORDER_TYPE_TIME为ORDER_TIME_SPECIFIED ,即不能在设置挂单时指定挂单的到期时间。

还是该用楼主的OrderSends函数设置挂单,再按老办法来删除自定义过时的挂单,举例如下:

   //--------------------------------------------------------
   // 删除过时挂单

   int barN=3;
   for(i=0;i<OrdersTotal();i++)
     {
      bool Del=false;
      int  Kn=0;
      if(OrderGetTicket(i)>0)
        {
         if(OrderGetString(ORDER_SYMBOL)==_Symbol)
           {
            if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT || OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT)
              {
               if(OrderGetInteger(ORDER_MAGIC)==MagicH)
                 {
                  Kn=Bars(_Symbol,PERIOD_H1,OrderGetInteger(ORDER_TIME_SETUP),TimeCurrent()); //加挂时间在现时的K线序号
                  if(Kn>=barN  )  Del=OrderRemove(OrderGetInteger(ORDER_TICKET));
                 }
               if(OrderGetInteger(ORDER_MAGIC)==MagicM15)
                 {
                  Kn=Bars(_Symbol,PERIOD_M15,OrderGetInteger(ORDER_TIME_SETUP),TimeCurrent());
                  if(Kn>=barN*3)  Del=OrderRemove(OrderGetInteger(ORDER_TICKET));
                 }
              }
           }
        }
     }
   //--------------------------------------------------------
  
 
手法细腻
 
适合mql5编程新人参考
 
Tiecheng Fu #:
适合mql5编程新人参考

付费帮我在我原来MT5 EA写个控制开仓!或者说是控制总亏损(浮亏)多少仓位不开仓这个给你可以吗?

 
waihui1001:
这些代码官方手册都有的复制黏贴,还高手,付费的,感觉你被坑了
 


Yuying #:
貌似不错,列入几个EA幻数,可实现同品多策略下单及分类管理。

对于交易命令类型的划分识别,貌似很不错,简单明了。

区分了挂单和现价单的交易命令;

现价单的交易命令类型究竟属于RDER_FILLING_IOC 还是属于 RDER_FILLING_FOK,也作了清晰的识别。

原因: