文章 "轻松快捷开发 MetaTrader 程序的函数库(第一部分)。 概念,数据管理和首期成果" - 页 4

 
fxsaber:

谢谢,解释得很清楚。但仍有一个问题--在 MT4 中显然更快,但如果我们讨论的是 5--分别执行所有方法是否比调用一个 CopyRates 更快?如果是,那么创建一个条形结构/类来代替MQLRates 是有意义的,这样就不会写入所有字段,而只会写入我们的情况下所需的字段,例如通过掩码。

 
alex_all:

谢谢,解释得很清楚。但仍有一个问题--在 MT4 中显然更快,但如果我们讨论的是 5--分别执行所有方法是否比调用一个 CopyRates 更快?如果是,那么创建自己的条形结构/类而不是MQLRates 是有意义的,因为MQLRates 不会写入所有字段,在我们的情况下只会写入必要的字段,例如通过掩码。

试试这个。

 
没有更新?
 
soldadoraso21:
不更新吗?

不更新。

我不明白这个问题。

 

由于这是一个正在开发中的程序库,我将等待更多文章后再做全面评论。

不过,我注意到第一部分有两个潜在的问题:

首先是

Sometimes, you may want to get the number of decimal places in a symbol lot. Let's enter this function to our file of service functions:

//+------------------------------------------------------------------+
//| 返回符号批次中的小数位数
//+------------------------------------------------------------------+
uint DigitsLots(conststring symbol_name) 
  { 
   return (int)ceil(fabs(log(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))/log(10)));
  }

1.a使用对数的 解决方案并不通用。例如,在某些符号上,您完全可以将体积步长设为 0.25,在这种情况下,DigitsLots() 将返回错误的答案。

1.b 您为什么需要 "符号手数的小数位数"?我看不出有什么实际用途。

1.c 如果您真的想使用对数函数,并且您将在其他地方处理特殊情况,您应该使用 log10,而不是自然对数。

return (int)ceil(fabs(log10(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))));

1.d 在公共接口上提供这样的函数可能会导致效率低下,因为它需要调用 5 个函数,而且每个 tick 都可能被调用多次。


其次

intOnInit()
  {
//---
   list_all_orders.Sort();
   list_all_orders.Clear();
   if(!HistorySelect(0,TimeCurrent()))
     {
      Print(DFUN,TextByLanguage(":Не удалось получить историю сделок и ордеров",": Failed to get history of deals and orders"));
      returnINIT_FAILED;
     }
   ...

2.a 这不是调用 HistorySelect() 的正确方法,因为 TimeCurrent() 会从经纪商服务器返回最后一个已知的刻度日期,所以可能会错过一些历史信息。理由来自这里 和经验。

2.b 在不能保证有经纪商连接的 OnInit() 函数中使用 TimeCurrent() 是个坏例子。一般来说,在 OnInit() 中进行任何数据请求都不是好主意。

 

感谢您的评论,但这只是一个测试。

  1. 我将考虑是否有可能将该函数改为另一种完全通用的函数
  2. 为了准确无误地发送交易指令,每个单独符号的手数的小数位数是必要的。
  3. 您的 log10 函数在手数为 0.25 时没有问题吗?
  4. 关于小数位数的数据将一次性写入符号类对象。这将在后续文章中进一步说明。

在 OnInit () 中需要进行测试检查。只有在这里,我才能以这种方式获得订单的历史记录。在订单、交易和头寸的集合中 - 否则。

所有这些将在后续文章中介绍。

-------------

Спасибо за комментарии, но это всего лишь тест.

  1. я рассмотрю возможность изменения функции на иную - полностью универсальную
  2. количество знаков после запятой для лота каждого отдельного символа нужно для безошибочной отправки торговых приказов
  3. ваша функция с log10 не имеет озвученной вами проблемы с шагом лота 0.25 ?
  4. данные о количестве знаков после запятой записываются единожды в объект класса-символ.Это будет далее - в последующих статьях

OnInit() 啟動時會自動啟動。И только там историю ордеров получаю таким образом.В коллекциях ордеров, сделок и позиций - иначе.

Всё это в последующих статьях.
 
Artyom Trishkin:

感谢您的评论,但这只是一次测试。

  1. 我将考虑是否有可能将该函数改为另一种完全通用的函数
  2. 为了准确无误地发送交易指令,每个单独符号的手数的小数位数是必要的。
  3. 您的 log10 函数在手数为 0.25 时没有问题吗?
  4. 关于小数位数的数据将一次性写入符号类对象。这将在以后的文章中进一步介绍。

在 OnInit () 中需要进行测试检查。只有在这里,我才能以这种方式获得订单的历史记录。在订单、交易和头寸的集合中 - 否则。

所有这些将在后续文章中介绍。


1.很好。

2.如果您对批量进行了正确的标准化处理,就不需要这样做,比如......:

 double lotStep=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
 lots=MathRound(lots/lotStep)*lotStep;

使用批号数字只会导致问题。

3. log10 也有同样的问题,它不是通用的。这样做只是为了避免调用 log(10) 时的无用功。

4.很好。

我知道这只是为了检查,但即使测试代码是公开的,我认为我们也有责任展示和使用好的做法。

我会阅读其他文章的。

 
Alain Verleyen:

1.好。

2.如果您对批次进行了正确的规范化处理,就不需要......这样的规范化处理:

使用批号数字只会导致问题。

3. log10 也有同样的问题,它不是通用的。这只是为了避免无用的 log(10) 调用。

4.很好。

我知道这只是为了检查,但即使测试代码是公开的,我认为我们也有责任展示和使用良好的做法。

我会阅读其他文章的。

好的。谢谢
 

您好

我可以说是您的入门者或学生。

我决定学习你们的资料库,但这对我来说很难,虽然我对 MQL 有所了解,但我在第一步就磕磕绊绊。

我找到了通过给定属性比较两个订单的方法的实现

//+------------------------------------------------------------------+
//|| 在所有可能的属性上相互比较 COrder 对象
//+------------------------------------------------------------------+
int COrder::Compare(const CObject *node,const int mode=0) const
  {
   const COrder *order_compared=node;
//--- 两阶整数特性的比较
   if(mode<ORDER_PROP_INTEGER_TOTAL)
     {
      long value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
      long value_current=this.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- 两阶实际属性的比较
   else if(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL)
     {
      double value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
      double value_current=this.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- 比较两个命令的字符串属性
   else if(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL+ORDER_PROP_STRING_TOTAL)
     {
      string value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_STRING)mode);
      string value_current=this.GetProperty((ENUM_ORDER_PROP_STRING)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
   return 0;
  }
//+------------------------------------------------------------------+

这是库中的代码,在哪里写呢

   //--- 在所有可能的属性上对 COrder 对象进行比较
   virtual int       Compare(const CObject *node,const int mode=0) const;

或抽象订单的保护类中。

protected:
   //--- 受保护的参数构造函数
                     COrder(ENUM_ORDER_STATUS order_status,const ulong ticket);
                     
   //--- 从参数中获取并返回所选订单的整数属性
   long              OrderMagicNumber(void)        const;
   long              OrderTicket(void)             const;
   long              OrderTicketFrom(void)         const;
   long              OrderTicketTo(void)           const;
   long              OrderPositionID(void)         const;
   long              OrderPositionByID(void)       const;
   long              OrderOpenTimeMSC(void)        const;
   long              OrderCloseTimeMSC(void)       const;
   long              OrderType(void)               const;
   long              OrderTypeByDirection(void)    const;
   long              OrderTypeFilling(void)        const;
   long              OrderTypeTime(void)           const;
   long              OrderReason(void)             const;
   long              DealOrder(void)               const;
   long              DealEntry(void)               const;
   bool              OrderCloseByStopLoss(void)    const;
   bool              OrderCloseByTakeProfit(void)  const;
   datetime          OrderOpenTime(void)           const;
   datetime          OrderCloseTime(void)          const;
   datetime          OrderExpiration(void)         const;
   datetime          PositionTimeUpdate(void)      const;
   datetime          PositionTimeUpdateMSC(void)   const;
   
   //--- 从参数中获取并返回所选订单的实际属性:(1) 开仓价,(2) 收盘价,(3) 利润、
   //--- (4) 佣金,(5) 互换,(6) 成交量,(7) 未成交量 (8) 止损价格,(9) 止盈价格 (10) 限价止损订单设置价格
   double            OrderOpenPrice(void)          const;
   double            OrderClosePrice(void)         const;
   double            OrderProfit(void)             const;
   double            OrderCommission(void)         const;
   double            OrderSwap(void)               const;
   double            OrderVolume(void)             const;
   double            OrderVolumeCurrent(void)      const;
   double            OrderStopLoss(void)           const;
   double            OrderTakeProfit(void)         const;
   double            OrderPriceStopLimit(void)     const;
   
   //--- 从参数中获取并返回所选订单的字符串属性:(1) 符号,(2) 注释,(3) 交易所标识符
   string            OrderSymbol(void)             const;
   string            OrderComment(void)            const;
   string            OrderExternalID(void)         const;
   
public:
   //--- 从属性数组中返回订单的 (1) 整数、(2) 实数和 (3) 字符串属性
   long              GetProperty(ENUM_ORDER_PROP_INTEGER property)      const { return m_long_prop[property];                    }
   double            GetProperty(ENUM_ORDER_PROP_DOUBLE property)       const { return m_double_prop[this.IndexProp(property)];  }
   string            GetProperty(ENUM_ORDER_PROP_STRING property)       const { return m_string_prop[this.IndexProp(property)];  }
   
   //--- 返回订单是否保持给定属性的标志
   virtual bool      SupportProperty(ENUM_ORDER_PROP_INTEGER property)        { return true; }
   virtual bool      SupportProperty(ENUM_ORDER_PROP_DOUBLE property)         { return true; }
   virtual bool      SupportProperty(ENUM_ORDER_PROP_STRING property)         { return true; }

请理解,我已经不再年轻了,年轻人可以很快掌握这些。

另外,我在论坛的文章和技术库中 开设了一个关于自动交易的 主题(12560) 我是 那里的学生,我将复制这个主题,我希望您能详细回答我的结构、

我希望您能详细回答有关结构的问题。你可能是错的,不明白。

Форум трейдеров - MQL5.community: Статьи и техническая библиотека по автоматическому трейдингу
Форум трейдеров - MQL5.community: Статьи и техническая библиотека по автоматическому трейдингу
  • www.mql5.com
Обсуждение статей по трейдингу и примеров на языках MQL4/MQL5
 
Vladimir Andreev:

您好

您可以把我当作您的申请人或学生。

我决定学习你们的图书馆,但这对我来说很难,虽然我对 MQL 有所了解,但我在第一步就绊倒了。

我已经达到了通过给定属性比较两个命令的方法的实现 点:

这是库中的代码,在哪里写?

之后

或抽象顺序的受保护类中

请理解,我已经不再年轻了,但年轻人可以在瞬间掌握它。

另外,我还在论坛的文章和技术库中 开设了一个关于自动交易的 主题(12560) 我是 那里的学生,我将复制这个主题,希望您能详细回答有关结构的问题、

我希望您能详细回答有关结构的问题,并根据文章一步一步地进行操作。您可能错了,也可能不理解。

创建类方法有两种方法 - 直接在类主体中创建:

class CMyClass
  {
   bool Flag(void) { return false; }
  }

和在类主体之外:

class CMyClass
  {
   bool Flag(void);
  }
//--- 在类主体之外实现的方法
bool CMyClass::Flag(void) { return false; }

在第一种情况下,方法直接在类主体中定义和实现--对于不占很多行的短方法来说,这样做很方便。但如果方法比较大,在类主体中声明方法,将实现放在类主体之外会更方便--如第二个例子。

很明显,将方法写在类主体中更方便。但你所询问的方法--将其与类主体分开编写会更方便。

不过,你可以下载文章所附的所有文件--它们已经包含了所有内容,可以随时使用--并用它们来研究文章中描述的内容。