文章 "整合基于MQL的EA交易和数据库 (SQL Server, .NET 和 C#)"

 

新文章 整合基于MQL的EA交易和数据库 (SQL Server, .NET 和 C#)已发布:

本文描述了如何把操作 Microsoft SQL Server 数据库的功能加到基于 MQL 语言的 EA 交易中,它使用了从一个DLL(动态链接库)中引入函数的方法。这个 DLL 是使用 Microsoft .NET 平台和 C# 语言创建的。本文中使用的方法只要做少许调整,就可以用于使用 MQL4 开发的 EA 交易中。

在论坛上经常会有关于在使用 MQL5 编写的 EA 交易中整合数据库有关的问题。对这个主题有兴趣并不令人惊讶,数据库是保存数据的一种非常好的方法,与终端记录不同,数据不会从数据库中消失,它们很容易排序和过滤,只选择所需要的部分。数据库可以用于向 EA 传递需要的信息 - 例如,某些命令,最重要的是 — 取得的数据可以从不同角度进行分析和进行统计学处理。例如,写一行查询代码就可以得到每个货币对在指定时间段的平均和总利润。现在让我们想象一下,在交易终端中人工计算这个需要花费多长时间,

不幸的是,MetaTrader 没有提供内建的与数据库服务器交互的工具,这个问题只能通过从 DLL 文件中引入函数来解决。任务并不简单,但是可行。

启动 EA,把连接字符串的值设为您自己的数据库服务器访问参数,如果一切操作正确,EA 将会在记录中输出下面的内容:

2018.07.10 20:36:21.428    MqlSqlDemo (EURUSD,H1)    已经连接到数据库.
2018.07.10 20:36:22.187    MqlSqlDemo (EURUSD,H1)    在数据库中创建了表.
2018.07.10 20:36:22.427    MqlSqlDemo (EURUSD,H1)    数据写入表.
2018.07.10 20:36:22.569    MqlSqlDemo (EURUSD,H1)    从数据库中读取数字: 1
2018.07.10 20:36:22.586    MqlSqlDemo (EURUSD,H1)    从数据库中读取字符串: Test

连接到数据库,执行 SQL 命令,写入和读取数据 - 一切都成功执行了。

作者:Сергей Ткаченко

 

感谢您的文章,最近我们在论坛上讨论了如何将 C# DLL 直接连接到 MQL5。在此之前,我使用的是 C++ DLL。谢尔盖,Entity Framework 可以与这项技术一起使用吗?我对 CodeFirst 特别感兴趣。

 

遗憾的是,我对 Entity Framework 一无所知,因为我从未使用过它。对于相对较新的 C# 和 .NET 技术,我也没什么经验。

如果让我来做,我会试试。据推测,它应该能行。特别是如果你不在导出静态函数中使用高级功能,而是将它们封装在一些辅助类的私有函数中并在那里应用它们。在我的一个项目 中,我使用了来自 System.Collections.Generic.Net 的类。

 
Сергей Ткаченко:

遗憾的是,我对 Entity Framework 一窍不通,因为我从未使用过它。而且我对相对较新的 C# 和 .NET 技术总体上也没什么经验。

如果让我来做,我会试试。据推测,它应该可以工作。特别是如果你不在导出静态函数中使用高级功能,而是将它们封装在一些辅助类的私有函数中并在那里应用它们。我在一个项目中使用了 System.Collections.Generic 的类。

我明白了,我有经验,有机会我会试试的。总的来说,你有没有注意到将 .NET DLL 文件中的函数导出到非托管代码中的缺点?我的意思是,Renat F. 对这类事情说了很多。他给出的最一般的论据都是些吓人的故事。

你注意到它的缺点了吗?例如,降低性能、增加内存消耗等。

 

我们只能谈论与其他东西相比的缺点。

如果我们将使用从 DLL 导出函数的 EA 与不使用 DLL 导出函数而使用纯 MQL 的 EA 进行比较,那么这完全取决于特定 EA 的实现及其执行的任务。如果有两个 EA 做的事情完全相同,那就很难说了。我认为使用 DLL 的 EA 会更快,因为编译器在构建 DLL 时会对代码 进行更好的优化。但这只是假设,因为我没有直接比较过。我通常只在 DLL 中完成在 MQL 中较难或不可能完成的工作(例如,文章中描述的数据库工作)。因此,我的 Expert Advisor 在使用 DLL 和不使用 DLL 的情况下执行不同的任务。

使用 DLL 的 Expert Advisor 有一个缺点 - 可靠性较低。它们有时会出现错误 "Access violation at 0x08364576"(内存地址位数不同),但这种情况很少。而基于纯 MQL 的机器人则不会出现这种错误。当然,一切都取决于特定的 DLL - 它是如何实现的,有多复杂,是否检查了所有可能出现内存错误的危险位置。但是,我的智能交易系统(Expert Advisor)会出现这样的情况:在两三个月内一切运行正常,但当重新启动时,在一台 MT 上运行的五个智能交易系统中的一个会在日志中出现这样的错误。而纯 MQL 不会出现这种情况。

如果我们将从 C# DLL 导出函数与从普通 DLL(例如,C++)导出函数进行比较,那么两种方法各有利弊。我用 C++ 和 Qt 制作了另一个 DLL。它也在使用数据库,但使用的是 SQLite,而不是 SQL Server。它也出现了内存访问错误,而且比 .NET DLL 更频繁。不过,如果对项目进行了 "清理",如果在必要的地方检查了指向 null 的指针,释放了内存等等,那么也许相反的情况会更可靠。但在 C# 中,一切都会被自动检查和释放,因此会更容易一些。我没有注意到性能上有什么不同。不过,我的 C++/Qt 项目使用得并不多。

 
Сергей Ткаченко:

这里的缺点只能与其他方面相比。

如果我们将使用从 DLL 导出函数的 EA 与不使用 DLL 导出函数而使用纯 MQL 的 EA 进行比较,那么这完全取决于特定 EA 的实现及其执行的任务。如果有两个 EA 做的事情完全相同,那就很难说了。我认为使用 DLL 的 EA 会更快,因为编译器在构建 DLL 时会对代码 进行更好的优化。但这只是假设,因为我没有直接比较过。我通常只在 DLL 中完成在 MQL 中较难或不可能完成的工作(例如,文章中描述的数据库工作)。因此,有 DLL 访问权限和没有 DLL 访问权限的智能交易系统执行的任务是不同的。

使用 DLL 的 Expert Advisor 有一个缺点 - 可靠性较低。它们有时会出现错误 "Access violation at 0x08364576"(内存地址位数不同),但这种情况很少。而基于纯 MQL 的机器人则不会出现这种错误。当然,一切都取决于特定的 DLL - 它是如何实现的,有多复杂,是否检查了所有可能出现内存错误的危险位置。但是,我的智能交易系统(Expert Advisor)会出现这样的情况:在两三个月内一切正常,但当重新启动在一台 MT 上运行的五个智能交易系统中的一个时,日志中就会出现这样的错误。而纯 MQL 不会出现这种情况。

如果我们将从 C# DLL 导出函数与从普通 DLL(例如,C++)导出函数进行比较,那么两种方法各有利弊。我用 C++ 和 Qt 制作了另一个 DLL。它也在使用数据库,但使用的是 SQLite,而不是 SQL Server。它也出现了内存访问错误,而且比 .NET DLL 更频繁。不过,如果对项目进行了 "清理",如果在必要的地方检查了指向 null 的指针,释放了内存等等,那么也许相反的情况会更可靠。但在 C# 中,一切都会被自动检查和释放,因此会更容易一些。我没有注意到性能上有什么不同。不过,我的 C++/Qt 项目并没有被充分利用。

还有一个问题,也许你已经做过了。是否可以通过 C# DLL 启动交互式控制面板,还是必须将控制面板作为一个单独的程序,并以某种方式与 DLL 通信,例如通过内存映射或 WCF?

我现在说的是一台本地计算机。

 

很遗憾,我没有接触过互动面板。我只能猜测。我不太明白 "交互式面板 "是什么意思。

是否需要打开某个 MetaTrader 窗口?我不知道该怎么做,也不知道能不能做。

我是否应该打开某个窗口,然后接收用户的输入?我也没做过这个,但我想应该不难。创建一个定义普通 Windows 窗体窗口的类。在该类中,创建一个可导出 的静态函数,用于创建窗口,以对话模式向用户显示窗口,然后释放窗口。这样就可以了。

 
了不起的文章!正是我想要的!谢谢 Sergiey!
 
mark.
 
是的,做得非常好,非常感谢 Sergy。
 

很喜欢这篇文章--非常感谢你的深入讨论。


希望有人能帮我解决建设过程中遇到的问题。

C:\Users\user\source\repos\mql\MqlSqlDemo\packages\UnmanagedExports.1.2.7\tools\RGiesecke.DllExport.targets(58,3): error : Microsoft.Build.Utilities.ToolLocationHelper could not find ildasm.exe


从本质上讲,UnmanagedExports 工具无法找到执行其工作所需的反汇编器可执行文件。


我知道 ildasm.exe 确实存在,也知道它的不同位置......但不知道如何让 DllExport 识别正确的路径。