将 MQL4 转换为 C++?
Converting MQL4 to C++?
我想将一堆用 MQL4(.mq4 文件)编写的 stock/forex 指标转换为 C++。以前,我只使用 Python 编程,很少接触 MQL4 和 C++。此外,我完全不知道如何解决这样的问题,甚至是否可行。 (虽然,最坏的情况下,手动重新编码它们绝对是可行的。)
我以一个简单的指标简单移动平均线为例,开始对其进行修改,并 运行使用 C++ 编译器对其进行编译。知道这两种语言的语法非常相似,我认为这可能是一个相对容易的过程,甚至可以在某种程度上实现自动化。
这是从可用的 .mq4 文件中提取的简单移动平均线脚本 at this link:
MA_Period=5;
void sma()
{
double sum=0;
int i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
sum+=Close[pos];
//---- main calculation loop
while(pos>=0)
{
sum+=Close[pos];
ExtMapBuffer[pos]=sum/MA_Period;
sum-=Close[pos+MA_Period-1];
pos--;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
这是我的 C++ 实现,目前在短数组 arr[]
上测试它,代表 MQL4 中的 Close
数组。此外,我删除了 MQL4 的 Bars
和 ExtCountedBars
变量(因为我想 运行 静态历史数据上的指标),并用名为 [=19 的数组替换 ExtMapBuffer
=],与“价格”数组长度相等 arr[]
.
#include <iostream>
using namespace std;
int main()
{
int MA_Period=5;
int arr[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
double sum=0;
int i, pos=0;
int output[20];
cout << "Pos: " << pos << endl;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
sum+=arr[pos];
cout << "Sum of past " << MA_Period << " prices : " << sum << endl;
cout << "Pos = " << pos << endl;
//---- main calculation loop
while(pos>=0)
{
sum+=arr[pos];
output[pos]=sum/MA_Period;
sum-=arr[pos+MA_Period-1];
pos--;
}
for(int j=0;j<sizeof(output)/sizeof(output[0]);j++){
cout << "output[" << j << "] = " << output[j] << endl;
}
return 0;
}
output
数组值的控制台输出是:
output[0] = 3
output[1] = 4
output[2] = 65535
output[3] = 1
output[4] = 1706671568
output[5] = 32766
output[6] = 4197523
output[7] = 0
output[8] = 2
output[9] = 0
output[10] = 4197613
output[11] = 0
output[12] = 124
output[13] = 0
output[14] = 0
output[15] = 0
output[16] = 4197536
output[17] = 0
output[18] = 4196352
output[19] = 0
这显然是不正确的。在转换为 C++ 时,我尝试保留尽可能多的原始 MQL4 代码,但现在遇到了一个障碍,为什么输出与预期的大不相同:
output[0] = nan
output[1] = nan
output[2] = nan
output[3] = nan
output[4] = 3
output[5] = 4
output[6] = 5
output[7] = 6
output[8] = 7
output[9] = 8
output[10] = 9
output[11] = 10
output[12] = 11
output[13] = 12
output[14] = 13
output[15] = 14
output[16] = 15
output[17] = 16
output[18] = 17
output[19] = 18
在将我的 MQL4 代码转换为 C++ 的过程中,我遗漏了什么/误解了什么?
这段代码有几个问题。主要问题是您使用索引 i
和 pos
。特别是,经过初始累加后,pos
等于1
,所以主计算循环只会运行一次迭代就完成了。所以只有 output[1]
被写入,数组的其余部分未初始化,可能包含任何值。
另请注意,C 中的数组索引从零开始。您的初始累积循环从 1
开始,这不是您想要的。
我会避免为索引设置两个变量,而只使用一个。要初始化 sum
,请写入:
for (int i = 0; i < MA_Period; ++i) {
sum += arr[i];
output[i] = -1;
}
然后做余数写:
for (int i = MA_Period; i < sizeof(output) / sizeof(output[0]); ++i) {
sum += arr[i];
sum -= arr[i - MA_Period];
output[i] = sum / MA_Period;
}
这将为您提供预期的输出。请注意,前 5 个值无法获得 nan
,因为 int
永远不可能是 nan
。如果你使 output
成为一个 double
的数组,这是可能的,例如在初始循环中使用这一行:
output[i] = 0.0 / 0.0;
至于原始 MQL4 代码为何有效:它将 pos
初始化为 Bars - ExtCountedBars - 1
,而您在 C++ 版本中将其初始化为 0
。
我想将一堆用 MQL4(.mq4 文件)编写的 stock/forex 指标转换为 C++。以前,我只使用 Python 编程,很少接触 MQL4 和 C++。此外,我完全不知道如何解决这样的问题,甚至是否可行。 (虽然,最坏的情况下,手动重新编码它们绝对是可行的。)
我以一个简单的指标简单移动平均线为例,开始对其进行修改,并 运行使用 C++ 编译器对其进行编译。知道这两种语言的语法非常相似,我认为这可能是一个相对容易的过程,甚至可以在某种程度上实现自动化。
这是从可用的 .mq4 文件中提取的简单移动平均线脚本 at this link:
MA_Period=5;
void sma()
{
double sum=0;
int i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
sum+=Close[pos];
//---- main calculation loop
while(pos>=0)
{
sum+=Close[pos];
ExtMapBuffer[pos]=sum/MA_Period;
sum-=Close[pos+MA_Period-1];
pos--;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
这是我的 C++ 实现,目前在短数组 arr[]
上测试它,代表 MQL4 中的 Close
数组。此外,我删除了 MQL4 的 Bars
和 ExtCountedBars
变量(因为我想 运行 静态历史数据上的指标),并用名为 [=19 的数组替换 ExtMapBuffer
=],与“价格”数组长度相等 arr[]
.
#include <iostream>
using namespace std;
int main()
{
int MA_Period=5;
int arr[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
double sum=0;
int i, pos=0;
int output[20];
cout << "Pos: " << pos << endl;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
sum+=arr[pos];
cout << "Sum of past " << MA_Period << " prices : " << sum << endl;
cout << "Pos = " << pos << endl;
//---- main calculation loop
while(pos>=0)
{
sum+=arr[pos];
output[pos]=sum/MA_Period;
sum-=arr[pos+MA_Period-1];
pos--;
}
for(int j=0;j<sizeof(output)/sizeof(output[0]);j++){
cout << "output[" << j << "] = " << output[j] << endl;
}
return 0;
}
output
数组值的控制台输出是:
output[0] = 3
output[1] = 4
output[2] = 65535
output[3] = 1
output[4] = 1706671568
output[5] = 32766
output[6] = 4197523
output[7] = 0
output[8] = 2
output[9] = 0
output[10] = 4197613
output[11] = 0
output[12] = 124
output[13] = 0
output[14] = 0
output[15] = 0
output[16] = 4197536
output[17] = 0
output[18] = 4196352
output[19] = 0
这显然是不正确的。在转换为 C++ 时,我尝试保留尽可能多的原始 MQL4 代码,但现在遇到了一个障碍,为什么输出与预期的大不相同:
output[0] = nan
output[1] = nan
output[2] = nan
output[3] = nan
output[4] = 3
output[5] = 4
output[6] = 5
output[7] = 6
output[8] = 7
output[9] = 8
output[10] = 9
output[11] = 10
output[12] = 11
output[13] = 12
output[14] = 13
output[15] = 14
output[16] = 15
output[17] = 16
output[18] = 17
output[19] = 18
在将我的 MQL4 代码转换为 C++ 的过程中,我遗漏了什么/误解了什么?
这段代码有几个问题。主要问题是您使用索引 i
和 pos
。特别是,经过初始累加后,pos
等于1
,所以主计算循环只会运行一次迭代就完成了。所以只有 output[1]
被写入,数组的其余部分未初始化,可能包含任何值。
另请注意,C 中的数组索引从零开始。您的初始累积循环从 1
开始,这不是您想要的。
我会避免为索引设置两个变量,而只使用一个。要初始化 sum
,请写入:
for (int i = 0; i < MA_Period; ++i) {
sum += arr[i];
output[i] = -1;
}
然后做余数写:
for (int i = MA_Period; i < sizeof(output) / sizeof(output[0]); ++i) {
sum += arr[i];
sum -= arr[i - MA_Period];
output[i] = sum / MA_Period;
}
这将为您提供预期的输出。请注意,前 5 个值无法获得 nan
,因为 int
永远不可能是 nan
。如果你使 output
成为一个 double
的数组,这是可能的,例如在初始循环中使用这一行:
output[i] = 0.0 / 0.0;
至于原始 MQL4 代码为何有效:它将 pos
初始化为 Bars - ExtCountedBars - 1
,而您在 C++ 版本中将其初始化为 0
。