程序库: MT4Orders - 页 78

 

我在我的类中进行了错误处理

#property strict

#ifdef __MQL5__
#include <MQL4_To_MQL5.mqh> //https://www.mql5.com/zh/code/16006
#endif // __MQL5__

#define GetLastError GetOrderError
// 不仅在 MT5 中存在,在 MT4 中也必须存在。
// https://www.mql5.com/ru/forum/93352/page19#comment_6730221
#include <MT4Orders.mqh>

#define  BUY     0
#define  SELL    1
#define  ALL    -1
#define  LAST    0
#define  NOMODY  -1
bool LogInfo=true;//Print to error log
/*
以下是处理订单的类函数
*/

在类的结尾,我添加了一个函数

//+-------------------------------------------------------------------------------------------------------------------+
//|| 从 MT5 到 MT4 的误差转换
//+-------------------------------------------------------------------------------------------------------------------+
int GetOrderError()
{
//int error=MT4ORDERS::LastTradeResult.retcode_external; // 返回自定义代码
   int error=(int)MT4ORDERS::LastTradeResult.retcode; // 向服务器发送订单后返回错误代码
   if(LogInfo==true)Print("error MT5=",error);
   switch(error)
   {
   case 10016:
      error=130;//错脚
      break;
   case 10018:
      error=132;/市场关闭
      break;
   case 10020:
      error=135;//价格已更改
      break;
   case 136:
      error=136;//无价格 - MT5 中无代码
      break;
   case 10004:
      error=138;//新价格
      break;
   case 145:
      error=145;//禁止修改,因为订单离市场太近 - MT5 中没有代码
      break;
   case 146:
      error=146;//交易子系统繁忙 - MT5 中无代码
      break;
   default:
      error=error;// 未描述的错误
   }
   return (error);
}
#undef GetLastError
 
Aleksey Vyazmikin #:

在我的班级中,错误处理是这样进行的

在类的结尾,我添加了一个函数

这个变体还不错。只需记住,其他错误代码 将不可用。

Документация по MQL5: Константы, перечисления и структуры / Коды ошибок и предупреждений / Ошибки времени выполнения
Документация по MQL5: Константы, перечисления и структуры / Коды ошибок и предупреждений / Ошибки времени выполнения
  • www.mql5.com
Ошибки времени выполнения - Коды ошибок и предупреждений - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
fxsaber #:

不错的选择。只需记住,其他错误代码 将不可用。

我认为这种更改只对我的类周围的代码有效,之后我关闭 #undef GetLastError 替换,如果我理解正确的话,编译器将不再替换 GetLastError,还是我理解错了?

 
Aleksey Vyazmikin #:

似乎这种更改只对我的类周围的代码有效,在我关闭 #undef GetLastError 替换后,如果我理解正确的话,编译器将不会进一步替换 GetLastError,还是我理解错了?

你是对的。我一下子没明白你的意思。

 
fxsaber #:

你说得对。我没有马上意识到你的意思。

谢谢!现在我只需要测试一下:)

 

你能帮我破译一下这个函数吗,因为所有这些冒号和问号我都不明白。

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
double AccountFreeMarginCheck(const string Symb,const int Cmd,const double dVolume)
  {
   double Margin;

   return(::OrderCalcMargin((ENUM_ORDER_TYPE)Cmd, Symb, dVolume,
          ::SymbolInfoDouble(Symb,(Cmd==::ORDER_TYPE_BUY) ? ::SYMBOL_ASK : ::SYMBOL_BID),Margin) ?
          ::AccountInfoDouble(::ACCOUNT_MARGIN_FREE) - Margin : -1);
  }

它返回的值小于零,资金为 9k 杠杆 1k100 lot 0.01 - 有什么问题吗?

 

将信息打印到日志中

/+------------------------------------------------------------------+
//| 检查是否有足够的资金开立订单
//+------------------------------------------------------------------+ 
bool CheckMoneyForTrade(double lots,int type)
  {
   string symb=Symbol();
   double free_margin=AccountFreeMarginCheck(symb,type,lots);

   double MarginAsk=0.0;
   bool MarginAskB=OrderCalcMargin(ENUM_ORDER_TYPE(type),Symbol(),lots,SymbolInfoDouble(Symbol(),SYMBOL_ASK),MarginAsk);
   double MarginBid=0.0;
   bool MarginBidB=OrderCalcMargin(ENUM_ORDER_TYPE(type),Symbol(),lots,SymbolInfoDouble(Symbol(),SYMBOL_BID),MarginBid);
   
   Print("ACCOUNT_MARGIN_FREE=",AccountInfoDouble(ACCOUNT_MARGIN_FREE),
   " SYMBOL_ASK=",SymbolInfoDouble(Symbol(),SYMBOL_ASK),
   " SYMBOL_BID=",SymbolInfoDouble(Symbol(),SYMBOL_BID),
   " OrderCalcMarginAsk=",MarginAsk,
   " OrderCalcMarginBid=",MarginBid, 
   " free_margin=",free_margin 
   );


   // -- 如果钱不够
   if(free_margin<0)
     {
      string oper=(type==OP_BUY)? "Buy":"Sell";
      Print("Not enough money for ", oper," ",lots, " ", symb, " Error code=",GetLastError());
      return(false);
     }
     if(NewOrderAllowedVolume(Symbol())<(lots+0.1))return(false);//检查可用容量
  
   //-- 测试成功
   return(true);
  }

在测试仪中

2022.07.22 21:50:39.521 2009.12.04 14:30:00   ACCOUNT_MARGIN_FREE=999560.05 SYMBOL_ASK=89.63 SYMBOL_BID=89.6 OrderCalcMarginAsk=100.0 OrderCalcMarginBid=100.0 free_margin=999460.05

在现实生活中

2022.07.22 21:45:08.956 Bingo_MT5 (USDJPY,M15)  ACCOUNT_MARGIN_FREE=9000.0 SYMBOL_ASK=136.267 SYMBOL_BID=136.241 OrderCalcMarginAsk=0.0 OrderCalcMarginBid=0.0 free_margin=-1.0
2022.07.22 21:45:08.956 Bingo_MT5 (USDJPY,M15)  Not enough money for Buy 0.0 USDJPY Error code=4002

由于不明原因,似乎没有进行 OrderCalcMargin() 计算 - 有什么办法吗?

错误 4002 意味着:

客户终端函数 内部调用 中的错误参数

但其含义并不清楚....

 
Aleksey Vyazmikin #:

你能帮我解读一下这个功能吗,因为所有这些冒号和问号我都不明白。

你使用的是某种古老的、匆忙组装的解决方案。

关于交易、自动交易系统和测试交易策略的论坛。

图书馆:MT4Orders

Aleksey Vyazmikin, 2022.07.21 11:58 AM

在我的类中的错误,使这样的工作

#ifdef __MQL5__
#include <MQL4_To_MQL5.mqh> //https://www.mql5.com/zh/code/16006
#endif // __MQL5__
很多次我都后悔把它贴出来,因为它与 MT4Orders 毫无关系。这只是对示例的补充。我不记得它的意思了。我不想深究。


我记得我在这里做了一个更详细的 "转换 "解决方案。

关于交易、自动交易系统和交易策略测试的论坛

库: MT4Orders

fxsaber, 2019.01.13 17:23 PM.

Kim 在 MT4 下的功能颇受欢迎,因此我从他的网站下载了所有源代码,并为它们在 MT5 下编写了一个简单的 "转换器"。
#include <KimIVToMT5.mqh> //https://c.mql5.com/3/263/KimIVToMT5.mqh

我自己只在订单功能中使用 MT4Style。我绝对不会为我的工作转换其他标准 MT4 函数,我认为这个选项是个拐杖。我建议使用本地函数编写保证金函数,而不要试图转换它们。我看了我的保证金工作课程--一个相当大的 mqh 文件。这仅适用于普通外汇交易。

 
fxsaber #:

你使用的是一些古老的、匆忙组装的解决方案。

我曾多次后悔发布这个解决方案,因为它与 MT4Orders 毫无关系。它只是对示例的补充。我不记得它的含义了。我不想去研究它。


我记得我在这里对 "转换 "做了一个更详细的解答。

我自己只在订单功能中使用 MT4Style。我在工作中绝对不会转换其他标准 MT4 函数,并将此选项视为拐杖。我建议在本地函数的基础上编写保证金函数,而不要试图转换它们。我看了我的保证金工作课程--一个相当大的 mqh 文件。这仅适用于普通外汇交易。

我的任务只是为 MT4 和 MT5 的 EA 逻辑功能编写可编译的代码,在上述 inkludniks 的帮助下,我转换了与环境和订单工作相关的内容,或者取出单独的函数,并针对每个平台重新编写。这个项目很大,您的解决方案帮了我大忙,感谢您的劳动。

我还遇到了另一个错误 - 最小手数的确定不正确,因此我在这里添加了标记。 早些时候,我在未考虑您的代码的情况下进行了遍历(MQL4_To_MQL5.mqh 不是您的代码吗?) - 它已编译,但工作不正常。

#define  MODE_BID 9
#define  MODE_ASK 10
#define  MODE_DIGITS 12
#define MODE_SPREAD 13
#define  MODE_STOPLEVEL 14
#define  MODE_LOTSIZE 15

#define  MODE_POINT 11
#define  MODE_TICKVALUE 16
#define  MODE_TICKSIZE 17

#define  MODE_MAXLOT 18
#define  MODE_MINLOT 19
#define  MODE_LOTSTEP 20

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
double MarketInfo(const string Symb,const int Type)
  {
   switch(Type)
     {
      case MODE_BID:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_BID));
      case MODE_ASK:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_ASK));
      case MODE_DIGITS:
         return((double)::SymbolInfoInteger(Symb, ::SYMBOL_DIGITS));
      case MODE_SPREAD:
         return((double)::SymbolInfoInteger(Symb, ::SYMBOL_SPREAD));
      case MODE_STOPLEVEL:
         return((double)::SymbolInfoInteger(Symb, ::SYMBOL_TRADE_STOPS_LEVEL));
      case MODE_LOTSIZE:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_TRADE_CONTRACT_SIZE));

      case MODE_POINT:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_POINT));
       case MODE_TICKVALUE:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_TRADE_TICK_SIZE));
      case MODE_TICKSIZE:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_TRADE_TICK_VALUE));                 
      case MODE_MAXLOT:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_VOLUME_MAX));  
      case MODE_MINLOT:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_VOLUME_MIN));  
      case MODE_LOTSTEP:
         return(::SymbolInfoDouble(Symb, ::SYMBOL_VOLUME_STEP));                    
     }

   return(-1);
  }
 
Aleksey Vyazmikin #:

或者 MQL4_To_MQL5.mqh 不是您的代码?

它是我的,但已经很旧了。最好研究一下 Kim 的 mqh,那里有更详细的 MarketInfo 解决方案。