新版MetaTrader 5平台build 3490:移动网页端版本和MQL5的新矩阵方法 新评论 MetaQuotes 2022.10.17 08:39 MetaTrader 5平台更新将于2022年11月4日星期五进行发布。 该更新引入了全功能支持移动设备的新网页端。现在,界面会自动适应用户的屏幕尺寸。 此外,我们还改进了任务管理器,以便更准确地监控消耗的资源,并添加用于管理可用设备的OpenCL标签。新OpenCL管理器能够明确指定用于快速计算的设备。 我们还继续扩展了平台在处理矩阵和向量方面的能力。MQL5提供了用于价格报价操作以及矩阵和向量之间的数据交换的新功能。它还提供扩展的分配方法。 此外,我们还对所有平台组件进行多次修正和改进。所有新功能、修复和性能改进都在下面详细描述。 网页平台的移动端版本 全新网页端为移动设备提供全功能的支持。该界面将自动适应屏幕尺寸,实现iOS与Android手机和平板电脑的高效操作: 此外,网页端还进行多项修复和改进。 全新MetaTrader 5网页端支持全部交易功能。使用户能够: 使用模拟账户和真实账户进行交易 接收任何交易品种的报价 在任何市场进行交易 使用30多个指标和20个图形对象分析交易品种报价 使用经济日历数据进行基本面分析 MetaTrader 5 客户端 build 3490 程序端:扩展任务管理器功能。新版本可以更准确地监控消耗的资源。 添加线程中堆栈大小的显示。 添加上下文切换数量的显示。 添加对系统和第三方DLL线程的识别。 添加内核模式运行时间的显示。与在用户模式下花费的时间相比,该指标的增加可能表明系统级问题:驱动程序问题、硬件错误或减缓硬件。更多细节,请参阅Microsoft文档。 添加用户模式运行时间的显示。 程序端:程序端设置中用于管理可用设备的新OpenCL选项卡。新OpenCL管理器能够明确指定用于计算的设备。 程序端:为在FIFO模式下运行的账户添加在市场深度中止损和止盈水平的指示(该模式可以在交易商端启用)。 根据FIFO规则,每个交易品种的持仓只能按照开仓的相同顺序进行平仓。为确保通过止损位平仓符合FIFO标准,在客户端实施以下逻辑: 如果同一交易品种存在多个持仓,则为任何持仓设置止损水平会导致所有其他持仓也设置相同的水平。因此,如果触发一个水平,则所有仓位都将按照FIFO规则平仓。 现在,当用户为已经有未结持仓的交易品种打开市场深度时,现有持仓水平(如果有)会自动在止损和止盈字段中指定。 程序端:修正使用工具箱\交易窗口中的X按键删除止损和止盈水平的问题。该错误通常在禁用快速交易功能时发生。单击该按键将打开一个交易对话框,其中包含相关级别的空值。 程序端:修正交易报告中的图形标题和最后手续费计算的问题。该部分可能显示报告统计中的不正确的利润,和净值与结余图的工具提示中的不正确值。 MQL5:添加向量和矩阵方法CopyTicks和CopyTicksRange。它们可以轻松地将报价数据数组复制到向量和矩阵中。 bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count); bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count); bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc); bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);复制的数据类型使用ENUM_COPY_TICKS枚举在"flags"参数中指定。以下值可供使用: COPY_TICKS_INFO = 1, // 由卖价和/或买价更改得出的报价 COPY_TICKS_TRADE = 2, // 由最后价和交易量更改得出的报价 COPY_TICKS_ALL = 3, // 所有报价都发生变化 COPY_TICKS_TIME_MS = 1<<8, // 以毫秒为单位的时间 COPY_TICKS_BID = 1<<9, // 卖价 COPY_TICKS_ASK = 1<<10, // 买价 COPY_TICKS_LAST = 1<<11, // 最后价 COPY_TICKS_VOLUME = 1<<12, // 交易量 COPY_TICKS_FLAGS = 1<<13, // 报价标识如果选择了多种数据类型(仅适用于矩阵),矩阵中的行序将对应于枚举中的值的顺序。 MQL5:扩展了matrix::Assign和vector::Assign方法的功能。 现在可以为矩阵分配一个一维数组或向量: bool matrix::Assign(const vector &vec);结果将是一个单行矩阵。 此外,现在可以将矩阵分配给向量(将执行矩阵平滑): bool vector::Assign(const matrix &mat); MQL5:为向量和矩阵添加Swap方法。 bool vector::Swap(vector &vec); bool vector::Swap(matrix &vec); bool vector::Swap(double &arr[]); bool matrix::Swap(vector &vec); bool matrix::Swap(matrix &vec); bool matrix::Swap(double &arr[]);每个数组、向量或矩阵都指向一个包含该对象元素的内存缓冲区。Swap方法实际上交换指向这些缓冲区的指针,而不将元素写入内存。因此,矩阵仍然是矩阵,向量仍然是向量。交换矩阵和矢量会产生一个带有矢量元素的单行矩阵和一个平面表示的带有矩阵元素的矢量(见Flat方法)。 //+------------------------------------------------------------------+ //| 脚本程序起始函数 | //+------------------------------------------------------------------+ void OnStart() { //--- matrix a= {{1, 2, 3}, {4, 5, 6}}; Print("a before Swap: \n", a); matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}}; Print("b before Swap: \n", b); //--- swap矩阵指针 a.Swap(b); Print("a after Swap: \n", a); Print("b after Swap: \n", b); /* a before Swap: [[1,2,3] [4,5,6]] b before Swap: [[5,10,15,20] [25,30,35,40] [45,50,55,60]] a after Swap: [[5,10,15,20] [25,30,35,40] [45,50,55,60]] b after Swap: [[1,2,3] [4,5,6]] */ vector v=vector::Full(10, 7); Print("v before Swap: \n", v); Print("b before Swap: \n", b); v.Swap(b); Print("v after Swap: \n", v); Print("b after Swap: \n", b); /* v before Swap: [7,7,7,7,7,7,7,7,7,7] b before Swap: [[1,2,3] [4,5,6]] v after Swap: [1,2,3,4,5,6] b after Swap: [[7,7,7,7,7,7,7,7,7,7]] */ }Swap()方法还可以使用动态数组进行操作(固定大小的数组不能作为参数传递)。数组可以是任何维度,但具有约定的大小,这意味着矩阵或向量的总大小必须是数组零维度的倍数。数组零维度是第一个索引处包含的元素数。例如,对于动态三维数组"double array[][2][3]",零维是第二维和第三维大小的乘积:2x3=6。因此,这样的数组只能在Swap方法中用于总大小为6的倍数的矩阵和向量:6、12、18、24等。考虑以下示例: //+------------------------------------------------------------------+ //| 脚本程序起始函数 | //+------------------------------------------------------------------+ void OnStart() { //--- 用7.0值填写1x10矩阵 matrix m= matrix::Full(1, 10, 7.0); Print("matrix before Swap:\n", m); //--- 尝试交换矩阵和数组 double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}; Print("array_small before Swap:"); ArrayPrint(array_small); if(m.Swap(array_small)) { Print("array_small after Swap:"); ArrayPrint(array_small); Print("matrix after Swap: \n", m); } else // 矩阵大小不是第一个数组维度的倍数 { Print("m.Swap(array_small) failed. Error ", GetLastError()); } /* matrix before Swap: [[7,7,7,7,7,7,7,7,7,7]] array_small before Swap: [,0] [,1] [,2] [,3] [,4] [0,] 1.00000 2.00000 3.00000 4.00000 5.00000 [1,] 6.00000 7.00000 8.00000 9.00000 10.00000 m.Swap(array_small) failed. Error 4006 */ //--- 使用更大的矩阵并重试交换操作 double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}, {3, 6, 9, 12, 15, 18, 21, 24, 27, 30} }; Print("array_static before Swap:"); ArrayPrint(array_static); if(m.Swap(array_static)) { Print("array_static after Swap:"); ArrayPrint(array_static); Print("matrix after Swap: \n", m); } else // 静态数组不能用于与矩阵交换 { Print("m.Swap(array_static) failed. Error ", GetLastError()); } /* array_static before Swap: [,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [0,] 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 9.00000 10.00000 [1,] 2.00000 4.00000 6.00000 8.00000 10.00000 12.00000 14.00000 16.00000 18.00000 20.00000 [2,] 3.00000 6.00000 9.00000 12.00000 15.00000 18.00000 21.00000 24.00000 27.00000 30.00000 m.Swap(array_static) failed. Error 4006 */ //--- 交换数组和矩阵的另一种尝试 double array_dynamic[][10]; // 动态数组 ArrayResize(array_dynamic, 3); // 设置第一维度大小 ArrayCopy(array_dynamic, array_static); //--- 现在为swap使用动态数组 if(m.Swap(array_dynamic)) { Print("array_dynamic after Swap:"); ArrayPrint(array_dynamic); Print("matrix after Swap: \n", m); } else // 没有错误 { Print("m.Swap(array_dynamic) failed. Error ", GetLastError()); } /* array_dynamic after Swap: [,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [0,] 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 matrix after Swap: [[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30]] */ } MQL5:添加向量和矩阵的LossGradient方法。这种方法计算损失函数对预测值的偏导函数的向量或矩阵。在线性代数中,这样的向量被称为梯度,并在机器学习中使用。 vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const; matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const; MQL5:启用SQLite中的FOREIGN KEYS,以在SQL查询中加强表格之间的关系。 示例: CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER, FOREIGN KEY(trackartist) REFERENCES artist(artistid) ); MQL5:修正根据方法和对象的不变性,选择对应类方法的问题。 MetaEditor:添加提交到MQL5存储中的评论的允许长度。 在大型项目中,向存储库提交修改时的详细评论被认为是很好的实践,但以前评论的长度被限制在128个字符。现在允许的长度最多260个字符。 MetaTester:提高可视模式下测试速度开关的灵敏度。 修正崩溃日志中的错误报告。 更新将通过实时更新系统提供。 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
MetaTrader 5平台更新将于2022年11月4日星期五进行发布。
该更新引入了全功能支持移动设备的新网页端。现在,界面会自动适应用户的屏幕尺寸。
此外,我们还改进了任务管理器,以便更准确地监控消耗的资源,并添加用于管理可用设备的OpenCL标签。新OpenCL管理器能够明确指定用于快速计算的设备。
我们还继续扩展了平台在处理矩阵和向量方面的能力。MQL5提供了用于价格报价操作以及矩阵和向量之间的数据交换的新功能。它还提供扩展的分配方法。
此外,我们还对所有平台组件进行多次修正和改进。所有新功能、修复和性能改进都在下面详细描述。
网页平台的移动端版本
全新网页端为移动设备提供全功能的支持。该界面将自动适应屏幕尺寸,实现iOS与Android手机和平板电脑的高效操作:
此外,网页端还进行多项修复和改进。
全新MetaTrader 5网页端支持全部交易功能。使用户能够:
MetaTrader 5 客户端 build 3490
根据FIFO规则,每个交易品种的持仓只能按照开仓的相同顺序进行平仓。为确保通过止损位平仓符合FIFO标准,在客户端实施以下逻辑:
如果同一交易品种存在多个持仓,则为任何持仓设置止损水平会导致所有其他持仓也设置相同的水平。因此,如果触发一个水平,则所有仓位都将按照FIFO规则平仓。
现在,当用户为已经有未结持仓的交易品种打开市场深度时,现有持仓水平(如果有)会自动在止损和止盈字段中指定。
bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count); bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count); bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc); bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
复制的数据类型使用ENUM_COPY_TICKS枚举在"flags"参数中指定。以下值可供使用:COPY_TICKS_INFO = 1, // 由卖价和/或买价更改得出的报价 COPY_TICKS_TRADE = 2, // 由最后价和交易量更改得出的报价 COPY_TICKS_ALL = 3, // 所有报价都发生变化 COPY_TICKS_TIME_MS = 1<<8, // 以毫秒为单位的时间 COPY_TICKS_BID = 1<<9, // 卖价 COPY_TICKS_ASK = 1<<10, // 买价 COPY_TICKS_LAST = 1<<11, // 最后价 COPY_TICKS_VOLUME = 1<<12, // 交易量 COPY_TICKS_FLAGS = 1<<13, // 报价标识
如果选择了多种数据类型(仅适用于矩阵),矩阵中的行序将对应于枚举中的值的顺序。现在可以为矩阵分配一个一维数组或向量:
bool matrix::Assign(const vector &vec);
结果将是一个单行矩阵。此外,现在可以将矩阵分配给向量(将执行矩阵平滑):
bool vector::Assign(const matrix &mat);
bool vector::Swap(vector &vec); bool vector::Swap(matrix &vec); bool vector::Swap(double &arr[]); bool matrix::Swap(vector &vec); bool matrix::Swap(matrix &vec); bool matrix::Swap(double &arr[]);
每个数组、向量或矩阵都指向一个包含该对象元素的内存缓冲区。Swap方法实际上交换指向这些缓冲区的指针,而不将元素写入内存。因此,矩阵仍然是矩阵,向量仍然是向量。交换矩阵和矢量会产生一个带有矢量元素的单行矩阵和一个平面表示的带有矩阵元素的矢量(见Flat方法)。//+------------------------------------------------------------------+ //| 脚本程序起始函数 | //+------------------------------------------------------------------+ void OnStart() { //--- matrix a= {{1, 2, 3}, {4, 5, 6}}; Print("a before Swap: \n", a); matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}}; Print("b before Swap: \n", b); //--- swap矩阵指针 a.Swap(b); Print("a after Swap: \n", a); Print("b after Swap: \n", b); /* a before Swap: [[1,2,3] [4,5,6]] b before Swap: [[5,10,15,20] [25,30,35,40] [45,50,55,60]] a after Swap: [[5,10,15,20] [25,30,35,40] [45,50,55,60]] b after Swap: [[1,2,3] [4,5,6]] */ vector v=vector::Full(10, 7); Print("v before Swap: \n", v); Print("b before Swap: \n", b); v.Swap(b); Print("v after Swap: \n", v); Print("b after Swap: \n", b); /* v before Swap: [7,7,7,7,7,7,7,7,7,7] b before Swap: [[1,2,3] [4,5,6]] v after Swap: [1,2,3,4,5,6] b after Swap: [[7,7,7,7,7,7,7,7,7,7]] */ }
Swap()方法还可以使用动态数组进行操作(固定大小的数组不能作为参数传递)。数组可以是任何维度,但具有约定的大小,这意味着矩阵或向量的总大小必须是数组零维度的倍数。数组零维度是第一个索引处包含的元素数。例如,对于动态三维数组"double array[][2][3]",零维是第二维和第三维大小的乘积:2x3=6。因此,这样的数组只能在Swap方法中用于总大小为6的倍数的矩阵和向量:6、12、18、24等。考虑以下示例:
//+------------------------------------------------------------------+ //| 脚本程序起始函数 | //+------------------------------------------------------------------+ void OnStart() { //--- 用7.0值填写1x10矩阵 matrix m= matrix::Full(1, 10, 7.0); Print("matrix before Swap:\n", m); //--- 尝试交换矩阵和数组 double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}; Print("array_small before Swap:"); ArrayPrint(array_small); if(m.Swap(array_small)) { Print("array_small after Swap:"); ArrayPrint(array_small); Print("matrix after Swap: \n", m); } else // 矩阵大小不是第一个数组维度的倍数 { Print("m.Swap(array_small) failed. Error ", GetLastError()); } /* matrix before Swap: [[7,7,7,7,7,7,7,7,7,7]] array_small before Swap: [,0] [,1] [,2] [,3] [,4] [0,] 1.00000 2.00000 3.00000 4.00000 5.00000 [1,] 6.00000 7.00000 8.00000 9.00000 10.00000 m.Swap(array_small) failed. Error 4006 */ //--- 使用更大的矩阵并重试交换操作 double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}, {3, 6, 9, 12, 15, 18, 21, 24, 27, 30} }; Print("array_static before Swap:"); ArrayPrint(array_static); if(m.Swap(array_static)) { Print("array_static after Swap:"); ArrayPrint(array_static); Print("matrix after Swap: \n", m); } else // 静态数组不能用于与矩阵交换 { Print("m.Swap(array_static) failed. Error ", GetLastError()); } /* array_static before Swap: [,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [0,] 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 9.00000 10.00000 [1,] 2.00000 4.00000 6.00000 8.00000 10.00000 12.00000 14.00000 16.00000 18.00000 20.00000 [2,] 3.00000 6.00000 9.00000 12.00000 15.00000 18.00000 21.00000 24.00000 27.00000 30.00000 m.Swap(array_static) failed. Error 4006 */ //--- 交换数组和矩阵的另一种尝试 double array_dynamic[][10]; // 动态数组 ArrayResize(array_dynamic, 3); // 设置第一维度大小 ArrayCopy(array_dynamic, array_static); //--- 现在为swap使用动态数组 if(m.Swap(array_dynamic)) { Print("array_dynamic after Swap:"); ArrayPrint(array_dynamic); Print("matrix after Swap: \n", m); } else // 没有错误 { Print("m.Swap(array_dynamic) failed. Error ", GetLastError()); } /* array_dynamic after Swap: [,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [0,] 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 matrix after Swap: [[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30]] */ }
vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const; matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER, FOREIGN KEY(trackartist) REFERENCES artist(artistid) );
更新将通过实时更新系统提供。