程序库: MT4Orders - 页 63 1...565758596061626364656667686970...95 新评论 fxsaber 2021.06.02 16:21 #621 关于交易、自动交易系统和测试交易策略的论坛 库: MT4Orders fxsaber, 2021.06.02 10:09 应我的要求,MetaQutoes 已将该库的最新更新完全本地化为英文。现在可以在英文页面上看到最新版本的库,源代码中的注释已翻译成英文。 这与之前在英文页面上提供的版本有所不同。 // 更改列表: // 02.11.2018 // 修复:现在 MT4 仓位开仓价格在触发前不能为零。 // 修复:已考虑到某些交易服务器的一些罕见执行问题。 // 26.11.2018 // 修复:MT4 平仓头寸的魔法和注释:开仓交易相关字段的优先级高于平仓交易。 // 修复:在计算 MT4 订单总额和 MT4 订单选择时考虑 MT5 订单总额和 MT5 仓位总额的罕见变化。 // 修复:库不考虑已开仓但尚未从 MT5 中删除的订单。 // 17.01.2019 // 修复:修复了在选择挂单时出现的不幸错误。 // 08.02.2019 // 添加:通过 OrderClose 在部分平仓时保存仓位注释。 // 如果需要在部分平仓时修改未结头寸的注释,可以在 OrderClose 中指定。 // 20.02.2019 // 修复:在没有 MT5 订单的情况下,程序库将期望从现有的 MT5 交易中同步历史记录。如果失败,它将发出通知。 // 13.03.2019 // 添加:已添加 OrderTicketID() - MT5 交易或 MT5 仓位的 PositionID,以及 MT4 挂单的 ticket。 // 添加:SELECT_BY_TICKET 适用于所有 MT5 票(和 MT5-PositionID)。 // 02.11.2019 // 修复:更正了 "平仓 "头寸的手数、佣金和平仓价格。 // 12.01.2020 // 修复:余额交易的 OrderTicketID() 现在可返回正确的值。 // 修复:修复了 SELECT_BY_TICKET - 通过 OrderTicketID() 进行选择的问题(MT5-PositionID)。 // 修复:更改了内部库方法的名称,以便与宏更加兼容。 // 10.04.2020 // 修复:部分执行的实时挂单未进入 OrdersTotal() 中的问题。 // 09.06.2020 // 添加:平仓的 StopLoss/TakeProfit/ClosePriceRequest 现在定义得更好了。 // 10.06.2020 // 添加:在 OrderPrint() 中添加毫秒,删除价格和订单四舍五入。 // 13.08.2020 // 添加:增加了通过 MT4ORDERS_BENCHMARK_MINTIME 宏检查库部件性能的功能。 // 20.08.2020 // 修正:考虑到部分订单执行所揭示的特征。 // 29.08.2020 // 修复:更快地处理历史交易。 // 24.09.2020 // 添加:通过 SELECT_BY_TICKET(相同的票据)选择 MT4 实时订单时,如果需要提高 MT5 订单相对于 MT5 仓位的优先级、 // 可以通过将票据大小改为负值来实现:OrderSelect(-Ticket, SELECT_BY_TICKET)。 // 添加:如果您需要在修改 MT4 实时订单时指定只选择 MT5 订单(相同的票据)、 // 可以通过将票据大小改为负值来实现:OrderModify(-Ticket, ...)。 // 添加:OrderSelect(INT_MAX, SELECT_BY_POS) - 无需检查是否存在和更新,即可切换到 MT5 仓位。 // OrderSelect(INT_MIN, SELECT_BY_POS) - 切换到 MT5 实时订单,无需检查是否存在和更新。 // 修复:更快地处理历史交易。 // 30.09.2020 // 修复:更快地处理历史交易。 // 08.10.2020 // 修复:由于 MT5 新交易搜索中的缺陷,市场订单的 OrderSend 执行时间可能更长。 // 21.10.2020 // 添加:为与 MT4 兼容,添加 OrderTicketID() - 返回 OrderTicket()。 // 11.11.2020 // 修复:OrderTicketID() 和 OrderTicketOpen() 返回 TICKET_TYPE 中指定的值类型。 // 06.12.2020 // 修复:MT5 交易历史中出现错误的 SL/TP 执行记录的情况现在会得到考虑。 // 添加:MT4ORDERS_TESTER_SELECT_BY_TICKET 市场强制 SELECT_BY_TICKET 仅通过 OrderTicketID() 在测试器中运行。 // 04.05.2021 // 修复:建仓但未能消失的 MT5 订单不再添加到 MT4 订单列表中。 // 修复:CloseBy MT5 订单不再出现在 MT4 订单列表中。 // 12.05.2021 // 添加:MT4ORDERS_BYPASS_MAXTIME 宏可改变 MT5 中不断出现的交易环境不同步情况。 // 13.05.2021 // 修复:修复了 OrderOpenReason() 中的错误。 // 14.05.2021 // 修复:BYPASS 机制不再影响 OrderSelect(INT_MAX, SELECT_BY_POS) 和 OrderSelect(INT_MIN, SELECT_BY_POS)。 // 01.06.2021 // 修复:与编译器第 2449 版及更高版本的兼容性问题。 // 修复:改进了同步功能。ByPass.mqh 必须是最新版本。 // 添加:OrderLots(true) - 所选仓位的同步大小,考虑到关闭该仓位的所有订单。 我建议使用最新版本和同步机制。这样,所有其他交易库无法解决的问题都会迎刃而解。 #define MT4ORDERS_BYPASS_MAXTIME 1000000 // 等待交易环境同步的最长时间(以微秒为单位 #include <MT4Orders.mqh> //https://www.mql5.com/en/code/16006 为使该机制发挥作用,您需要下载该库。所有复杂而有效的交易环境正确性检查都将自动完成,用户在编写交易逻辑时不会分心。 fxsaber 2021.06.11 09:56 #622 MT4Orders (+ByPass) 仅适用于 HistorySelect(0,INT_MAX),因此不会产生当前将刚删除的订单添加到历史表(+同步)末尾的问题。 fxsaber 2021.06.17 03:16 #623 fxsaber: MT4Orders (+ByPass) 仅适用于 HistorySelect(0,INT_MAX),因此不会产生当前将刚删除的订单添加到历史表(+sync)末尾的问题。 已损坏! 我不建议更新 MT5。谁能理解并帮助解释 MT5 以前的行为是正确的。现在不是了。 mktr8591 2021.06.17 22:42 #624 fxsaber:坏了! 我不建议更新 MT5。谁能理解并帮助解释 MT5 以前的行为是正确的。现在不是了。 可悲。 我草拟了一段代码,说明如何跟踪历史订单插入情况,并仅在 "移位 "期间+不超过 100 个历史仓位(即血量很少)时更新 TradesID 类。 我没有测试过这段代码,而且它当然也不是最佳的 - 只是演示一下这个想法。(黄色 - 与您的原始代码相比有哪些变化) //跟踪订单插入和历史缓存的示例想法 //不跟踪票号的删除或更改 // 基于交易 ID #include "Classificator.mqh" class TRADESID { CLASSIFICATOR<ulong, ulong> OrdersID; CLASSIFICATOR<ulong, ulong> DealsID; int LastTotalOrders; int LastTotalDeals; //在历史记录的每一百个位置上都有一个订单 ulong OrderTickets[]; void RefreshOrders(void) { static ulong LastOrderTicket = -1; //从上一次传递中提取的订单票据 if(::HistorySelect(0, INT_MAX)) { const int Total = ::HistoryOrdersTotal(); if(this.LastTotalOrders > 0 && LastOrderTicket != ::HistoryOrderGetTicket(this.LastTotalOrders - 1)) { int i; //按相反顺序检查每一百张票 for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--) ; if(i < 0) LastTotalOrders = 0; else {LastTotalOrders = i * 100 + 1; LastOrderTicket = OrderTickets[i];} ArrayResize(OrderTickets, i + 1); } while(this.LastTotalOrders < Total) { const ulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders); //(this.LastTotalOrders++) // 为历史记录的每一百个位置添加一张票到数组中 if(LastTotalOrders++ % 100 == 0) OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket; const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID); if(PositionID) { this.OrdersID.Add(PositionID, Ticket); const ulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID); if(PositionBy) this.OrdersID.Add(PositionBy, Ticket); } } } return; } }; 跟踪订单删除/更改要困难得多,但您的 "圣经 "也没有解决这个问题。 当然,ByPASS 和 MT4HISTORY 需要更复杂的算法来进行校正,但似乎并不复杂(我还没研究过)。 mktr8591 2021.06.17 23:00 #625 您还可以跟踪TRADE_TRANSACTION_HISTORY_UPDATE 和 TRADE_TRANSACTION_HISTORY_DELETE 交易: https://www.mql5.com/ru/forum/366029/page2#comment_22442705 如果他们提供了票据编号,并且历史记录中的订单是按票据排序的,那么就可以通过 OrderTickets 数组轻松跟踪订单在历史记录中的位置。 附注:作为最后手段,您还可以添加 HashMap... Библиотеки: TradesID 2021.05.13www.mql5.com Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: TradesID fxsaber 2021.06.17 23:15 #626 mktr8591:真可悲如果他们不按原样返回,我们可以制作一个拐杖。 我草拟了一个代码,如何在历史记录中跟踪订单插入情况,并仅在 "移位 "期间 + 不超过 100 个历史仓位时在 TradesID 类中进行更新,即几乎不流血。我没有测试过这段代码,而且它当然也不是最佳代码,只是演示一下而已。(黄色 - 与您的原始代码相比有何变化) 如果我没有理解错的话,您是在寻找发生移动的百位数。但我不明白,新票据本身是如何出现在那一百张票据中的?特别是如果有多个票单,而且它们位于不同的百位上。 跟踪订单删除/更改要困难得多,但你的 "圣经 "也没有解决这个问题。 我不明白。到底是什么没有被跟踪?我建议暂时停止b2958。 如果是为了追溯编辑历史--那就不值得了。创建解决方案不是为了书呆子气,而是为了交易。 当然,ByPASS 和 MT4HISTORY 需要更复杂的算法来进行此类修正,但似乎并不复杂(我还没研究过)。 问题是,每次传递调用的常规函数越多,出现滞后的概率就越高。EA 开始挂起。多个智能交易系统--情况更糟。当有多个终端时,情况就更糟糕了。甚至 OnTradeTransaction 的到达也会变慢--例如,OrderSend 的时间开始比 ping 的时间长几倍。事实上,这根拐杖不仅意味着疯狂调试,还会造成滞后。试想一下,在枚举过程中,历史记录等会被更新。这样就会出现大量的 bug。 毕竟,最重要的是一切都工作得很完美。他们只是把它弄坏了,却不做任何评论。 对我来说,ZЫ 是一个谜,为什么几乎没有人明白它是怎么回事。 Andrey Khatimlianskii 2021.06.18 06:00 #627 fxsaber:ZЫ 我很奇怪,为什么几乎没有人明白这一切是怎么回事。 因为没有人尝试过在 MT5 中(a)轻松、(b)正确、(c)快速地使用订单。包括我在内。 mktr8591 2021.06.18 10:46 #628 fxsaber:如果我没有理解错的话,你是在寻找发生转变的那一百张票。但我不明白,新票据本身如何位于这一百个中。特别是如果有几张票,而且它们位于不同的百位上。 如果只有插入而没有删除,那么循环 for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--) ; 循环搜索插入票据的最早百位的开头。您不需要搜索票据本身,只需要查看从这一百个开始的所有订单和下一个(更新的)订单,并将它们添加到哈希米表中。这通常是在 while(this.LastTotalOrders < Total) 循环中完成的,几乎总是最后的 1-2 百个订单。 减少步长可能更好,不是 100 步,而是 40 或 20 步。 如果在 for 期间历史发生了变化--在找到的百单之前插入了一些东西,可以将其放入循环: void RefreshOrders(void) { static ulong LastOrderTicket = -1; //从上一次传递中提取的订单票据 if(::HistorySelect(0, INT_MAX)) { // 我们需要对 IsStopped 和最大执行时间添加检查 while(this.LastTotalOrders > 0 && LastOrderTicket != ::HistoryOrderGetTicket(this.LastTotalOrders - 1)) { int i; //按相反顺序检查每一百张票 for(i = ArraySize(OrderTickets) - 1; i >= 0 && OrderTickets[i] !=::HistoryOrderGetTicket(i * 100) ; i--) ; if(i < 0) LastTotalOrders = 0; else {LastTotalOrders = i * 100 + 1; LastOrderTicket = OrderTickets[i];} ArrayResize(OrderTickets, i + 1); ::HistorySelect(0, INT_MAX); } const int Total = ::HistoryOrdersTotal(); while(this.LastTotalOrders < Total) { const ulong Ticket = LastOrderTicket = ::HistoryOrderGetTicket(this.LastTotalOrders); // 为历史记录的每一百个位置添加一张票到数组中 if(LastTotalOrders++ % 100 == 0) OrderTickets[::ArrayResize(OrderTickets, ::ArraySize(OrderTickets) + 1) - 1] = Ticket; const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID); if(PositionID) { this.OrdersID.Add(PositionID, Ticket); const ulong PositionBy = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_BY_ID); if(PositionBy) this.OrdersID.Add(PositionBy, Ticket); } } } return; } 但这种情况很少见。 fxsaber 2021.06.18 10:56 #629 mktr8591:如果只有插入而没有删除,那么循环循环会搜索发生插入的最早 100 张订单的起始位置。您不需要搜索票据本身,只需查看从这一百张票开始的所有订单以及下一张(较新的)订单,并将它们添加到哈希米表中。这通常是在 while(this.LastTotalOrders < Total) 循环中完成的,几乎总是最后 1-2 个百次。 也就是说,重复将同一票添加到哈希米表不会改变哈希米表吗? 我曾遇到过订单达到第八百个的情况。在活跃的交易中,这是新建仓的常见现象。 在这种情况下,您需要哈希米表几百个订单。 mktr8591 2021.06.18 15:12 #630 fxsaber:也就是说,重复向哈希米表添加同一张票不会改变哈希米表吗? 是的,刚才我注意到--如果重复添加票据 OrdersID.Add(PositionID,票据),那么在 OrdersID.ValuesID[] 中,该票据将被反转。也就是说,哈希表会膨胀。 我们需要以某种方式进行检查。或者使用 HashSet 代替 VALUESID 的数组结构。或者类似的方法。 1...565758596061626364656667686970...95 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
关于交易、自动交易系统和测试交易策略的论坛
库: MT4Orders
fxsaber, 2021.06.02 10:09
应我的要求,MetaQutoes 已将该库的最新更新完全本地化为英文。现在可以在英文页面上看到最新版本的库,源代码中的注释已翻译成英文。
这与之前在英文页面上提供的版本有所不同。
我建议使用最新版本和同步机制。这样,所有其他交易库无法解决的问题都会迎刃而解。
为使该机制发挥作用,您需要下载该库。所有复杂而有效的交易环境正确性检查都将自动完成,用户在编写交易逻辑时不会分心。
MT4Orders (+ByPass) 仅适用于 HistorySelect(0,INT_MAX),因此不会产生当前将刚删除的订单添加到历史表(+sync)末尾的问题。
已损坏! 我不建议更新 MT5。谁能理解并帮助解释 MT5 以前的行为是正确的。现在不是了。
坏了! 我不建议更新 MT5。谁能理解并帮助解释 MT5 以前的行为是正确的。现在不是了。
可悲。
我草拟了一段代码,说明如何跟踪历史订单插入情况,并仅在 "移位 "期间+不超过 100 个历史仓位(即血量很少)时更新 TradesID 类。
我没有测试过这段代码,而且它当然也不是最佳的 - 只是演示一下这个想法。(黄色 - 与您的原始代码相比有哪些变化)
跟踪订单删除/更改要困难得多,但您的 "圣经 "也没有解决这个问题。
当然,ByPASS 和 MT4HISTORY 需要更复杂的算法来进行校正,但似乎并不复杂(我还没研究过)。
您还可以跟踪TRADE_TRANSACTION_HISTORY_UPDATE 和 TRADE_TRANSACTION_HISTORY_DELETE 交易:
https://www.mql5.com/ru/forum/366029/page2#comment_22442705
如果他们提供了票据编号,并且历史记录中的订单是按票据排序的,那么就可以通过 OrderTickets 数组轻松跟踪订单在历史记录中的位置。
附注:作为最后手段,您还可以添加 HashMap...
真可悲
如果他们不按原样返回,我们可以制作一个拐杖。 我草拟了一个代码,如何在历史记录中跟踪订单插入情况,并仅在 "移位 "期间 + 不超过 100 个历史仓位时在 TradesID 类中进行更新,即几乎不流血。
我没有测试过这段代码,而且它当然也不是最佳代码,只是演示一下而已。(黄色 - 与您的原始代码相比有何变化)
如果我没有理解错的话,您是在寻找发生移动的百位数。但我不明白,新票据本身是如何出现在那一百张票据中的?特别是如果有多个票单,而且它们位于不同的百位上。
跟踪订单删除/更改要困难得多,但你的 "圣经 "也没有解决这个问题。
我不明白。到底是什么没有被跟踪?我建议暂时停止b2958。
如果是为了追溯编辑历史--那就不值得了。创建解决方案不是为了书呆子气,而是为了交易。
当然,ByPASS 和 MT4HISTORY 需要更复杂的算法来进行此类修正,但似乎并不复杂(我还没研究过)。
问题是,每次传递调用的常规函数越多,出现滞后的概率就越高。EA 开始挂起。多个智能交易系统--情况更糟。当有多个终端时,情况就更糟糕了。甚至 OnTradeTransaction 的到达也会变慢--例如,OrderSend 的时间开始比 ping 的时间长几倍。事实上,这根拐杖不仅意味着疯狂调试,还会造成滞后。试想一下,在枚举过程中,历史记录等会被更新。这样就会出现大量的 bug。
毕竟,最重要的是一切都工作得很完美。他们只是把它弄坏了,却不做任何评论。
对我来说,ZЫ 是一个谜,为什么几乎没有人明白它是怎么回事。
ZЫ 我很奇怪,为什么几乎没有人明白这一切是怎么回事。
因为没有人尝试过在 MT5 中(a)轻松、(b)正确、(c)快速地使用订单。包括我在内。
如果我没有理解错的话,你是在寻找发生转变的那一百张票。但我不明白,新票据本身如何位于这一百个中。特别是如果有几张票,而且它们位于不同的百位上。
如果只有插入而没有删除,那么循环
循环搜索插入票据的最早百位的开头。您不需要搜索票据本身,只需要查看从这一百个开始的所有订单和下一个(更新的)订单,并将它们添加到哈希米表中。这通常是在 while(this.LastTotalOrders < Total) 循环中完成的,几乎总是最后的 1-2 百个订单。
减少步长可能更好,不是 100 步,而是 40 或 20 步。
如果在 for 期间历史发生了变化--在找到的百单之前插入了一些东西,可以将其放入循环:
但这种情况很少见。
如果只有插入而没有删除,那么循环
循环会搜索发生插入的最早 100 张订单的起始位置。您不需要搜索票据本身,只需查看从这一百张票开始的所有订单以及下一张(较新的)订单,并将它们添加到哈希米表中。这通常是在 while(this.LastTotalOrders < Total) 循环中完成的,几乎总是最后 1-2 个百次。
也就是说,重复将同一票添加到哈希米表不会改变哈希米表吗?
我曾遇到过订单达到第八百个的情况。在活跃的交易中,这是新建仓的常见现象。 在这种情况下,您需要哈希米表几百个订单。
也就是说,重复向哈希米表添加同一张票不会改变哈希米表吗?
是的,刚才我注意到--如果重复添加票据 OrdersID.Add(PositionID,票据),那么在 OrdersID.ValuesID[] 中,该票据将被反转。也就是说,哈希表会膨胀。
我们需要以某种方式进行检查。或者使用 HashSet 代替 VALUESID 的数组结构。或者类似的方法。