EA: 交易者的MQL5编程(MQL5 Programming for Traders) - 源代码第六部分 - 页 2 123 新评论 pauldic 2025.10.23 19:23 #11 Stanislav Korotky #: 无论如何,订单、交易、头寸都与时间框架无关。你不是误解了什么,就是用词不当。 对不起,我想我用词不当,我说的"时间 范围 "是指 "日期范围"。如果我想选择在给定日期范围内成交的交易/订单,比如从 2025-10-01 00:00:00 到 2025-10-22 23:59:59 的交易。 Stanislav Korotky 2025.10.24 12:03 #12 pauldic #: 对不起,我想我用词不当,我说的"时间 范围 "是指 "日期范围"。如果我想选择在给定日期范围内成交的交易/订单,比如从 2025-10-01 00:00:00 到 2025-10-22 23:59:59 的交易。 如果要分析交易历史的子范围,在不影响过滤代码本身的情况下,在过滤之前只请求这部分历史记录会更有效:input datetime SubrangeFrom = 0; input datetime SubrangeTo = 0; ... { HistorySelect(SubrangeFrom, SubrangeTo); // ......过滤器代码在这里保持不变 }如果出于某种原因,您想在HistorySelect 应用的全局范围内选择一个(更窄的)子范围,那么您仍然可以在过滤代码中这样做:{ // 其中一些在这里 // HistorySelect(0, LONG_MAX); // HistorySelectByPosition(PositionID); ... DealTuple deals[]; if(SubrangeFrom != SubrangeTo && SubrangeFrom < SubrangeTo) { filter.let(DEAL_TIME, SubrangeFrom - 1, IS::GREATER).let(DEAL_TIME, SubrangeTo + 1, IS::LESS); } filter.let(DEAL_POSITION_ID, PositionID).select(deals, true); ... }黄线高亮部分使用额外的限定符 IS::GREATER 和 IS::LESS(默认情况下,在调用let() 时不会指定这两个限定符,而 IS::EQUAL 通常用于单值字段)为日期时间范围 [SubrangeFrom, SubrangeTo] 设置了两个条件。我只知道一个按日期范围应用子过滤器的原因,那就是订单的设置时间 (ORDER_TIME_SETUP),因为HistorySelect 应用于订单的另一个日期时间属性,即订单执行时间 (ORDER_TIME_DONE)。此外,如果有很多有效订单,过滤有效订单的子范围(不在历史中)可能会很有趣。 您可以从MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5 示例脚本开始。 pauldic 2025.10.24 12:56 #13 Stanislav Korotky #:如果要分析交易历史的一个子范围,在不影响过滤代码本身的情况下,在过滤前只请求分析这部分历史记录会更有效:如果出于某种原因,您想在HistorySelect 应用的全局范围内选择一个(更窄的)子范围,那么您仍然可以在过滤代码中这样做:黄线高亮部分使用额外的限定符 IS::GREATER 和 IS::LESS(默认情况下,在其他调用let() 时不指定这两个限定符,而 IS::EQUAL 通常用于单值字段)为日期时间范围 [SubrangeFrom, SubrangeTo] 设置了两个条件。我只知道一个按日期范围应用子过滤器的原因,那就是订单的设置时间 (ORDER_TIME_SETUP),因为HistorySelect 应用于订单的另一个日期时间属性,即订单执行时间 (ORDER_TIME_DONE)。此外,如果有很多有效订单,过滤有效订单的子范围(不在历史中)可能会很有趣。 您可以从MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5 示例脚本开始。 @StanislavKorotky 再次感谢...这对我来说是一个很好的起点,我将开始使用它。 Stanislav Korotky 2025.12.21 19:08 #14 修正MQL5/Include/MQL5Book/TradeUtils.mqh. bool Equal(const double v1, const double v2) { return v1 == v2 || fabs(v1 - v2) < DBL_EPSILON * fmax(1.0, fmax(fabs(v1), fabs(v2))); } 附加的文件: TradeUtils.mqh 12 kb Anil Varma 2025.12.22 13:55 #15 pauldic #: 插入代码 时请 使用代码 按钮 (Alt-S)。 版主对错误粘贴的代码进行了格式化。通常,此类代码会被删除。 @StanislavKorotky 请您帮忙看看这个错误,我相信它是在 MT5 更新后开始出现的,因为我知道代码在前几个月没有任何修改的情况下也能正常工作。 参数转换类型 'long[][2]' 到 'string[][] &' 是不允许的 SymbolFilter.mqh 199 20 不允许将参数类型 'double[][2]' 转换为 'string[][] &' TradeFilter.mqh 332 20 不允许将参数类型 'long[][2]' 转换为 'string[][] &' TradeFilter.mqh 163 17 我怀疑下面的代码有助于复制该问题: 你好@Paul Dick 请尝试使用https://www.mql5.com/zh/code/57233 对数组进行排序 Introsort (Introspective sort) using Function Pointers 2025.03.18www.mql5.com A hybrid sorting algorithm that provide fast performance for sorting arrays of simple types, structures or object pointers. Stanislav Korotky 2025.12.22 23:13 #16 现附上基于 R2 -RSquared.mqh 的自定义优化 准则计算文件的更新版本,其中对变量手数的计算进行了修正。 估算质量有了明显改善--从优化结果 表中可以看出,已经获得了恢复系数和夏普参数的组合。 使用示例 double OnTester() { HistorySelect(0, LONG_MAX); #define STAT_PROPS 5 const ENUM_DEAL_PROPERTY_DOUBLE props[STAT_PROPS] = { DEAL_PROFIT, DEAL_SWAP, DEAL_COMMISSION, DEAL_FEE, DEAL_VOLUME }; double expenses[][STAT_PROPS]; ulong tickets[]; // 仅用于匹配 "选择 "原型,但对调试很有用 DealFilter filter; filter.let(DEAL_TYPE, (1 << DEAL_TYPE_BUY) | (1 << DEAL_TYPE_SELL), IS::OR_BITWISE) .let(DEAL_ENTRY, (1 << DEAL_ENTRY_OUT) | (1 << DEAL_ENTRY_INOUT) | (1 << DEAL_ENTRY_OUT_BY), IS::OR_BITWISE) .select(props, tickets, expenses); const int n = ArraySize(tickets); double balance[]; double volumes[]; // 使用 R2 标准时考虑贸易量 ArrayResize(balance, n + 1); balance[0] = 0; ArrayResize(volumes, n + 1); volumes[0] = 0; for(int i = 0; i < n; ++i) { double result = 0; for(int j = 0; j < STAT_PROPS - 1; ++j) { result += expenses[i][j]; } // 以数量为模型 - 更多投资 - 更多预期回报 volumes[i + 1] = expenses[i][STAT_PROPS - 1] + volumes[i]; balance[i + 1] = result + balance[i]; } const double r2 = RSquaredTest(balance, volumes); #undef STAT_PROPS return r2 * 100; } 附加的文件: RSquared.mqh 4 kb hini 2026.01.15 12:56 #17 我最近在学习 Frame,并测试了您的代码 FrameTransfer.mq5。在当前的 MT5 编译器中,这一行出现了错误。请验证:#property tester_set "FrameTransfer.set" (invalid tester set file extension, '*.set' expected FrameTransfer.mq5) 必须这样修改才能成功编译:#property tester_set "\\Presets\FrameTransfer.set" 甚至 `#property tester_set "/Presets/FrameTransfer.set"` 也会失败。 也许你可以修改算法书中的描述: Stanislav Korotky 2026.01.15 15:17 #18 hini #属性 tester_set "FrameTransfer.set"(测试器设置文件扩展名无效,"*.set "应为 FrameTransfer.mq5) 若要成功编译,应作如下更改:#property tester_set "\\Presets\\FrameTransfer.set"即使是 `#property tester_set "/Presets/FrameTransfer.set"` 也会失败。也许你可以修改算法书中的描述: 这是一个明显的编译器错误--它给代码带来了错误:"无效的 tester set 文件扩展名,'*.set'预期": #property tester_set "FrameTransfer.set" 其中文件具有所需的扩展名。文件位置路径与此无关。 这个错误由来已久,至少从 2024 年就存在了。我不知道为什么 MQ 不急于修复它。 至于图书编辑,在这种情况下并不需要,但无论如何,图书现在完全由 MQ 控制。 Alain Verleyen 2026.01.15 16:33 #19 Stanislav Korotky 控制。 已确认并报告。让我们看看是否会得到修复。 Ilyas 2026.01.16 14:22 #20 Stanislav Korotky #:这是一个明显的编译器错误 - 它给出了错误:代码中出现了 "无效的测试仪设置文件扩展名,预计为 '*.set'"的错误: 谢谢,已修复! 要保持你的 MetaEditor 版本,请在文件名末尾添加 0:"myset.set\0 123 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
无论如何,订单、交易、头寸都与时间框架无关。你不是误解了什么,就是用词不当。
对不起,我想我用词不当,我说的"时间 范围 "是指 "日期范围"。如果我想选择在给定日期范围内成交的交易/订单,比如从 2025-10-01 00:00:00 到 2025-10-22 23:59:59 的交易。
如果要分析交易历史的子范围,在不影响过滤代码本身的情况下,在过滤之前只请求这部分历史记录会更有效:
如果出于某种原因,您想在HistorySelect 应用的全局范围内选择一个(更窄的)子范围,那么您仍然可以在过滤代码中这样做:
{ // 其中一些在这里 // HistorySelect(0, LONG_MAX); // HistorySelectByPosition(PositionID); ... DealTuple deals[]; if(SubrangeFrom != SubrangeTo && SubrangeFrom < SubrangeTo) { filter.let(DEAL_TIME, SubrangeFrom - 1, IS::GREATER).let(DEAL_TIME, SubrangeTo + 1, IS::LESS); } filter.let(DEAL_POSITION_ID, PositionID).select(deals, true); ... }黄线高亮部分使用额外的限定符 IS::GREATER 和 IS::LESS(默认情况下,在调用let() 时不会指定这两个限定符,而 IS::EQUAL 通常用于单值字段)为日期时间范围 [SubrangeFrom, SubrangeTo] 设置了两个条件。
我只知道一个按日期范围应用子过滤器的原因,那就是订单的设置时间 (ORDER_TIME_SETUP),因为HistorySelect 应用于订单的另一个日期时间属性,即订单执行时间 (ORDER_TIME_DONE)。此外,如果有很多有效订单,过滤有效订单的子范围(不在历史中)可能会很有趣。
您可以从MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5 示例脚本开始。如果要分析交易历史的一个子范围,在不影响过滤代码本身的情况下,在过滤前只请求分析这部分历史记录会更有效:
如果出于某种原因,您想在HistorySelect 应用的全局范围内选择一个(更窄的)子范围,那么您仍然可以在过滤代码中这样做:
黄线高亮部分使用额外的限定符 IS::GREATER 和 IS::LESS(默认情况下,在其他调用let() 时不指定这两个限定符,而 IS::EQUAL 通常用于单值字段)为日期时间范围 [SubrangeFrom, SubrangeTo] 设置了两个条件。
我只知道一个按日期范围应用子过滤器的原因,那就是订单的设置时间 (ORDER_TIME_SETUP),因为HistorySelect 应用于订单的另一个日期时间属性,即订单执行时间 (ORDER_TIME_DONE)。此外,如果有很多有效订单,过滤有效订单的子范围(不在历史中)可能会很有趣。
您可以从MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5 示例脚本开始。修正MQL5/Include/MQL5Book/TradeUtils.mqh.
版主对错误粘贴的代码进行了格式化。通常,此类代码会被删除。
@StanislavKorotky 请您帮忙看看这个错误,我相信它是在 MT5 更新后开始出现的,因为我知道代码在前几个月没有任何修改的情况下也能正常工作。
参数转换类型 'long[][2]' 到 'string[][] &' 是不允许的 SymbolFilter.mqh 199 20
我怀疑下面的代码有助于复制该问题:
你好@Paul Dick
请尝试使用https://www.mql5.com/zh/code/57233 对数组进行排序
现附上基于 R2 -RSquared.mqh 的自定义优化 准则计算文件的更新版本,其中对变量手数的计算进行了修正。
估算质量有了明显改善--从优化结果 表中可以看出,已经获得了恢复系数和夏普参数的组合。
使用示例
我最近在学习 Frame,并测试了您的代码 FrameTransfer.mq5。在当前的 MT5 编译器中,这一行出现了错误。请验证:#property tester_set "FrameTransfer.set" (invalid tester set file extension, '*.set' expected FrameTransfer.mq5)
必须这样修改才能成功编译:#property tester_set "\\Presets\FrameTransfer.set"
甚至 `#property tester_set "/Presets/FrameTransfer.set"` 也会失败。
也许你可以修改算法书中的描述:
若要成功编译,应作如下更改:#property tester_set "\\Presets\\FrameTransfer.set"
即使是 `#property tester_set "/Presets/FrameTransfer.set"` 也会失败。
也许你可以修改算法书中的描述:
这是一个明显的编译器错误--它给代码带来了错误:"无效的 tester set 文件扩展名,'*.set'预期":
其中文件具有所需的扩展名。文件位置路径与此无关。
这个错误由来已久,至少从 2024 年就存在了。我不知道为什么 MQ 不急于修复它。
至于图书编辑,在这种情况下并不需要,但无论如何,图书现在完全由 MQ 控制。
这是一个明显的编译器错误 - 它给出了错误:代码中出现了 "无效的测试仪设置文件扩展名,预计为 '*.set'"的错误:
要保持你的 MetaEditor 版本,请在文件名末尾添加 0:"myset.set\0