Terminal
MQL5
Terminal Web
A atualização estará disponível através do sistema Live Update.
MetaTrader 5 Android
Atualize seus aplicativos móveis para o build 4360 através do Google Play, Huawei AppGallery ou baixe o arquivo APK.
Terminal
MetaTester
Terminal Web
MetaEditor
Terminal
MQL5
MetaTrader 5 Web Terminal
vector<double/complex> operator[](const int i) const; vector<double/complex> operator[](const ulong i) const;Agora, em vez deles, é usado um método com um valor de retorno constante:
const vector<double/complex> operator[](const ulong i) const;A correção permitirá capturar o uso incorreto do resultado no na nova versão do Alglib, o código mat[row][col]=x funciona de forma diferente do antigo. Antes, era uma escrita na matriz, e agora - escrita em um objeto vector<double/complex> temporário, que é destruído imediatamente após a escrita.
bool ArrayToFP16(ushort &dst_array[],const float &src_array[],ENUM_FLOAT16_FORMAT fmt); bool ArrayToFP16(ushort &dst_array[],const double &src_array[],ENUM_FLOAT16_FORMAT fmt); bool ArrayToFP8(uchar &dst_array[],const float &src_array[],ENUM_FLOAT8_FORMAT fmt); bool ArrayToFP8(uchar &dst_array[],const double &src_array[],ENUM_FLOAT8_FORMAT fmt); bool ArrayFromFP16(float &dst_array[],const ushort &src_array[],ENUM_FLOAT16_FORMAT fmt); bool ArrayFromFP16(double &dst_array[],const ushort &src_array[],ENUM_FLOAT16_FORMAT fmt); bool ArrayFromFP8(float &dst_array[],const uchar &src_array[],ENUM_FLOAT8_FORMAT fmt); bool ArrayFromFP8(double &dst_array[],const uchar &src_array[],ENUM_FLOAT8_FORMAT fmt);Como os formatos de números reais para 16 e 8 bits podem variar, no parâmetro fmt nas funções de conversão é necessário especificar qual formato de número precisa ser processado. Para versões de 16 bits, é utilizada a nova enumeração NUM_FLOAT16_FORMAT, que atualmente possui os seguintes valores:
Correções de acordo com os logs de erro.
Terminal
MQL5
MetaEditor
Tester
Terminal Web
Terminal
MQL5
Terminal da Web MetaTrader 5
Terminal
MetaTrader 5 Web Terminal
Terminal
MQL5
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { complex a=1+1i; complex b=a.Conjugate(); Print(a, " ", b); /* (1,1) (1,-1) */ vectorc va= {0.1+0.1i, 0.2+0.2i, 0.3+0.3i}; vectorc vb=va.Conjugate(); Print(va, " ", vb); /* [(0.1,0.1),(0.2,0.2),(0.3,0.3)] [(0.1,-0.1),(0.2,-0.2),(0.3,-0.3)] */ matrixc ma(2, 3); ma.Row(va, 0); ma.Row(vb, 1); matrixc mb=ma.Conjugate(); Print(ma); Print(mb); /* [[(0.1,0.1),(0.2,0.2),(0.3,0.3)] [(0.1,-0.1),(0.2,-0.2),(0.3,-0.3)]] [[(0.1,-0.1),(0.2,-0.2),(0.3,-0.3)] [(0.1,0.1),(0.2,0.2),(0.3,0.3)]] */ ma=mb.Transpose().Conjugate(); Print(ma); /* [[(0.1,0.1),(0.1,-0.1)] [(0.2,0.2),(0.2,-0.2)] [(0.3,0.3),(0.3,-0.3)]] */ }
from sys import argv data_path=argv[0] last_index=data_path.rfind("\\")+1 data_path=data_path[0:last_index] from sklearn.datasets import load_iris iris_dataset = load_iris() from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0) from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=1) knn.fit(X_train, y_train) # Convert into ONNX format from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType initial_type = [('float_input', FloatTensorType([None, 4]))] onx = convert_sklearn(knn, initial_types=initial_type) path = data_path+"iris.onnx" with open(path, "wb") as f: f.write(onx.SerializeToString())Abra o arquivo onnx criado no MetaEditor:
struct MyMap { long key[]; float value[]; };Aqui usamos arrays dinâmicos com tipos apropriados. Nesse caso, é possível usar arrays fixos, já que para esse modelo o Map sempre contém 3 pares de chave+valor.
//--- declaramos um array para receber dados da camada de saída output_probability MyMap output_probability[]; ... //--- execução do modelo OnnxRun(model,ONNX_DEBUG_LOGS,float_input,output_label,output_probability);
MetaEditor
MetaTrader 5 Web Terminal build 3980
Terminal
O relatório está dividido em quatro guias, cada uma contendo informações agregadas em seu próprio contexto:
Novos relatórios permitem avaliar visualmente vários aspectos dos resultados de negociação, simplesmente clicando nas guias. Os histogramas, gráficos e tabelas são interativos e apresentam informações adicionais ao passar o cursor do mouse sobre eles. Nossos designers trabalharam arduamente para garantir que as informações dos relatórios fossem lidas da maneira mais simples e clara possível. Experimente você mesmo e avalie o resultado!
Terminal MetaTrader 5 x64 build 3914 started for MetaQuotes Software Corp.
Terminal Windows 10 build 19045, 20 x Intel Xeon E5-2630 v4 @ 2.20GHz, AVX, 41 / 63 Gb memory, 58 / 280 Gb disk, UAC, GMT+2
VPS Hosting
MQL5
#define MACRO1 /* #define MACRO2 */ void OnStart() { #ifdef MACRO2 Print( 2 ); #else Print( 1 ); #endif }
void OnStart() { Print("CPU name: ",TerminalInfoString(TERMINAL_CPU_NAME)); Print("CPU cores: ",TerminalInfoInteger(TERMINAL_CPU_CORES)); Print("CPU architecture: ",TerminalInfoString(TERMINAL_CPU_ARCHITECTURE)); Print(""); Print("EX5 architecture: ",__CPU_ARCHITECTURE__); } CPU name: 12th Gen Intel Core i9-12900K CPU cores: 24 CPU architecture: AVX2 + FMA3 EX5 architecture: AVX
extern int X=0; void OnStart() { }
extern int X; void OnStart() { }
extern int X; int Y=X; void OnStart(void) { Print("Y=",Y," X=",X); } int X=_Digits;
MetaEditor
Tester
Traduções atualizadas da interface do usuário.
Correções de registros de falhas.
MetaTrader 5 Web Terminal build 3950
Terminal
MQL5
double vector::RegressionMetric( const vector& vector_true, // valores reais const ENUM_REGRESSION_METRIC metric // métrica ); double matrix::RegressionMetric( const matrix& matrix_true, // valores reais const ENUM_REGRESSION_METRIC metric // métrica ); vector matrix::RegressionMetric( const matrix& matrix_true, // valores reais const ENUM_REGRESSION_METRIC metric, // métrica const int axis // eixo );
vector vector::LinearRegression(); matriz::RegressãoLinear( ENUM_MATRIX_AXIS axis=AXIS_NONE // eixo ao longo do qual é calculada a regressão );Exemplo:
vector vector_a; //--- preenchemos o vetor com preços vector_a.CopyRates(_Symbol,_Period,COPY_RATES_CLOSE,1,100); //--- obtemos uma regressão linear vector vector_r=vector_a.LinearRegression();Visualização do resultado em forma de gráfico:
ulong vector::HasNan(); ulong matrix::HasNan();Os métodos Compare e CompareByDigits, ao comparar os respectivos pares de elementos que têm valores NaN, considera esses elementos iguais, enquanto em uma comparação normal de ponto flutuante NaN != NaN.
A estrutura OnnxTypeInfo, usada para trabalhar com modelos ONNX, foi modificada:
struct OnnxTypeInfo { ENUM_ONNX_TYPE type; // tipo de parâmetro OnnxTensorTypeInfo tensor; // descrição do tensor OnnxMapTypeInfo map; // descrição do mapa OnnxSequenceTypeInfo sequence; // descrição da sequência };
Agora, o tipo de dados é especificado usando novas subestruturas:
struct OnnxTensorTypeInfo { ENUM_ONNX_DATATYPE data_type; // tipo de dados no tensor long dimensions[]; // número de elementos }; struct OnnxMapTypeInfo { ENUM_ONNX_DATA_TYPE key_type; // tipo de chave OnnxTypeInfo type_info; // tipo de valor }; struct OnnxSequenceTypeInfo { OnnxTypeInfo type_info; // tipo de dados na sequência };Dependendo de OnnxTypeInfo::type (ONNX_TYPE_TENSOR, ONNX_TYPE_MAP ou ONNX_TYPE_SEQUENCE), a subestrutura correspondente é preenchida.
bool vector<T>::CopyIndicatorBuffer(long indicator_handle,ulong buffer_index,ulong start_pos,ulong count); bool vector<T>::CopyIndicatorBuffer(long indicator_handle,ulong buffer_index,datetime start_time,ulong count); bool vector<T>::CopyIndicatorBuffer(long indicator_handle,ulong buffer_index,datetime start_time,datetime stop_time);
MetaEditor
Tester
Correções de registro de falhas.
Web Terminal
MQL5.community
Terminal
MQL5
Web Terminal
WebTerminal
MQL5
MQL5: adicionados os sinalizadores COPY_TICKS_VERTICAL e COPY_RATES_VERTICAL aos métodos CopyTicks, CopyTicksRange e CopyRates, respectivamente.
Por
padrão, os ticks e as séries são copiados para a matriz ao longo do
eixo horizontal, ou seja, os dados são adicionados à esquerda no final
da linha. Nas tarefas de execução de um modelo ONNX treinado, tal matriz deve ser transposta para fornecer dados de entrada:
const long ExtOutputShape[] = {1,1}; // model output shape const long ExtInputShape [] = {1,10,4}; // model input form #resource "Python/model.onnx" as uchar ExtModel[] // model as resource //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { matrix rates; //--- get 10 bars if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,2,10)) return(-1); //--- input a set of OHLC vectors 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);
Agora, ao chamar o método, basta especificar um sinalizador adicional COPY_RATES_VERTICAL (COPY_TICKS_VERTICAL para ticks) para evitar uma operação de transformação de dados desnecessária:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { matrix rates; //--- get 10 bars if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC|COPY_RATES_VERTICAL,2,10)) return(-1); //--- input a set of OHLC vectors
MetaEditor
Terminal
Terminal
MQL5
Compile o projeto e execute-o com EURUSD H1 para ver o resultado.
Além
do modelo finalizado e do código MQL5 para executá-lo, o projeto também
inclui o script de Python PricePredictionTraining.py. Ele mostra como
criar um modelo ONNX sozinho. Para que o script funcione, instale o
Python em seu computador, bem como os módulos necessários a partir da
linha de comando:
#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)
Para um processamento adequado de matrizes e vetores, além de seus buffers, devem ser passados seus tamanhos.Adicionada a nova função CopySeries para copiar séries temporais sincronizadas de MqlRates para arrays separados.
A função CopySeries permite obter apenas as séries temporais necessárias, de cada vez, em diferentes matrizes especificadas, garantindo que todas elas estejam sincronizadas entre si. Isso significa que todos os valores nas matrizes resultantes, em um índice específico N, pertencem à mesma barra no par símbolo/período de tempo especificado. Dessa forma, não é necessário garantir que todas as séries temporais recebidas estejam sincronizadas com o tempo de abertura da barra.
Ao contrário da função CopyRates, que retorna um conjunto completo de séries temporais como uma matriz MQLRates, a função CopySeries permite que o programador obtenha somente as séries temporais necessárias, com base em uma combinação de sinalizadores que indicam o tipo de série temporal solicitado. Neste caso, a ordem dos arrays passados para a função deve corresponder à ordem dos campos na estrutura MqlRates:
struct MqlRates
{
datetime time; // período de início
double open; // preço de abertura
double high; // preço mais alto no período
double low; // preço mais baixo no período
double close; // preço de fechamento
long tick_volume; // volume de ticks
int spread; // spread
long real_volume; // volume de negociação
}
Assim, caso seja necessário obter os valores das séries temporais time, close e real_volume para as últimas 100 barras do símbolo/timeframe atual, a chamada deve ser a seguinte:
datetime time[];
double close[];
long volume[];
CopySeries(NULL,0,0,100,COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_VOLUME_REAL,time,close,volume);
Ao mesmo tempo, a ordem dos arrays "time, close, volume" é importante — deve corresponder à ordem dos campos Estrutura MqlRates. Mas a ordem dos valores na máscara rates_mask não importa, a máscara poderia ser assim:
COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE
Exemplo
//--- input parameters
input datetime InpDateFrom=D'2022.01.01 00:00:00';
input datetime InpDateTo =D'2023.01.01 00:00:00';
input uint InpCount =20;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart(void)
{
//--- obtemos séries temporais a partir da estrutura de preços Rates
double open[];
double close[];
float closef[];
datetime time1[], time2[];
//--- solicitamos os preços de fechamento em uma matriz do tipo 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);
//--- agora pedimos mais preços de abertura e fechamento em uma série de preços do tipo 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);
//--- comparamos os dados
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]);
}
}
/* Resultado
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 WebTerminal, build 3620
Terminal
WebTerminal
WebTerminal
Terminal
MQL5
longo preferido_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); }Resultado:
MetaEditor
Terminal
MQL5
//--- primeiro parâmetro handle é ignorado quando o último código de erro é recebido
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
//--- obter o código para o último erro OpenCL
int code = (int)CLGetInfoInteger(0,CL_LAST_ERROR);
string desc; // для получения текстового описания ошибки
//--- usamos o código de erro para obter uma descrição textual do erro
if(!CLGetInfoString(code,CL_ERROR_DESCRIPTION,desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
//--- para obter uma descrição do último erro OpenCL sem primeiro obter o código, passamos CL_LAST_ERROR
if(!CLGetInfoString(CL_LAST_ERROR,CL_ERROR_DESCRIPTION, desc))
desc = "cannot get OpenCL error description, " + (string)GetLastError();
Print(desc);
Por enquanto, o nome da enumeração interna é dado como a descrição do erro, cuja decifração pode ser encontrada na página https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_SUCCESS.
Por exemplo, se CL_INVALID_KERNEL_ARGS for recebido, a descrição para
ele será "Returned when enqueuing a kernel when some kernel arguments
have not been set or are invalid."