网页端
客户端
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
>
更新文档。
struct POINT { int x,y; }; int GetYFunc(y) { return(y * y); } void SomeFunction(int x1,int x2,int y) { POINT pt={ x1+x2, GetYFunc(y) }; ProcessPoint(pt); };
struct complex { double real; // 实数部分 double imag; // 虚数部分 };“复数”类型可以作为MQL5函数的参数按值传递(与普通结构不同,普通结构只通过引用传递)。对于从DLL导入的函数,“复数”类型只能通过引用来传递。
complex square(complex c) { return(c*c); } void OnStart() { Print(square(1+2i)); // 常量作为参数传递 } // "(-3,4)"将被输出,这是复数的字符串表示目前,复数只有简单的运算可用:=、+、-、*、/、+=、-=、*=、/=、==、!=。