EA: 交易者的MQL5编程(MQL5 Programming for Traders) - 源代码第七部分

 

交易者的MQL5编程(MQL5 Programming for Traders) - 源代码第七部分:

在本书的最后,即第七部分讨论了MQL5 API的高级功能,这在为MetaTrader 5开发程序时发挥重要作用。其中包括自定义交易品种、内置经济日历事件以及网络、数据库和加密等通用技术。

交易者的MQL5编程(MQL5 Programming for Traders) - 源代码第七部分

作者: MetaQuotes

 
不错的学习资源
 
 
學習一下
 
这里是对日历缓存过滤器 的小错误修复和改进。
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
MQL5 Book: Advanced language tools / Economic calendar / Transferring calendar database to tester
  • www.mql5.com
The calendar is available for MQL programs only online, and therefore testing news trading strategies poses some difficulties. One of the solutions...
附加的文件:
 

您能告诉我这是一个错误还是我不明白什么吗?

MarginProfitMeter.mqh 文件。

// 将 "当前 "金额转换为 "账户 "金额
bool Convert(const string current, const string account,
             const bool ask, double &margin, const datetime moment = 0)
  {
   string rate;
   int dir = FindExchangeRate(current, account, rate);
   if(dir == +1)
     {
      margin *= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_BID : SYMBOL_ASK) :
                GetHistoricPrice(rate, moment, ask);
     }
   else
      if(dir == -1)
        {
         margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
        }
      else
        {
         static bool once = false;
         if(!once)
           {
            Print("Can't convert ", current, " -> ", account);
            once = true;
           }
        }
   return true;
  }

除以零是不可能的,不是吗?


此外,该方法应返回保证金,但它返回的却是价格。我知道这个价格应该乘以合约大小,但我不知道在哪里做才正确。

是在这个函数中添加,还是从哪里调用这个函数?

 
Aleksandr Slavskii #:

您能告诉我这是一个错误还是我遗漏了什么吗?

文件 MarginProfitMeter.mqh

除以零是不可能的,不是吗?

确实不可能。

margin /= moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);

除法符号后有一个三元运算符,赋值为"/="。因此,如果 momet==0, 那么:

margin /= SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID)

否则

margin /= GetHistoricPrice(rate, moment, ask)

但我还是会在这两个函数中都加上检查是否为零的功能....。


另外,这个方法应该返回 margin,但它却返回 price。我知道在某个地方,这个价格应该乘以合约大小,但我不知道在哪里做得更正确....。

根据描述判断

// 将 "当前 "金额转换为 "账户 "金额

该方法将当前货币(币种)转换为存款的货币(币种)。从代码来看,该方法将保证金转换为存款货币。

如果成功,该方法将返回 true。它还会计算新的、修正后的保证金金额,并将其存储在 margin 变量中。这是链接中的一个参数:

double &margin

因此你可以根据计算结果得到它。

 
Denis Kirichenko #:

真的不行。

除法符号后有一个三元运算符,赋值为"/="。因此,如果 momet==0 ,那么

对,没错,三元运算符我今天早上太累了,都快哑了。


丹尼斯-基里琴科#

Judging by the description

该方法将活期存款(货币)转换为定期存款(货币)。从代码来看,该方法将保证金转换为存款货币。

不,现在也正确了。


对不起,我在代码中犯了一个小错误。


反正也没什么用,因为如果交易量超过 3,最后计算保证金时还是会出错。

EURUSD; margin = 24668.8  //  OrderCalcMargin()
EURUSD; margin = 10889.599999999999 // MarginProfitMeter.mqh 

十份合同的保证金计算。

 
Denis Kirichenko #:
margin /=moment ==0? SymbolInfoDouble(rate, ask ?SYMBOL_ASK:SYMBOL_BID) GetHistoricPrice(rate, moment, ask);

有点错误。条件(margin /= moment)==0 然后三元运算符...

 
Alexey Viktorov #:

有点错误。条件 (margin /= moment)==0 然后是三元运算符...

不知为什么,我不同意。先试着满足这个条件

double margin = 1.5;
datetime moment = 0;
margin /= moment;

那么你就是在把刺猬分成刺猬,这本身就有问题。

而且赋值操作的优先级很低,只有 zpt 的优先级更低。

编译器也会生气:

possible loss of data due to type conversion from 'datetime' to 'double'

而函数的逻辑是余量转换。据我所知,moment = 0 就是现在:

margin /= moment == 0 ?
                SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                GetHistoricPrice(rate, moment, ask);

意味着如果是现在, 我们就询问当前价格。如果是过去,我们就参考历史价格。在得到想要的价格后,最后我们用保证金值除以这个价格,赋值....。按照您的逻辑,在时刻 = 0 时,我们将得到的不是保证金转换,而只是市场价格或过去的价格....。


一般来说,教科书最好用括号来 写:

margin /= (moment == 0) ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask);
 
Denis Kirichenko #:

不知为什么,我不同意。先满足这个条件 吧:

这样就把刺猬分成了刺猬,这本身就有问题。

而赋值操作的优先级很低,只有 zpt 的优先级更低。

编译器也会生气:

而函数的逻辑是余量转换。据我所知,moment = 0 就是现在,然后:

意味着如果是现在, 我们就询问当前价格。如果是过去,那么我们就参考历史价格。在得到想要的价格后,最后我们用保证金值除以这个价格,赋值....。根据您的逻辑,如果 moment = 0,我们得到的将不是保证金转换,而只是市场价格或过去的价格...


一般来说,教科书最好用括号来 写:

令人信服。我同意,是我没注意。但是,如果你是为教科书而写,为了让我也能看懂,那么最好这样写

margin /= ( moment == 0 ?
                   SymbolInfoDouble(rate, ask ? SYMBOL_ASK : SYMBOL_BID) :
                   GetHistoricPrice(rate, moment, ask));