客户端
MQL5
网页端
网页端
MQL5
MQL5:分别为CopyTicks、CopyTicksRange和CopyRates方法添加COPY_TICKS_VERTICAL和COPY_RATES_VERTICAL标识。
默认情况下,报价和函数沿水平轴复制到矩阵,这意味着数据添加到右侧,在行尾。在练习的ONNX模型运行任务中,这样的矩阵需要被转置以提供输入数据:
const long ExtOutputShape[] = {1,1}; // 模型输出形状
const long ExtInputShape [] = {1,10,4}; // 模型输入形状
#resource "Python/model.onnx" as uchar ExtModel[]// 作为资源的模型
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
int OnStart(void)
{
matrix rates;
//--- 获取10个柱状图
if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,2,10))
return(-1);
//--- 输入一组OHLC向量
matrix x_norm=rates.Transpose();
vector m=x_norm.Mean(0);
vector s=x_norm.Std(0);
matrix mm(10,4);
matrix ms(10,4);
通过在调用该方法时指定附加标识COPY_RATES_VERTICAL(COPY_TICKS_VERTICAL用于报价),可以消除额外的数据转置操作:
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
int OnStart(void)
{
matrix rates;
//--- 获取10个柱状图
if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC|COPY_RATES_VERTICAL,2,10))
return(-1);
//--- 输入一组OHLC向量
MetaEditor
客户端
程序端
MQL5
编译该项目并在EURUSD H1上运行以查看结果。
除了模型和运行模型的MQL5代码外,该项目还包括PricePredictionTraining.py Python脚本。该脚本显示了您如何自己创建一个ONNX模型。要运行该脚本,请在计算机上安装Python,并从提示行安装所需的模块:
#import "mmlib.dll"
bool sgemm(uint flags,matrix<float> &C,const matrix<float> &A,const matrix<float> &B,ulong M,ulong N,ulong K,float alpha,float beta);
#import
C++extern "C" __declspec(dllexport) bool sgemm(UINT flags,float *C,const float *A,const float *B,UINT64 M,UINT64 N,UINT64 K,float alpha,float beta)
除了缓冲区之外,您还应该传递矩阵和向量大小以进行正确的处理。添加新CopySeries函数,用于将同步时间周期从MqlRates复制到单独的数组中。
CopySeries函数允许在一次调用中只获取必要的时间周期到不同的指定数组中,同时所有的时间周期数据将被同步。这意味着结果数组中特定索引N的所有值将属于指定交易品种/时间周期上的同一柱形图。因此,程序员无需另外通过柱形图开盘时间来同步接收的时间序列。
与将完整的时间周期集作为MqlRates数组返回的CopyRates不同,CopySeries函数允许将特定的所需时间周期获取到单独的数组中。这可以通过指定一个标识组合来选择时间序列的类型来实现。传递到函数的数组顺序必须与MqlRates结构中字段的顺序相匹配:
struct MqlRates
{
datetime time; // 期初
double open; // 开仓价
double high; // 该时间段的最高价
double low; // 该时间段的最低价
double close; // 平仓价
long tick_volume; // 报价量
int spread; // 点差
long real_volume; // 交易量
}
因此,如果您需要获取当前交易品种/时间帧的最近100柱形图的"time","close"和"real_volume"时间周期的值,您应该使用以下调用:
datetime time[];
double close[];
long volume[];
CopySeries(NULL,0,0,100,COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_VOLUME_REAL,time,close,volume);
数组"time,close,volume"顺序必须与MqlRates结构中字段的顺序相匹配。忽略rates_mask中值的顺序。掩码可以如下所示:
COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE
示例
//--- 输入参数
input datetime InpDateFrom=D'2022.01.01 00:00:00';
input datetime InpDateTo =D'2023.01.01 00:00:00';
input uint InpCount =20;
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart(void)
{
//--- 从Rates结构获取时间周期的数组
double open[];
double close[];
float closef[];
datetime time1[], time2[];
//---将平仓价请求到double数组
ResetLastError();
int res1=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
COPY_RATES_TIME|COPY_RATES_CLOSE, time1, close);
PrintFormat("1. CopySeries returns %d values. Error code=%d", res1, GetLastError());
ArrayPrint(close);
//--- 现在还请求开仓价;为平仓价使用float数组
ResetLastError();
int res2=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_OPEN, time2, open, closef);
PrintFormat("2. CopySeries returns %d values. Error code=%d", res2, GetLastError());
ArrayPrint(closef);
//--- 对比接收的数据
if((res1==res2) && (time1[0]==time2[0]))
{
Print(" | Time | Open | Close double | Close float |");
for(int i=0; i<10; i++)
{
PrintFormat("%d | %s | %.5f | %.5f | %.5f |",
i, TimeToString(time1[i]), open[i], close[i], closef[i]);
}
}
/* Result
1. CopySeries returns 0 values. Error code=0
[ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
[10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
2. CopySeries returns 0 values. Error code=0
[ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
[10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
| Time | Open | Close double | Close float |
0 | 2023.03.01 17:00 | 1.06660 | 1.06722 | 1.06722 |
1 | 2023.03.01 18:00 | 1.06722 | 1.06733 | 1.06733 |
2 | 2023.03.01 19:00 | 1.06734 | 1.06653 | 1.06653 |
3 | 2023.03.01 20:00 | 1.06654 | 1.06520 | 1.06520 |
4 | 2023.03.01 21:00 | 1.06520 | 1.06573 | 1.06573 |
5 | 2023.03.01 22:00 | 1.06572 | 1.06649 | 1.06649 |
6 | 2023.03.01 23:00 | 1.06649 | 1.06694 | 1.06694 |
7 | 2023.03.02 00:00 | 1.06683 | 1.06675 | 1.06675 |
8 | 2023.03.02 01:00 | 1.06675 | 1.06684 | 1.06684 |
9 | 2023.03.02 02:00 | 1.06687 | 1.06604 | 1.06604 |
*/
}
MetaEditor
Tester
MetaTrader 5网页端build 3620
网页端
客户端
MQL5
long preferred_workgroup_size_multiple=OpenCL.GetDeviceInfo(0x1067);
void OnStart() { string cpu,os; //--- cpu=TerminalInfoString(TERMINAL_CPU_NAME); os=TerminalInfoString(TERMINAL_OS_VERSION); PrintFormat("CPU: %s, OS: %s",cpu,os); }Result:
MetaEditor
程序端
MQL5
//--- 在获得最后一个错误代码时,将忽略第一个句柄参数
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
//--- 获得最后一个OpenCL错误的代码
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
string desc; // 要获得错误的文本描述
//--- 使用错误代码来获得错误的文本描述
if(!CLGetInfoString(code,CL_ERROR_DESCRIPTION,desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
//--- 要在没有接收代码的情况下获取最后一个OpenCL错误的描述,请传递CL_LAST_ERROR
if(!CLGetInfoString(CL_LAST_ERROR,CL_ERROR_DESCRIPTION, desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
内部枚举名称作为错误描述传递。其解释可显示在https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_SUCCESS。例如,CL_INVALID_KERNEL_ARGS值意味着“在某些内核参数未设置或无效时,在对内核进行排队时返回。” MetaTrader 5 WebTerminal
程序端
MQL5
class A { }; void OnStart(void) { const A *const arr[][2][3]={}; Print(typename(arr)); }Result:
"class A const * const [][2][3]"
程序端
MQL5
修正崩溃日志中的错误报告。
MetaTrader 5 WebTerminal(网页端)build 3500
网页平台的移动端版本
全新网页端为移动设备提供全功能的支持。该界面将自动适应屏幕尺寸,实现iOS与Android手机和平板电脑的高效操作:
此外,网页端还进行多项修复和改进。
全新MetaTrader 5网页端支持全部交易功能。使用户能够:
程序端
MQL5
bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
复制的数据类型使用ENUM_COPY_TICKS枚举在"flags"参数中指定。以下值可供使用:COPY_TICKS_INFO = 1, // 由卖价和/或买价更改得出的报价
COPY_TICKS_TRADE = 2, // 由最后价和交易量更改得出的报价
COPY_TICKS_ALL = 3, // 所有报价都发生变化
COPY_TICKS_TIME_MS = 1<<8, // 以毫秒为单位的时间
COPY_TICKS_BID = 1<<9, // 卖价
COPY_TICKS_ASK = 1<<10, // 买价
COPY_TICKS_LAST = 1<<11, // 最后价
COPY_TICKS_VOLUME = 1<<12, // 交易量
COPY_TICKS_FLAGS = 1<<13, // 报价标识
如果选择了多种数据类型(仅适用于矩阵),矩阵中的行序将对应于枚举中的值的顺序。bool matrix::Assign(const vector &vec);
结果将是一个单行矩阵。bool vector::Assign(const matrix &mat);
bool vector::Swap(vector &vec);
bool vector::Swap(matrix &vec);
bool vector::Swap(double &arr[]);
bool matrix::Swap(vector &vec);
bool matrix::Swap(matrix &vec);
bool matrix::Swap(double &arr[]);
每个数组、向量或矩阵都指向一个包含该对象元素的内存缓冲区。Swap方法实际上交换指向这些缓冲区的指针,而不将元素写入内存。因此,矩阵仍然是矩阵,向量仍然是向量。交换矩阵和矢量会产生一个带有矢量元素的单行矩阵和一个平面表示的带有矩阵元素的矢量(见Flat方法)。//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//---
matrix a= {{1, 2, 3}, {4, 5, 6}};
Print("a before Swap: \n", a);
matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}};
Print("b before Swap: \n", b);
//--- swap矩阵指针
a.Swap(b);
Print("a after Swap: \n", a);
Print("b after Swap: \n", b);
/*
a before Swap:
[[1,2,3]
[4,5,6]]
b before Swap:
[[5,10,15,20]
[25,30,35,40]
[45,50,55,60]]
a after Swap:
[[5,10,15,20]
[25,30,35,40]
[45,50,55,60]]
b after Swap:
[[1,2,3]
[4,5,6]]
*/
vector v=vector::Full(10, 7);
Print("v before Swap: \n", v);
Print("b before Swap: \n", b);
v.Swap(b);
Print("v after Swap: \n", v);
Print("b after Swap: \n", b);
/*
v before Swap:
[7,7,7,7,7,7,7,7,7,7]
b before Swap:
[[1,2,3]
[4,5,6]]
v after Swap:
[1,2,3,4,5,6]
b after Swap:
[[7,7,7,7,7,7,7,7,7,7]]
*/
}
Swap()方法还可以使用动态数组进行操作(固定大小的数组不能作为参数传递)。数组可以是任何维度,但具有约定的大小,这意味着矩阵或向量的总大小必须是数组零维度的倍数。数组零维度是第一个索引处包含的元素数。例如,对于动态三维数组"double array[][2][3]",零维是第二维和第三维大小的乘积:2x3=6。因此,这样的数组只能在Swap方法中用于总大小为6的倍数的矩阵和向量:6、12、18、24等。//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 用7.0值填写1x10矩阵
matrix m= matrix::Full(1, 10, 7.0);
Print("matrix before Swap:\n", m);
//--- 尝试交换矩阵和数组
double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
Print("array_small before Swap:");
ArrayPrint(array_small);
if(m.Swap(array_small))
{
Print("array_small after Swap:");
ArrayPrint(array_small);
Print("matrix after Swap: \n", m);
}
else // 矩阵大小不是第一个数组维度的倍数
{
Print("m.Swap(array_small) failed. Error ", GetLastError());
}
/*
matrix before Swap:
[[7,7,7,7,7,7,7,7,7,7]]
array_small before Swap:
[,0] [,1] [,2] [,3] [,4]
[0,] 1.00000 2.00000 3.00000 4.00000 5.00000
[1,] 6.00000 7.00000 8.00000 9.00000 10.00000
m.Swap(array_small) failed. Error 4006
*/
//--- 使用更大的矩阵并重试交换操作
double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{2, 4, 6, 8, 10, 12, 14, 16, 18, 20},
{3, 6, 9, 12, 15, 18, 21, 24, 27, 30}
};
Print("array_static before Swap:");
ArrayPrint(array_static);
if(m.Swap(array_static))
{
Print("array_static after Swap:");
ArrayPrint(array_static);
Print("matrix after Swap: \n", m);
}
else // 静态数组不能用于与矩阵交换
{
Print("m.Swap(array_static) failed. Error ", GetLastError());
}
/*
array_static before Swap:
[,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[0,] 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 9.00000 10.00000
[1,] 2.00000 4.00000 6.00000 8.00000 10.00000 12.00000 14.00000 16.00000 18.00000 20.00000
[2,] 3.00000 6.00000 9.00000 12.00000 15.00000 18.00000 21.00000 24.00000 27.00000 30.00000
m.Swap(array_static) failed. Error 4006
*/
//--- 交换数组和矩阵的另一种尝试
double array_dynamic[][10]; // 动态数组
ArrayResize(array_dynamic, 3); // 设置第一维度大小
ArrayCopy(array_dynamic, array_static);
//--- 现在为swap使用动态数组
if(m.Swap(array_dynamic))
{
Print("array_dynamic after Swap:");
ArrayPrint(array_dynamic);
Print("matrix after Swap: \n", m);
}
else // 没有错误
{
Print("m.Swap(array_dynamic) failed. Error ", GetLastError());
}
/*
array_dynamic after Swap:
[,0] [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[0,] 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000
matrix after Swap:
[[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30]]
*/
}
vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const;
matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
MetaEditor
MetaTester
修正崩溃日志中的错误报告。
程序端
MQL5
bool vector<TDst>::Assign(const vector<TSrc> &assign); bool matrix<TDst>::Assign(const matrix<TSrc> &assign);示例:
//--- copying matrices matrix b={}; matrix a=b; a.Assign(b); //--- copying an array to a matrix double arr[5][5]={{1,2},{3,4},{5,6}}; Print("array arr"); ArrayPrint(arr); b.Assign(arr); Print("matrix b \n",b); /* array arr [,0] [,1] [,2] [,3] [,4] [0,] 1.00000 2.00000 0.00000 0.00000 0.00000 [1,] 3.00000 4.00000 0.00000 0.00000 0.00000 [2,] 5.00000 6.00000 0.00000 0.00000 0.00000 [3,] 0.00000 0.00000 0.00000 0.00000 0.00000 [4,] 0.00000 0.00000 0.00000 0.00000 0.00000 matrix b [[1,2,0,0,0] [3,4,0,0,0] [5,6,0,0,0] [0,0,0,0,0] [0,0,0,0,0]] */
bool matrix::CopyRates(string symbol,ENUM_TIMEFRAMES period,ulong rates_mask,ulong from,ulong count); bool vector::CopyRates(string symbol,ENUM_TIMEFRAMES period,ulong rates_mask,ulong from,ulong count);复制的数据类型使用ENUM_COPY_RATES枚举在rates_mask参数中指定。有以下值可供使用:
修正改变将常量参数作为对象指针引用传递给函数时的错误。
const指定符将一个变量声明为常量,以防止它在程序执行中被更改。它只允许在声明时进行一次性的变量初始化。OnCalculate函数中的常量变量示例:
int OnCalculate (const int rates_total, // price[] array size const int prev_calculated, // bars processed on previous call const int begin, // meaningful data starts at const double& price[] // array for calculation );
下面的示例包含一个编译器错误,它允许隐式指针强制转换引用参数:
class A {}; const A *a = new A; void foo( const A*& b ) { b = a; } void OnStart() { A *b; foo(b); // not allowed Print( a,":",b ); }编译器会检测到这种非法操作,并返回相关错误。
MetaEditor
全新MetaTrader 5网页端
我们发布了经过改进的MetaTrader 5网页端,它提供了更新的界面和重新设计的内核。新界面类似于iPad程序端:
它还包含许多新功能:
程序端
MQL5
//--- matrix a= {{1, 4}, {9, 16}}; Print("matrix a=\n",a); a=MathSqrt(a); Print("MatrSqrt(a)=\n",a); /* matrix a= [[1,4] [9,16]] MatrSqrt(a)= [[1,2] [3,4]] */对于MathMod和MathPow,第二个元素既可以是标量,也可以是相应大小的矩阵/向量。
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Use the initializing function to populate the vector vector r(10, ArrayRandom); // Array of random numbers from 0 to 1 //--- Calculate the average value double avr=r.Mean(); // Array mean value vector d=r-avr; // Calculate an array of deviations from the mean Print("avr(r)=", avr); Print("r=", r); Print("d=", d); vector s2=MathPow(d, 2); // Array of squared deviations double sum=s2.Sum(); // Sum of squared deviations //--- Calculate standard deviation in two ways double std=MathSqrt(sum/r.Size()); Print(" std(r)=", std); Print("r.Std()=", r.Std()); } /* avr(r)=0.5300302133243813 r=[0.8346201971495713,0.8031556138798182,0.6696676534318063,0.05386516922513505,0.5491195410016175,0.8224433118686484,... d=[0.30458998382519,0.2731254005554369,0.1396374401074251,-0.4761650440992462,0.01908932767723626,0.2924130985442671, ... std(r)=0.2838269732183663 r.Std()=0.2838269732183663 */ //+------------------------------------------------------------------+ //| Fills the vector with random values | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
改进浮点类型运算的数学函数。新实现的将数学函数应用于‘float'矩阵和向量的可能性可以改进应用于‘float'标量的数学函数。以前,这些函数参数被无条件地转换为‘double'类型,然后调用相应实施的数学函数,并将结果转换回‘float'类型。现在,实施这些操作,无需其他类型转换。
以下示例显示了数学正弦计算的差值:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Array of random numbers from 0 to 1 vector d(10, ArrayRandom); for(ulong i=0; i<d.Size(); i++) { double delta=MathSin(d[i])-MathSin((float)d[i]); Print(i,". delta=",delta); } } /* 0. delta=5.198186103783087e-09 1. delta=8.927621308885136e-09 2. delta=2.131878673594656e-09 3. delta=1.0228555918923021e-09 4. delta=2.0585739779477308e-09 5. delta=-4.199390279957527e-09 6. delta=-1.3221741035351897e-08 7. delta=-1.742922250969059e-09 8. delta=-8.770715820283215e-10 9. delta=-1.2543186267421902e-08 */ //+------------------------------------------------------------------+ //| Fills the vector with random values | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
AF_ELU | Exponential Linear Unit函数 |
AF_EXP | Exponential函数 |
AF_GELU | Gaussian Error Linear Unit函数 |
AF_HARD_SIGMOID | Hard Sigmoid函数 |
AF_LINEAR | Linear函数 |
AF_LRELU | Leaky REctified Linear Unit函数 |
AF_RELU | REctified Linear Unit函数 |
AF_SELU | Scaled Exponential Linear Unit函数 |
AF_SIGMOID | Sigmoid函数 |
AF_SOFTMAX | Softmax函数 |
AF_SOFTPLUS | SoftPlus函数 |
AF_SOFTSIGN | Softsign函数 |
AF_SWISH | Swish函数 |
AF_TANH | Hyperbolic Tangent函数 |
AF_TRELU | Thresholded REctified Linear Unit函数 |
LOSS_MSE | 均方差损失函数 |
LOSS_MAE | 平均绝对误差损失函数 |
LOSS_CCE | Categorical Crossentropy函数 |
LOSS_BCE | Binary Crossentropy函数 |
LOSS_MAPE | 平均 绝对百分比误差损失函数 |
LOSS_MSLE | 均方对数误差损失函数 |
LOSS_KLD | Kullback-Leibler Divergence函数 |
LOSS_COSINE | Cosine similarity/proximity函数 |
LOSS_POISSON | Poisson函数 |
LOSS_HINGE | Hinge函数 |
LOSS_SQ_HINGE | Squared Hinge函数 |
LOSS_CAT_HINGE | Categorical Hinge函数 |
LOSS_LOG_COSH | 双曲余弦对数 函数 |
LOSS_HUBER | Huber函数 |
int cl_ctx; //--- Initializing the OpenCL context if((cl_ctx=CLContextCreate(CL_USE_GPU_DOUBLE_ONLY))==INVALID_HANDLE) { Print("OpenCL not found"); return; }
CalendarValueLast(change, result, "", "EUR")
MetaEditor
'levels.bmp' as 'uint levels[18990]'
程序端
MQL5
MetaTester
MetaEditor
修复崩溃日志中报告的错误。
程序端
MQL5
double vector.RegressionError(const enum lr_error); double matrix.RegressionError(const enum lr_error); vector matrix.RegressionError(const enum lr_error,const int axis);以下变量可用作度量指标:
enum REGRESSION_ERROR { REGRESSION_MAE, // 平均绝对误差 REGRESSION_MSE, // 均方差 REGRESSION_RMSE, // 均方根误差 REGRESSION_R2, // R平方 REGRESSION_MAPE, // 平均绝对百分比误差 REGRESSION_MSPE, // 均方百分比误差 REGRESSION_RMSLE // 均方根对数误差 };
MetaEditor
Tester
程序端
程序端
MQL5
void OnStart() { int arr[4][5]= { {22, 34, 11, 20, 1}, {10, 36, 2, 12, 5}, {33, 37, 25, 13, 4}, {14, 9, 26, 21, 59} }; ulong indexes[4][5]; //--- 排序数组 arr.ArgSort(indexes,-1,0); Print("indexes"); ArrayPrint(indexes); } // 结果日志: // 索引 // [,0][,1][,2][,3][,4] // [0,] 4 2 3 0 1 // [1,] 2 4 0 3 1 // [2,] 4 3 2 0 1 // [3,] 1 0 3 2 4
void OnStart() { string test="some string"; PrintFormat("String length is %d",test.Length()); } // 结果日志: // 字符串长度是11
MQL5
double matrix::Flat(ulong index) const; // getter void matrix::Flat(ulong index,double value); // setter
计算矩阵元素地址的伪代码:
ulong row=index / mat.Cols(); ulong col=index % mat.Cols(); mat[row,col]
例如,对于'matrix mat(3,3)',访问元素可以按如下写出:
Tester
程序端
程序端
MQL5
VPS
MetaEditor
Tester