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." MetaTrader 5 WebTerminal
Terminal
MQL5
classe A { }; void OnStart(void) { const A *const arr[][2][3]={}; Print(typename(arr)); }Resultado:
"class A const * const [][2][3]"
Terminal
MQL5
Correções de crash-logs.
MetaTrader 5 WebTerminal build 3500
Versão móvel do terminal web
A nova versão do terminal web possui suporte total para dispositivos móveis. Agora sua interface se adapta automaticamente ao tamanho da tela, permitindo que os usuários trabalhem convenientemente na plataforma por meio de telefones e tablets com iOS e Android:
Além disso, muitas correções e melhorias foram feitas no terminal web.
Novo terminal web MetaTrader 5 suporta todos os recursos que um trader moderno precisa. O aplicativo permite:
Terminal
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);
O tipo de dados a ser copiado é especificado no parâmetro flags usando a enumeração ENUM_COPY_TICKS. Estão disponíveis os seguintes valores:COPY_TICKS_INFO = 1, // ticks causados por mudanças em Bid e/ou Ask
COPY_TICKS_TRADE = 2, // ticks causados por mudanças em Last e Volume
COPY_TICKS_ALL = 3, // ticks com alterações
COPY_TICKS_TIME_MS = 1<<8, // tempo em milissegundos
COPY_TICKS_BID = 1<<9, // preço Bid
COPY_TICKS_ASK = 1<<10, // preço Ask
COPY_TICKS_LAST = 1<<11, // preço Last
COPY_TICKS_VOLUME = 1<<12, // volume
COPY_TICKS_FLAGS = 1<<13, // sinalizadores de tick
Quando vários tipos de dados são selecionados (disponível apenas para matrizes), a ordem das linhas na matriz corresponderá à ordem dos valores na enumeração.bool matrix::Assign(const vector &vec);
O resultado será uma matriz de uma linha.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[]);
Cada array, vetor ou matriz aponta para um buffer de memória que contém os elementos de dado objeto. O método Swap realmente troca de lugar os ponteiros para esses buffers sem gravar os elementos na memória. Desse modo, a matriz continua sendo uma matriz e o vetor continua sendo um vetor. Quando você troca uma matriz e um vetor, obtém uma matriz de uma linha com elementos vetoriais e um vetor com elementos de matriz em uma representação plana (consulte o método Flat).//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
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 matrix pointers
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]]
*/
}
O método Swap também permite trabalhar com arrays dinâmicos (um array de tamanho fixo que não pode ser passado como parâmetro). Neste caso, a matriz pode ser de qualquer dimensão, mas de um tamanho acordado. Isso significa que o tamanho total de uma matriz ou vetor deve ser um múltiplo da dimensão zero da matriz. A dimensão zero de uma matriz é o número de elementos contidos no primeiro índice da matriz. Por exemplo, para um array tridimensional dinâmico double array[][2][3], a dimensão zero será o produto dos tamanhos da segunda e da terceira dimensão, ou seja, 2x3=6. Isso significa que tal array só pode ser usado no método Swap com matrizes e vetores cujo tamanho total seja múltiplo de 6: 6, 12, 18, 24, etc.//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- preenchemos a matriz 1x10 com o valor 7,0
matrix m= matrix::Full(1, 10, 7.0);
Print("matrix before Swap:\n", m);
//--- tentamos realizar um intercâmbio entre uma matriz e um array
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 // o tamanho da matriz não é um múltiplo do tamanho da primeira dimensão do array
{
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
*/
//--- pegamos uma matriz maior e tentamos a realizar o intercâmbio novamente
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 // um array estático não pode ser usado para troca com uma matriz
{
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
*/
//--- outra tentativa de trocar um array e uma matriz
double array_dynamic[][10]; // array dinâmico
ArrayResize(array_dynamic, 3); // colocamos o tamanho da primeira dimensão
ArrayCopy(array_dynamic, array_static);
//--- agora usamos um array dinâmico para realizar o intercâmbio
if(m.Swap(array_dynamic))
{
Print("array_dynamic after Swap:");
ArrayPrint(array_dynamic);
Print("matrix after Swap: \n", m);
}
else // não há erros
{
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
Correções de crash-logs.
Terminal
MQL5
bool vector<TDst>::Assign(const vector<TSrc> &assign); bool matrix<TDst>::Assign(const matrix<TSrc> &assign);Por exemplo:
//--- 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);O tipo de dados a ser copiado é especificado no parâmetro rates_mask usando a enumeração ENUM_COPY_RATES. Estão disponíveis os seguintes valores:
Corrigido o erro de alteração em um parâmetro constante passado para uma função como referência a um ponteiro de objeto.
Lembre-se de que o especificador const declara variável constante e não permite alterar o valor desta variável durante a execução do programa. Apenas uma vez permitida a inicialização da variável quando ela é declarada. Exemplo de variáveis constantes na função 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 );
Mas no exemplo abaixo, houve um erro do compilador que permitia a conversão implícita de ponteiro para parâmetros de referência:
class A {}; const A *a = new A; void foo( const A*& b ) { b = a; } void OnStart() { A *b; foo(b); // não permitido Print( a,":",b ); }Agora esta operação ilegal será detectada pelo compilador e gerará um erro.
MetaEditor
Novo terminal web MetaTrader 5
Apresentamos
um novo terminal web para o MetaTrader 5. Nós o fizemos moderno e
rápido, atualizando não apenas o visual, mas também reescrevendo
completamente o núcleo. Em termos de interface, o terminal web evoluiu
de forma similar à já familiar versão iPad da plataforma:
Comparado com a versão antiga, tem muitos recursos novos:
Terminal
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]] */No caso de MathMod e MathPow, um escalar, uma matriz ou um vetor de tamanho apropriado pode ser usado como segundo parâmetro.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- используем инициализирующую функцию для заполнения вектора vector r(10, ArrayRandom); // массив случайных чисел от 0 до 1 //--- вычислим среднее значение double avr=r.Mean(); // среднее значение массива vector d=r-avr; // вычислим массив отклонений от среднего значения Print("avr(r)=", avr); Print("r=", r); Print("d=", d); vector s2=MathPow(d, 2); // массив квадратов отклонений double sum=s2.Sum(); // сумма квадратов отклонений //--- вычислим стандартное отклонение 2-мя способами 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 */ //+------------------------------------------------------------------+ //| Заполняет вектор случайными значениями | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
Aprimoradas as funções matemáticas para trabalhar com o tipo float.
Devido ao surgimento da aplicação de funções matemáticas a matrizes e
vetores flutuantes, as funções correspondentes aplicadas a escalares
flutuantes também foram melhoradas. Anteriormente, os parâmetros dessas
funções eram convertidos incondicionalmente no tipo double, a
implementação correspondente da função matemática era chamada e, em
seguida, o resultado era convertido no tipo float. Agora, no caso do
tipo float, os parâmetros e resultados não são convertidos, pois são
chamadas as implementações das funções matemáticas correspondentes ao
tipo float.
A diferença nos cálculos usando o exemplo de um seno matemático:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- массив случайных чисел от 0 до 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 */ //+------------------------------------------------------------------+ //| Заполняет вектор случайными значениями | //+------------------------------------------------------------------+ void ArrayRandom(vector& v) { for(ulong i=0; i<v.Size(); i++) v[i]=double(MathRand())/32767.; }
Uma função de ativação em uma rede neural determina como a soma ponderada de um sinal de entrada é convertida no sinal de saída de um nó ou nós a nível da rede. A escolha da função de ativação tem um grande impacto nas capacidades e no desempenho da rede neural. Diferentes partes do modelo podem usar diferentes funções de ativação. A linguagem MQL5 implementa não apenas todas as funções de ativação conhecidas, mas também derivações da função de ativação. Funções derivadas são necessárias para calcular rapidamente a correção com base no erro recebido durante o treinamento da rede neural.
AF_ELU Exponential Linear Unit AF_EXP Exponencial 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 Mean Squared Error LOSS_MAE Mean Absolute Error LOSS_CCE Categorical Crossentropy LOSS_BCE Binary Crossentropy LOSS_MAPE Mean Absolute Percentage Error LOSS_MSLE Mean Squared Logarithmic Error 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 Logarithm of the Hyperbolic Cosine LOSS_HUBER Huber
int cl_ctx; //--- инициализация OpenCL контекста 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]'