- 显示:
- 1534
- 等级:
- 已发布:
- 2018.02.27 09:28
-
需要基于此代码的EA交易或指标吗?请在自由职业者服务中订购 进入自由职业者服务
MQL5 的主要问题之一就是删除了内建的时间序列函数,而这样做可以使编程人员从开发角度有更完全的控制,但是它也使得速度变慢,因为需要一些步骤来每次创建和销毁用来访问时间序列数据的新的内存。
... if(CopyTime(symbol,timeframe,time,1,checkcandle)==1) { ...
让我们看一下常用的 iBarShift 算法。为了根据时间返回柱的索引 - 我们首先必须调用 ::CopyTime(...),它会创建一个动态数组,改变它的大小,复制数据,然后再在内存中销毁它。如果只是偶尔调用,这不是什么问题,但是因为时间序列函数在不同的时段中经常会多次调用,这种内存处理可能会大幅增加而造成显著变慢。考虑一下每一次程序调用使用这种方法的任何时间序列数据时,分配新内存所需的所有潜在的开销和浪费的资源。
为了使这些事情加速,这个开发库实现的是使用标准库的 CObject 和 CArrayObj 类来复制一次这些数组,再对特定的交易品种和周期调用时间序列时就重新访问它。这可能是一把双刃剑,因为初始化阶段花的时间比正常时间要长,而随后所有访问数据可能只需要原来1/100的时间。以 iBarShift() 为例, 这种新的算法工作得更快,它创建一个 int[] 数组,在数组中保存柱的索引整数,然后使用时间(转换为整数类型)作为数组地址来进行访问。换句话说,您就是直接传入时间作为直接的地址来访问数据,
这给我们带来了几个需要注意的问题:
在初始化阶段会花费较多的时间. 如果您并不打算在每个某时段的柱中访问时间序列数据超过几千次 (加在一起) 以上,您最好还是换个方法。
CiTimeSeries 类中的对象在新柱生成的时候会自动刷新储存的数据。把这个设为 "false" 将会把对象设为高性能模式使得对性能要求高的应用访问起来更快, 但是需要在随后的维护循环中人工刷新.
例子:
#include <itimeseries_nicholishen.mqh> //--- iTimeSeries 对象的全局声明 CiTimeSeries iBar; int OnInit() { //--- 初始化阶段 iBar.Init( NULL, PERIOD_CURRENT, false // bool 自动刷新 ); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| EA交易订单分时函数 | //+------------------------------------------------------------------+ void OnTick() { //--- if(hot_path_operations) { //例子 index = iBar.Shift(time); } else if(maintenance_path_operations) { iBar.Refresh(); } }
另外,您可以直接调用全局函数 (就像您在 MQL4 中那样),而不需要创建 CiTimeSeries对象的实例, 但是第一次访问的时间将会慢,因为首先它必须在后台初始化一个全局对象。如果您只想调用几次这些时间序列函数,以这种方法使用开发库可能会比较慢,但是,当您的算法需要调用超过几千次针对相同交易品种+时段设置的时间序列数据时,效率会有很大提高。
现在,最常用的 iBarShift 算法的开发者有一个很好的对"iBarShift"的性能测试,您可以在这里找到 https://www.mql5.com/zh/code/1864.
因为它是最准确最快的方法 (在本文发布的时候),我决定使用它作为基准来进行测试。
100,000个直接(全局)函数调用,计算结果时间比当前可用的最快方法要快50倍,而在初始化之后,在“高性能”模式下调用就快了超过100倍。
可用的公有方法和全局函数:
注意: 全局函数和 MetaTrader 4 是一样的,例如 iBarShift, iTime, 等等。
//--- 初始化一个交易品种和时段; 把自动刷新设为 false,以取得高性能模式 bool Init(string symbol=NULL, ENUM_TIMEFRAMES period = PERIOD_CURRENT, const bool autoRefresh = true ); //--- 在一个 ENUM_TIMEFRAMES 数组中初始化一个交易品种和所有时段; 如需高性能模式,要把自动刷新设为 false bool Init(string symbol, ENUM_TIMEFRAMES &period[], const bool autoRefresh = true );
//--- 初始化所有时段 bool InitAllPeriods ( string symbol = NULL, const bool autoRefresh=true);
//--- 把自动刷新设为 false 来人工管理数据的刷新 void AutoRefresh(const bool ref) { m_autoRefresh=ref; } bool AutoRefresh() const { return m_autoRefresh; }
//--- 人工刷新调用;刷新所有初始化时段的数据 bool Refresh();
CRatesArray *GetArrayObjPointer(string symbol, ENUM_TIMEFRAMES period);
- .Open = iOpen https://docs.mql4.com/series/iopen
- .High = iHigh https://docs.mql4.com/series/ihigh
- .Low = iLow https://docs.mql4.com/series/ilow
- .Close = iClose https://docs.mql4.com/series/iclose
- .Highest = iHighest https://docs.mql4.com/series/ihighest
- .Lowest = iLowest https://docs.mql4.com/series/ilowest
- .Volume = iVolume https://docs.mql4.com/series/ivolume
- .BarsTotal = iBars https://docs.mql4.com/series/ibars
- .Time = iTime https://docs.mql4.com/series/itime
- .Shift = iBarShift https://docs.mql4.com/series/ibarshift
由MetaQuotes Ltd译自英文
原代码: https://www.mql5.com/en/code/18305