MT5和速度在行动 - 页 20 1...131415161718192021222324252627...94 新评论 Andrey Pogoreltsev 2020.08.29 07:19 #191 fxsaber: 可能有一个更快的选择。但是,在需要计算的条件中,向左走一步,逻辑可能就要发生很大的变化。不容易,一般来说。 CHashMap<ulong, ulong> DealsIn; // По PositionID возвращает DealIn. 这不是缓存,是索引。这里是缓存(代码的一部分)。 class DealInfo { public: datetime Closed; ulong Ticket; ulong Position; string Symbol; long Type; long Reason; double Volume; double Price; double Profit; double Swap; long Magic; }; class DealsComparer : public IComparer<DealInfo*> { int Compare(DealInfo* x, DealInfo* y) { int res = (int)(x.Closed - y.Closed); if (res == 0) { res = (int)(x.Ticket - y.Ticket); } return res; } }; CArrayList<DealInfo*> dealsHistory; inline bool UpdateDeals(CArrayList<DealInfo*> &deals, datetime &lastUpdated) { DealInfo* dealsToAdd[]; DealsComparer comparer; int toAdd = 0; DealInfo* deal; if (!HistorySelect(lastUpdated, TimeLocal() + 12*3600)) { return false; } for (int i = 0, total = HistoryDealsTotal(); i < total; i++) { DealInfo tmp; ulong ticket = HistoryDealGetTicket(i); if (ticket == 0) continue; datetime dt = (datetime)HistoryDealGetInteger(ticket, DEAL_TIME); if (lastUpdated < dt) { lastUpdated = dt; } if (HistoryDealGetInteger(ticket, DEAL_ENTRY) != DEAL_ENTRY_OUT) continue; ulong reason = HistoryDealGetInteger(ticket, DEAL_REASON); tmp.Ticket = ticket; tmp.Closed = dt; int idx = deals.BinarySearch(&tmp, &comparer); if (idx >= 0 && deals.TryGetValue(idx, deal) && deal != nullptr && deal.Ticket == ticket) continue; deal = new DealInfo; deal.Ticket = ticket; deal.Closed = dt; deal.Position = HistoryDealGetInteger(ticket, DEAL_POSITION_ID); deal.Symbol = HistoryDealGetString(ticket, DEAL_SYMBOL); deal.Type = HistoryDealGetInteger(ticket, DEAL_TYPE); deal.Reason = HistoryDealGetInteger(ticket, DEAL_REASON); deal.Volume = HistoryDealGetDouble(ticket, DEAL_VOLUME); deal.Price = HistoryDealGetDouble(ticket, DEAL_PRICE); deal.Swap = HistoryDealGetDouble(ticket, DEAL_SWAP); deal.Profit = HistoryDealGetDouble(ticket, DEAL_PROFIT); deal.Magic = HistoryDealGetInteger(ticket, DEAL_MAGIC); ArrayResize(dealsToAdd, toAdd + 1, total); dealsToAdd[toAdd++] = deal; } if (toAdd > 0) { deals.AddRange(dealsToAdd); deals.Sort(&comparer); } return (toAdd > 0); } 这段代码写得很仓促,考虑到频繁的ArrayResize,有很多需要完善的地方,但它确切地更新了缓存,按Closed排序。如果你想以后搜索,请使用你自己的索引。但你每次只需要更新一小部分。 我不记得为什么会有"12*3600",我不认为所有的交易都发给了我。 fxsaber 2020.08.29 07:42 #192 Andrey Pogoreltsev:这不是缓存,是一个索引。 请仔细阅读。 关于交易、自动交易系统和交易策略测试的论坛 MT5和速度在行动 fxsaber, 2020.08.28 21:10 纯粹的MQL5比部分(只有HistorySelectByPosition) 的缓存慢100倍。 在架构上 做完全的缓存--你需要仔细思考。有很多隐患。 这里是缓存(代码的一部分)。 这段代码写得很仓促,考虑到频繁的ArrayResize,还有一些需要改进的地方,但它是按Close排序更新缓存的。如果你想以后搜索,请使用你自己的索引。但你每次只需要更新一小部分。 这只是一个正面拯救历史的例子,没有现实世界的噱头。即使在MT4Orders中,部分缓存也是以5秒的幅度进行的... 我不记得为什么会有"12*3600",我不认为所有的交易都发给了我。 总是设置INT_MAX。 Andrey Pogoreltsev 2020.08.29 13:59 #193 fxsaber:从架构上看, 做完整的缓存需要大量的思考。有很多隐患。 那里真的没有什么复杂的东西。你可以用几个小时的时间进行抽查,例如,对所有可能出现在历史上的订单进行追溯(顺便说一下,这非常奇怪)。 这只是一个没有任何实时噱头的正面历史保存的例子。即使在MT4Orders中,部分缓存也是以5秒的幅度进行的... 总是设置INT_MAX。 我不明白这种转变的意义。因为如果有一个当前的时间戳,我想获得相对于它的时间,而你必须指定一个不存在的时间,这很奇怪。我有点想要一个合理的解释。 顺便说一下,我的缓存在有10K以上交易的真实账户上工作。 而到目前为止,代码中的主要刹车是网络功能。 Stanislav Korotky 2020.08.29 16:53 #194 只是路过,我想我要总结一下这里已经暗示过的内容。如果你需要不惜一切代价获得超快的性能,那就以传统的方式实现--以牺牲其他资源消耗为代价,例如内存。换句话说,当需要计算一些总值(可以不只是总时长)时,没有必要每次都在整个历史中运行一个循环,提前在 "数组"(或其他优化的数据结构)中全部计算好,然后只进行增量。而通过位置标识符(或任何参数,通过它进行分解)对一个值的请求将退化为一个存储单元的引用。在最一般的形式下--它是类似于OLAP的东西(虽然在我的实现中没有完成在线更新),但对于一个特定的问题可以做得更简单。 Renat Fatkhullin 2020.09.01 12:18 #195 在最新的测试版2588中,HistorySelect功能 的缓存非常好,几乎总是(除了第一次)是免费的。 我们可能会在发布前进行一些其他的改进。 正如我之前解释的那样,在MT5中,在每个事件发生前为每个EA自动创建市场快照,并没有额外的费用,因为在MT4中是这样做的。这减少了延迟,使机器人能够更快地运行。每个开发商都准确地问出了他的需求。 因此,你应该清楚地认识到,"在整个历史上调用HistorySelect,然后立即进行HistorySelectByPosition的另一次选择 "的做法会杀死之前创建的历史缓存。这是一针见血的做法。 发布后,我们将开始大量工作,增加新的更有效的MQL5函数和开放的本地订单/交易数据结构,因此我们可以简化和加快算法交易。 fxsaber 2020.09.01 19:59 #196 Renat Fatkhullin:在最新的2588测试版中,HistorySelect功能 的缓存非常好,而且几乎总是(除了第一次)是免费的。 #include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh input int inAlertTime = 1; // Нижний порог в миллисекундах #define _B2(A) _B(A, inAlertTime) #define ALERT(A) Alert(#A + " = " + (string)(A)) void OnInit() { if (HistorySelect(0, INT_MAX)) { ALERT(HistoryDealsTotal()); ALERT(HistoryOrdersTotal()); } } void OnTick() { static int i = 0; ALERT(i++); _B2(HistorySelect(TimeCurrent(), INT_MAX)); _B2(HistorySelect(0, INT_MAX)); } 结果。 2020.09.01 22:56:46.089 Test6 (EURAUD,M1) Alert: HistoryDealsTotal() = 9435 2020.09.01 22:56:46.089 Test6 (EURAUD,M1) Alert: HistoryOrdersTotal() = 12529 2020.09.01 22:56:46.575 Test6 (EURAUD,M1) Alert: i++ = 0 2020.09.01 22:56:46.579 Test6 (EURAUD,M1) Alert: Time[Test6.mq5 25: HistorySelect(0,INT_MAX)] = 3 ms. 2020.09.01 22:56:47.424 Test6 (EURAUD,M1) Alert: i++ = 1 2020.09.01 22:56:47.428 Test6 (EURAUD,M1) Alert: Time[Test6.mq5 25: HistorySelect(0,INT_MAX)] = 3 ms. 2020.09.01 22:56:47.765 Test6 (EURAUD,M1) Alert: i++ = 2 2020.09.01 22:56:47.768 Test6 (EURAUD,M1) Alert: Time[Test6.mq5 25: HistorySelect(0,INT_MAX)] = 3 ms. 2020.09.01 22:56:47.902 Test6 (EURAUD,M1) Alert: i++ = 3 2020.09.01 22:56:47.906 Test6 (EURAUD,M1) Alert: Time[Test6.mq5 25: HistorySelect(0,INT_MAX)] = 3 ms. 2020.09.01 22:56:48.453 Test6 (EURAUD,M1) Alert: i++ = 4 2020.09.01 22:56:48.456 Test6 (EURAUD,M1) Alert: Time[Test6.mq5 25: HistorySelect(0,INT_MAX)] = 3 ms. 2020.09.01 22:56:48.516 Test6 (EURAUD,M1) Alert: i++ = 5 2020.09.01 22:56:48.521 Test6 (EURAUD,M1) Alert: Time[Test6.mq5 25: HistorySelect(0,INT_MAX)] = 4 ms. 每一次打勾都有一个问题。 ZY安装了Win10,LatencyMon显示一切正常。 fxsaber 2020.09.01 20:14 #197 目前我看到,在99%的情况下,只应该使用HistorySelect(0,INT_MAX)。尽量不要使用其他选项。 fxsaber 2020.09.01 20:54 #198 Renat Fatkhullin:发布后,我们将开始大量的工作,增加新的更有效的MQL5函数,并开放本地订单/交易数据结构,以便简化 和加速算法交易。 MqlDeal、MqlOrder和MqlPosition会很好。它甚至可能变得更简单。 Dmi3 2020.09.01 20:54 #199 fxsaber: 目前,我看到在99%的情况下,我们应该只使用HistorySelect(0,INT_MAX)。尽量不要使用其他选项。 如果我的历史上有几十万个订单,是否也会比采取最后一分钟的历史更快? 那么,我是否必须经历所有这些历史?这是不符合逻辑的。 fxsaber 2020.09.01 21:01 #200 Dmi3:如果我的历史上有几十万个订单,是否也比取最后一分钟的历史更快? 在战斗机器人中只留下0-INT_MAX的变体。不再注意到滞后的问题。 1...131415161718192021222324252627...94 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
可能有一个更快的选择。但是,在需要计算的条件中,向左走一步,逻辑可能就要发生很大的变化。不容易,一般来说。
这不是缓存,是索引。这里是缓存(代码的一部分)。
这段代码写得很仓促,考虑到频繁的ArrayResize,有很多需要完善的地方,但它确切地更新了缓存,按Closed排序。如果你想以后搜索,请使用你自己的索引。但你每次只需要更新一小部分。
我不记得为什么会有"12*3600",我不认为所有的交易都发给了我。
这不是缓存,是一个索引。
请仔细阅读。
关于交易、自动交易系统和交易策略测试的论坛
MT5和速度在行动
fxsaber, 2020.08.28 21:10
纯粹的MQL5比部分(只有HistorySelectByPosition) 的缓存慢100倍。
这里是缓存(代码的一部分)。
这段代码写得很仓促,考虑到频繁的ArrayResize,还有一些需要改进的地方,但它是按Close排序更新缓存的。如果你想以后搜索,请使用你自己的索引。但你每次只需要更新一小部分。
这只是一个正面拯救历史的例子,没有现实世界的噱头。即使在MT4Orders中,部分缓存也是以5秒的幅度进行的...
我不记得为什么会有"12*3600",我不认为所有的交易都发给了我。
总是设置INT_MAX。
从架构上看, 做完整的缓存需要大量的思考。有很多隐患。
那里真的没有什么复杂的东西。你可以用几个小时的时间进行抽查,例如,对所有可能出现在历史上的订单进行追溯(顺便说一下,这非常奇怪)。
这只是一个没有任何实时噱头的正面历史保存的例子。即使在MT4Orders中,部分缓存也是以5秒的幅度进行的...
总是设置INT_MAX。
我不明白这种转变的意义。因为如果有一个当前的时间戳,我想获得相对于它的时间,而你必须指定一个不存在的时间,这很奇怪。我有点想要一个合理的解释。
顺便说一下,我的缓存在有10K以上交易的真实账户上工作。
而到目前为止,代码中的主要刹车是网络功能。
在最新的测试版2588中,HistorySelect功能 的缓存非常好,几乎总是(除了第一次)是免费的。
我们可能会在发布前进行一些其他的改进。
正如我之前解释的那样,在MT5中,在每个事件发生前为每个EA自动创建市场快照,并没有额外的费用,因为在MT4中是这样做的。这减少了延迟,使机器人能够更快地运行。每个开发商都准确地问出了他的需求。
因此,你应该清楚地认识到,"在整个历史上调用HistorySelect,然后立即进行HistorySelectByPosition的另一次选择 "的做法会杀死之前创建的历史缓存。这是一针见血的做法。
发布后,我们将开始大量工作,增加新的更有效的MQL5函数和开放的本地订单/交易数据结构,因此我们可以简化和加快算法交易。
在最新的2588测试版中,HistorySelect功能 的缓存非常好,而且几乎总是(除了第一次)是免费的。
结果。
每一次打勾都有一个问题。
ZY安装了Win10,LatencyMon显示一切正常。
发布后,我们将开始大量的工作,增加新的更有效的MQL5函数,并开放本地订单/交易数据结构,以便简化 和加速算法交易。
MqlDeal、MqlOrder和MqlPosition会很好。它甚至可能变得更简单。
目前,我看到在99%的情况下,我们应该只使用HistorySelect(0,INT_MAX)。尽量不要使用其他选项。
如果我的历史上有几十万个订单,是否也会比采取最后一分钟的历史更快?
那么,我是否必须经历所有这些历史?这是不符合逻辑的。
如果我的历史上有几十万个订单,是否也比取最后一分钟的历史更快?
在战斗机器人中只留下0-INT_MAX的变体。不再注意到滞后的问题。