English Русский 中文 Español Deutsch 日本語
Interação entre o MеtaTrader 4 e a máquina MATLAB (Máquina virtual MATLAB)

Interação entre o MеtaTrader 4 e a máquina MATLAB (Máquina virtual MATLAB)

MetaTrader 4Exemplos | 8 fevereiro 2016, 14:12
807 0
Andrey Emelyanov
Andrey Emelyanov

Introdução

O pacote matemático do MetaTrader 4 e do MATLAB teve alta popularidade entre os usuários devido a suas características positivas, incluindo "flexibilidade" na criação de sistemas de cálculo complexos. Há várias formas de conectar o MATLAB com aplicativos externos, mas apenas uma delas é recomendada - o uso da máquina MATLAB de área de trabalho virtual. Esse método garante a compatibilidade completa com todo o pacote MATLAB. Vários programadores evitaram esse método pelas razões abaixo:

  • Muitos usuários a acharam lenta. Isso é verdade, se comparado com a função direta chamada das bibliotecas DLL do MATLAB. O atraso principal se dá no início da operação, quando a máquina virtual é solicitada devido à chamada de várias bibliotecas que são carregadas no espaço da área virtual do processo de chamamento (no nosso caso, MetaTrader 4).
  • Transferibilidade do projeto. Verdade, ao transferir um projeto para outro computador, todas as bibliotecas MATLAB DLL também devem ser transferidas, assim como quando uma chamada direta é usada, para saber as "relações" das últimas, por exemplo, iniciar fila!
  • Conhecimento obrigatório de C++ ou Fortran. Bem, se você sabe MQL4, pode aprender facilmente C++ e vice-versa.

Por que recomendo esse método:

  1. Esta é a forma mais independente e confiável do método da versão MATLAB de conexão com programas externos. É possível alterar a versão MATLAB e seus indicadores ou Expert Advisors não perceberão. Essa é a vantagem mais importante.
  2. Ele tem um método de desenvolvimento relativamente rápido. Ele não exige depuradores e não trará dificuldades para escrever o empacotador DLL.
  3. "Área de trabalho comum" para vários indicadores e/ou Expert Advisors. Considero este método útil quando precisamos tomar uma decisão com base nos dados de vários indicadores ou na implementação de uma negociação pirâmide.

Este artigo descreve como conectar o MetaTrader 4 e o MATLAB ver. 7.4.0 (R2007a) por meio do "empacotador DLL" escrito em Borland C++ Builder 6. Os programadores que preferirem produtos Microsoft terão de adaptar os exemplos aos seus compiladores (boa sorte com esse problema complicado!)

I. Como configurar uma tarefa

Primeiro, precisamos definir de onde devemos começar o projeto. Vamos dividir o processo de desenvolvimento em três partes:

  1. O desenvolvimento da função M no MATLAB que implementa o cálculo de um indicador/EA.
  2. O desenvolvimento do "empacotador DLL" para conectar o MATLAB e o MetaTrader 4.
  3. Desenvolvimento do programa MQL.

II. Como desenvolver a função M

Esse é provavelmente o processo mais interessante e de longo prazo que inclui as seguintes ações:

1. Pré-exporta os dados do MetaTrader 4 para o MATLAB.

As figuras mostrar o processo da exportação manual de dados no MATLAB. Quando a exportação terminar, as variáveis serão criadas na área de trabalho do MATLAB.

2. Pesquise fórmulas, parâmetros de faixas de fórmulas etc. corretos.

Esse processo é criativo e muito importante, mas o desenvolvimento do algoritmo matemático de um indicador e/ou Expert Advisor não é o assunto do nosso artigo. É possível encontrar informações sobre isso na literatura sobre MATLAB.

3. Criação da função M no MATLAB.

Um programador que conhece C++ e/ou MQL4 não terá dificuldades em criar a função - além do mais, todas as variáveis tem o mesmo tipo de dados - "matriz". Isto é, não é significativo definir com clareza uma variável com um raio ou uma variável multidimensional - a linguagem fará isso sozinha. E eu não acho que o processo de seleção de tipo de dados seja significativo. Eu sempre uso mxREAL. Bem, talvez seja usada mais memória, mas não há confusão em tal caso. Mais detalhes podem ser encontrados nas referências 1, 2. No exemplo dado, o filtro de frequências alto será implementado.

III. Como desenvolver o "empacotador DLL"

Vamos nos prolongar nesse ponto com mais detalhes, porque é tão ESSENCIAL como ar. Então, cada biblioteca DLL de vinculação anterior deve corresponder às seguintes condições:

  • É necessário ter funções internas para a coleção "sobras" e limpar a memória após sua operação.
  • A multitarefa deve ser possível, isto é, a operação de suporte de mais de um segmento ao mesmo tempo.
  • Deve ser localizado em certos diretórios, consulte adiante: localização de arquivos de projeto.

As funções externas principais do "empacotador DLL" são a interface da API da Máquina MATLAB e uma função da biblioteca de entrada/saída C++ padrão. A interface da API da Máquina MATLAB é simples e compacta; ela contém somente 8 funções:

Máquina *pEng = engOpen(NULL) - função chamando a área de trabalho MATLAB, o parâmetro é sempre NULL, ele retorna o ponteiro para o descritor de área de trabalho, é necessário para a operação de outras funções, a variável é feita de forma global.

int exitCode = engClose(Engine *pEng) - função que fecha a área de trabalho, o ponteiro pEng para o descritor da área de trabalho, retorna o valor, embora ele não seja importante, porque essa função é no fechamento do DLL e não é importante, retorna o número de "usuários" da área de trabalho do MATLAB .

mxArray *mxVector = mxCreateDoubleMatrix(int m, int n, int ComplexFlag) - a função cria uma matriz para a área de trabalho do MATLAB, retorna o ponteiro para a matriz da variável. Isso é necessário para a criação de uma variável compatível com o MATLAB. As séries de dados usuais e/ou tipos de dados simples não podem ser enviados para o MATLAB!

mxArray *mxVector – ponteiro para a matriz variável;

int m – número de linhas;

int m – número de colunas;

ComplexFlag – tipo de número complexo, sempre mxREAL para a operação correta com MetaTrader 4.

void = mxDestroyArray(mxArray *mxVector) – a função apaga a matriz do MATLAB, necessária para a limpeza da memória. Sempre exclua os dados quando eles não forem mais necessários, caso contrário haverá problemas com a memória ou com "sobreposição" de resultados.

mxArray *mxVector – ponteiro para a matriz variável.

int = engPutVariable( Máquina *pEng, char *Name, mxArray *mxVector) – função enviando uma variável para a área de trabalho. As variáveis do tipo mxArray não devem ser apenas criadas, mas também enviadas ao MATLAB.

Máquina *pEng – ponteiro para o "descritor" da área de trabalho;

char *Name – nome da variável da área de trabalho do MATLAB tipo - char;

mxArray *mxVector – ponteiro para a matriz variável.

mxArray *mxVector = engGetVariable(Máquina*pEng, char *Name) – função da variável recebendo da área de trabalho, função oposta à anterior. As variáveis do tipo mxArray podem ser recebidas.

mxArray *mxVector – ponteiro para a matriz variável;

Máquina *pEng – ponteiro para o "descritor" da área de trabalho;

char *Name – nome da variável da área de trabalho do MATLAB tipo - char.

double *p = mxGetPr(mxArray *mxVector) – a função recebe o ponteiro para a série de dados; é usada para copiar os dados junto com memcpy(…). Use essa função quando receber/escrever uma variável do tipo mxArray , para extrair/colar uma variável de um tipo simples (int, double...).

double *p – ponteiro para a série de tipos double;

mxArray *mxVector – ponteiro para a matriz variável.

int = engEvalString(Máquina *pEng, char *Command) – a função envia comando para a área de trabalho. O comando na linha Command será executado pela área trabalho do MATLAB.

Máquina *pEng – ponteiro para o "descritor" da área de trabalho;

char *Command – comando para o MATLAB, linha do tipo de char.

Há apena uma única função para trabalhar com memória:

void *pIn = memcpy (void *pIn, void *pOut, int nSizeByte) – função que copia (clona) uma variável (série) pOut em uma variável pIn no tamanho de nSizeByte bytes.

ATENÇÃO: Veja a dimensionalidade da série. Elas precisam ser iguais, ou a série pln deve ser maior que pOut.

Exigências para as funções de exportação do "empacotador DLL"

Para o MetaTrader 4 ser capaz de usar o MATLAB, transmissores de funções devem ser escritos. Vamos ver as exigências para a implementação de tais funções. Qualquer função seja chamada a partir do MetaTrader 4 deve ser __stdcall – isto é, os parâmetros são transmitidos por meio da pilha, a função limpa a pilha. É assim que a função é declarada:

extern "C" __declspec(dllexport) <variable_type> __stdcall Funcion(<type> <name>);

extern "C" __declspec(dllexport) — informa ao compilador C++ que a função é externa, é escrita na tabela de exportação.

<variable_type> — tipo de uma variável para retornar; pode ser: void, bool, int, double, tipos compostos e ponteiros não podem ser transmitidos, consulte adiante;

__stdcall — acordo em parâmetros de transmissão na função e no retorno;

Função — nome da sua função;

<type> <name> — tipo e nome da variável de entrada; o número máximo de variáveis - 64.

Aqui está o protótipo da função definindo, preste atenção também em __stdcall

bool __stdcall Funcion (<type> <name>)

{

//……

}

Além disso, deve ser criado um arquivo com a extensão def. Normalmente, esse é um texto que descreve o nome da biblioteca e os nomes das funções de exportação. Se esse arquivo não existe, seu arquivo vai "pensar" nos seus próprios nomes distorcidos de função que complicarão o uso do DLL. Aqui estão os exemplos de arquivo:

LIBRARY NameDll

EXPORTS

NameFunctionA

NameFunctionB

LIBRARY – palavra acessório, aponta para o nome DLL.

EXPORTS — palavra acessório que diz que as funções abaixo serão enumeradas.

NameFunctionA, NameFunctionB — nomes das funções DLL.

Mas existem restrições impostas pelo MQL: Como essa linguagem não tem ponteiros, não há memória dinâmica, então as séries, estruturas etc. não podem ser passadas de uma biblioteca DLL. Mas os dados MetaTrader podem ser escritos em séries passadas por uma função por referência. O resultado pode ser escrito em uma série criada por MetaTrader, o ponteiro do qual seu DLL recebeu. Mas a série deve ser de uma certa dimensionalidade e não pode ser uma linha de indicador (essa restrição está conectada provavelmente ao arranjo específico de memória no MetaTrader 4).

Agora, sabendo como escrever e quais funções chamar, vamos ver um algoritmo típico do "empacotador DLL".

1. Iniciar a Máquina MATLAB usando a função engOpen() durante a primeira chamada do DLL;

2. Obter dados do MetaTrader e enviar de volta, função DLL;

2.1. Criar variáveis pela função mxCreateDoubleMatrix();

2.2. Copiar dados na variável mxVector, funções memcpy() e mxGetPr();

2.3. Passar as variáveis para a área de trabalho do MATLAB, função engPutVariable();

2.4. Passar o código/fórmula para a área de trabalho do MATLAB, função engEvalString();

2.5. Receber resposta da área de trabalho do MATLAB, função engGetVariable();

2.6. Retornar o valor ao MetaTrader, funções memcpy() e mxGetPr();

3. Fechar o MATLAB usando a função engClose(), excluindo todas as variáveis mxDestroyArray() ao carregar o DLL do endereço da área de trabalho do processo MetaTrader.

Agora, vamos criar o esqueleto do "empacotador DLL":

/*---------------------------------------------------------------------------
** Libraries + *.lib + *.def:
** libeng.lib** libmx.lib
** libmex.lib** project_name.def
*/
#include <windows.h>#include <memory.h>#include "engine.h"
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)<variable_type>__stdcall Funcion(<type><name>);
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst,unsigned long reason,void *lpReserved)
  {
   /*    
** reason for DLL call    
*/
   switch(reason)
     {
      case DLL_PROCESS_ATTACH:
         /*            
** DLL uploaded into the address space of the process            
*/
         break;
      case DLL_PROCESS_DETACH:
         /*            
**DLL loaded from the address space of the process            
*/
         break;
     }
   return TRUE;
  }
//---------------------------------------------------------------------------
bool __stdcall Funcion(<type><name>)
  {
   ……
  }
//---------------------------------------------------------------------------

Montagem do projeto

A figura abaixo mostra como as bibliotecas e os arquivos *.def são adicionados ao projeto:

Aqui está a lista de arquivos necessários para o projeto "empacotador DLL":

  1. libeng.lib – localizado em: \Program Files\MATLAB\R2007a\extern\lib\win32\borland\
  2. libmx.lib – localizado em: \Program Files\MATLAB\R2007a\extern\lib\win32\borland\
  3. libmex.lib – localizado em: \Program Files\MATLAB\R2007a\extern\lib\win32\borland\
  4. имя_проекта.def – este arquivo deve ser criado em um bloco de notas como descrito acima.

O arquivo engine.h file deve ser copiado de \Program Files\MATLAB\R2007a\extern\\include para a pasta \Program Files\Borland\CBuilder6\Include - assim você não precisa indicar sempre o caminho ao compilador.

Atenção: Essas instruções são dadas para a montagem do projeto apenas em Borland C++ Builder 6!

IV. Como desenvolver um programa MQL4

Veremos perguntas conectadas apenas à declaração das funções "empacotador DLL" e a passagem de parâmetros. Então, para declarar uma função, a construção da linguagem abaixo é necessária:

#import "HighPass.dll"

void ViewAnsFilter();

bool TestDllFilter();

bool AdaptiveHighFilter(double& nInVector[], int nSizeVector, double nSizeWind, double dAmplit);

void MakeBuffFilter(int nSize);

void DestrBuffFilter();

#import

em que:

#import "HighPass.dll" – palavra chave e nome da biblioteca DLL;

void MakeBuffFilter(int nSize); - nome da função, tipo de um valor a ser retornado, nome e tipo de um valor passado.

NB ! "[]" é usado ao passar séries, o caractere "&" é necessário, se dll escrever uma resposta a essa série de dados! Não há outras formas da série passar de programas externos em MQL4! A série a ser passada deve ser de uma certa dimensionalidade e não pode ser uma série de indicador!

V. Localização de arquivos

Após a construção do projeto, todos os arquivos de projeto devem ser corretamente localizados:

*.dll e *.m - arquivos da biblioteca e funções m no catálogo \Program Files\MetaTrader\experts\libraries;

*.mql está localizado no seu local usual. Isto é, se isso for um indicador - na pasta "indicador", se um EA - em "experts", se um script - na pasta "scripts".

Atenção: Ao iniciar um indicador ou Expert Advisor, o aviso sobre servidor ocupado poderá aparecer:

Em tal caso, espere de 5 a 10 segundos até que o Console Matlab apareça na barra de tarefas e clique em "Repetir".

P.S. Tenho um notebook com 512 RAM, Celeron M 2.100; não sofri atrasos na operação de filtro, número de gráficos - 5 com o buffer total de 500 х 8 х 5 = 20.000 bytes. Então, a escolha é sua! Quanto a mim, eu já decidi. Se houver atraso, um sistema de cálculo distribuído pode ser facilmente implementado no MATLAB; isto é, várias áreas de trabalho podem ser iniciadas em diferentes PCs conectados a uma rede local.

Lista de referência

  1. Ajuda incorporada ao MATLAB.
  2. "Matlab 5.х Calculations, Visualization, Programing" N.N. Martynov.
  3. "C++ Builder 6. Reference Manual" A.Y. Arkhangelski.
  4. Ajuda incorporada ao MQL4.

Conclusão

Neste artigo, discutimos o básico do desenvolvimento do "empacotador DLL" para vincular o MetaTrader 4 ao pacote matemático do MATLAB. Não tratamos de questões sobre o fornecimento de operação de vários indicadores e/ou Expert Advisors - eles serão discutidos no próximo artigo. O arquivo anexado contém MACD melhorado devido ao uso de filtros de alta frequência.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1567

Arquivos anexados |
highpas.rar (10.19 KB)
highpasFull.zip (355.1 KB)
Alerta e comentários para indicadores externos Alerta e comentários para indicadores externos
No trabalho prático, um trader pode enfrentar a seguinte situação: é necessário ficar "alerta" ou uma mensagem de texto aparecerá em uma tela (em uma janela de gráfico) indicando um sinal de um indicador. O artigo contém um exemplo de exibição de informações sobre objetos gráficos criados por um indicador externo.
Canais. Modelos avançados. Wolfe Waves Canais. Modelos avançados. Wolfe Waves
O artigo descreve as regras para marcar padrões de Wolfe Waves. Você encontrará mais detalhes sobre a construção e as regras de marcação precisa, o que ajuda a encontrar as formações corretas de ondas de forma rápida e correta.
Kit do trader: Indicadores de decoração Kit do trader: Indicadores de decoração
Neste artigo, você encontrará tarefas principais ao decorar indicadores, suas soluções e automatização.
Algoritmos de média eficiente com lag mínimo: Usar em indicadores Expert Advisors Algoritmos de média eficiente com lag mínimo: Usar em indicadores Expert Advisors
O artigo descreve as funções médias personalizadas de desenvolvimento de alta qualidade pelo autor: JJMASeries(), JurXSeries(), JLiteSeries(), ParMASeries(), LRMASeries(), T3Series() e MASeries(). O autor considera a substituição quente dessas funções em indicadores usando a chamada da função SmoothXSeries().