![Abordagem do objeto no MQL](https://c.mql5.com/i/articles/overlay.png)
Abordagem do objeto no MQL
Introdução
Este artigo vai ser interessante, em primeiro lugar, para programadores novatos e profissionais que trabalham no ambiente MQL. Também seria útil se este artigo fosse lido por desenvolvedores e ideólogos do ambiente MQL pois as questões aqui analisadas podem tornar-se projetos para uma futura implementação do MetaTrader e da MQL. Ideias parecidas podem ser encontradas nos artigos Modelo Universal de Expert Advisor e Envio de sinais de trading em um Expert advisor Universal.
Então,
Uma das desvantagens da MQL, na minha opinião de programador, é a ausência de objecto de abordagem na construção do modelo do sistema de trading. Os desenvolvedores da MQL nos oferecem duas saídas: utilizar a chamada de funções externas ou utilizar o parâmetro MAGIA para identificação da ordem pertencente.
Na verdade, se apenas um sistema opera em uma conta, nós não precisamos de identificação. Mas quando temos a opção do programa de anexar a uma conta vários sistemas de trading automatizados, então não podemos fazer isto sem MAGIA. Mesmo ao chamar funções externas, é preciso determiná-las. Claro que podemos construir uma matriz OrderTicket e identificar a matriz pertencente a um único sistema de trading, mas como sabemos, em algumas corretoras a ordem de crédito alterar a troca (na verdade, uma é fechada, a outra é aberta). É por isso que não podemos fazer isto sem utilizar MAGIA.
Assim, enquanto os desenvolvedores estão ocupados melhorando a linguagem MQL e tornando-a mais flexível, vamos tentar implementar já agora a abordagem do objeto na construção de um modelo de trading.
Este é um sistema de trading de acordo com o meu modelo de objeto. Claro, ele não é universal, mas até agora eu não vi outras abordagens.
![](https://c.mql5.com/2/15/1.png)
Então, vamos analisar este modelo.
A) Sistema do sinal (SS).
Objeto deste processo de módulo e interpretação de cotações recebidas. Normalmente, o "objeto" do sistema de sinal é um conjunto de indicadores, por exemplo, de médias móveis. Como resultado do processamento dos valores de cotações e indicadores, "o objeto" (ou semáforo) produz sinais de entrada/saída ou modificação de ordens.
O semáforo forma seu sinal e o envia para outro objeto do módulo de entrada/saída (EE).
Definir o semáforo em MQL é bastante fácil.
1. Defina um identificador global usando #define.
É melhor definir números não consecutivos como 1, 2, 3, 4 ..., mas em 5-10, de modo que em um Expert Advisor poderíamos utilizar um sinal para vários processos (ver o segundo módulo).
//+------------------------------------------------------------------+ //| Signals.mqh | //| Copyright © 2007 Сергеев Алексей | //| los@we.kherson.ua | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, Сергеев Алексей " #property link "mailto: los@we.kherson.ua" #property library #define BLACKSYS 10 #define BORCHAN 20 #define ELDER 80 #define ENVELOP 90
2. Em seguida, na função global deste módulo devemos habilitar seu processador.
int CheckSignal(bool bEntry, int SignalID) { switch (SignalID) { case BLACKSYS: return (BlackSys(bEntry)); break; case BORCHAN: return (BorChan(bEntry)); break; case ELDER: return (Elder(bEntry)); break; case ENVELOP: return (Envelop(bEntry)); break; default: return (-1); } }
3. E a última etapa é a descrição das funções.
Aqui está um exemplo para sinais de processamento de um objeto que herda as características do indicador Envelope.
int Envelope(bool bEntry) { int MA=21; double Deviation=0.6; int Mode=MODE_SMA;//0-sma, 1-ema, 2-smma, 3-lwma int Price=PRICE_CLOSE;//0-close, 1-open, 2-high, 3-low, 4-median, 5-typic, 6-wieight double envH0, envL0, m0; double envH1, envL1, m1; envH0=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_UPPER, 0); envL0=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_LOWER, 0); envH1=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_UPPER, 1); envL1=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_LOWER, 1); m0 = (Low[0]+High[0])/2; m1 = (Low[1]+High[1])/2; //----- condition for operation execution if (bEntry) //for opening { if (envH0<m0 && envH1<m1) return (OP_SELL); if (envL0>m0 && envL1>m1) return (OP_BUY); } else //for closing { if (envH0<m0 && envH1<m1) return (OP_BUY); if (envL0>m0 && envL1>m1) return (OP_SELL); } return (-1); //no signal }
Assim, temos um módulo que irá conter diferentes sinais-objetos.
B) Objetos do bloco EE têm tarefas mínimas:
Em primeiro lugar, seus objetos interagem com sinais-objetos - observe-os. O ciclo de vida e a interação é a seguinte:
Verificação do semáforo -> se existirem sinais positivos, abrir/fechar/ modificar posições -> Passe o controle para os objetos no módulo PS.
Todos os objetos no módulo EE ter um processo de prefixo ..., que determina seu comportamento mais especificamente.
Por exemplo:
ProcessAvgLim // - the object processes signals with opening pending limit-orders and positions averaging ProcessTurn // - the object processes signals with position turning
Cada amostra de uma classe de sistema de trading (todos nós entendemos isso e utilizamos em nossos módulos) deve ter suas próprias características individuais, tais como lucro, stop-loss, sua própria gestão financeira, bem como outros parâmetros adicionais implementados em diferentes variantes de rastreamento etc.
Ao implementar esses recursos, tentei várias variantes da abordagem e a mais adequada em MQL, na minha opinião, é a criação de uma matriz bidimensional. Aqui está a descrição:
double SysPar[nSignal][11]; #define _TP 0 // Profit #define _NullTP 1 // profit level, after which we set into losslessness #define _NullTP2 2 // profit level, after which we set into losslessness #define _TS 3 // distance of the trailing stop #define _NullSL 4 // level, after achieving which the expected profit is transfered into opening point #define _SL 5 // level, after achieving which the expected profit is transfered into opening point #define _dSL 6 // the initial step upon the opening level of the next order in the position support #define _dStep 7 // The step is increased in .. times upon the level of the next opening #define _dLot 8 // In how many times (as compared to the last one) we increase the lot on the next one #define _nLot 9 // In how many times (as compared to the initial one) we increase the lot on the next one string SysParName[nSignal];
onde nSignal é o identificador dos sinais-objeto.
Por exemplo:
SysPar[ENVELOP][_TS] = 40.0; // distance of the trailing stop SysPar[ENVELOP][_NullSL] = 20.0;// level, after achieving which the expected profit is transfered into opening point SysPar[ENVELOP][_SL] = 70; // changing stop-loss
Se desejar, você pode aumentar o número de parâmetros definidos desta estrutura de matriz.
Então, depois de definir os parâmetros, chamamos a função de processamento do semáforo. Em outras palavras: nós interagimos com o sinal do sistema. Isto é feito na minha função favorita start()
void start()
{
ProcessAvgLim(ENVELOP, ENVELOP, Green, Red);
… …
![](https://c.mql5.com/2/15/2.png)
Como se vê no esquema, no sistema de trading temos 4 semáforos registrados e 3 observadores. Cada semáforo é baseado em sua própria variante da interpretação das cotações.
Por exemplo, o Semáforo 1 envia sinais analisando o indicador MACD. O Observador 1 , por sua vez, após receber estes sinais, abre ordens em um simples esquema ProcessSimple.
Os observadores 2 e 3 são mais difíceis. Cada um controla sinais de dois semáforos. E, consequentemente, a abordagem para a ordem de abertura é diferente.
Então, depois de definir os parâmetros do observador e anexar um semáforo para isso, precisamos controlar e rastrear as posições de abertura.
Os objetos do módulo Suporte de Posição (PS) são "responsáveis" pelo estado das ordens abertas.
C) OBloco PS , na minha opinião, é o mais interessante e não menos importante que os semáforos.
Aqui diferentes variantes de rastreamento são implementadas: as ordens pendentes são abertas, suporte de posição e bloqueio, controle de lucro e perda e assim por diante. Tal PS deve reagir adequadamente aos sinais EE sobre sair do mercado em caso de perda de posições com perdas mínimas.
Neste site há uma biblioteca interessante de rastreamento Library of Functions and Expert Advisors for trailing / Yury Dzyuban. Todos os tipos de rastreamento são facilmente anexados no sistema.
Para uma percepção mais fácil, todos os objetos de suporte iniciam do prefixo rastreamento...
Ele possui o seguinte esquema:
![](https://c.mql5.com/2/15/3.png)
A chamada da transferência de controle a partir de um observador para o rastreamento é feita na mesma função Start()
void start()
{
ProcessSimple(MACD, MACD, Black, Plum); TrailingSimple(MACD, Black, Plum);
ProcessAvgLim(ENVELOPE, ENVELOPE, Green, Red); TrailingAvgLim(ENVELOPE, Green, Red);
}
Portanto, este foi uma variante de exemplo da abordagem do objeto para a construção do sistema. Aqueles que quiserem, podem usá-la.
E mais uma vez eu gostaria de pedir aos desenvolvedores da MQL para aumentarem as opções da linguagem. E como exemplo, aqui está uma variante de implementação de classes de objetos escrita na linguagem C++.
struct SystemParam { double TP; // profit double NullTP; // profit level, after which we set into losslessness double NullTP2; // profit level, after which we set into losslessness a set of one-direction orders double TS; // distance of the trailing stop double NullSL; // loss level, at which we transfer the expected profit into losslessness double SL; // stop-loss double dSL; // a step upon the opening level of the next order for the position support double dStep; // In how many times we increase the step upon the opening level of the next order double dLot; // In how many times we increase the lot on the next order } class MTS { public: string m_NameTS; // system name (for making comments for the order) int m_SignalID; // identifier of trading signals (for semaphore inquiry) long int Tickets[1000]; // array of order tickets, selected upon m_SignalID (MAGIC) SystemParam SysPar; // Trading system parameters color ClrBuy; // color for indicating BUY order color ClrSell; // color for indicating SELL order // Initialization void MyMTS (); // standard function that sets initial values of the system void MyMTS (int aSignalID, int nProcessMode, int nTrailingMode); // standard function // that sets initial values of the system // Implementation int CheckSignal(); //function of checking state of market signals // Processing int m_nProcessMode; // identifier of observation mode int m_nTrailingMode; // identifier of trailing mode void Process(); // EE function - processing CheckSignal() void Trailing(); // PS function - order trailing // Special functions bool CreatTicketArray(int dir); // creating an array of tickets, selected upon m_SignalID (MAGIC) // and desired type dir: buy, sell, buylim, buystop, sellim, sellstop bool ArrangeOrderBy(int iSort); // arranging array Tickets upon the parameter (date, profit, price...) }; … MTS MyTS; // our trading system … int init() { … MyTS.m_SignalID = SIGNAL_MACD; // our system is based on MACD signals MyTS.m_NameTS = "MACD"; MyTS.SysPar.TP = 500; MyTS.SysPar.NullTP = 20; MyTS.SysPar.TS = 50; MyTS.SysPar.SL = 1000; MyTS.SetProcess (MODE_AVGLIM); MyTS.SetTrailing (MODE_AVGLIM); … } void start() { … MyTS.Process (); MyTS.Trailing (); … } … void MTS::Process() { … int Signal = CheckSignal(true, m_SignalID); //calling the global function of signal processing if (Signal == -1) return; // if no signal, do nothing //----- for buying if(Signal == OP_BUY) { } if(Signal == OP_SELL) { } … } … // global processor of semaphores int CheckSignal(bool bEntry, int SignalID) { switch (SignalID) { case ELDER: return (Elder(bEntry)); break; case ENVELOP: return (Envelop(bEntry)); break; case LAGUER: return (Laguer(bEntry)); break; case MACD: return (Macd(bEntry)); break; … } } // calling a certain semaphore int Macd(bool bEntry) { double MACDOpen=3; double MACDClose=2; double MA=26; int MODE_MA = MODE_EMA; // method of the calculation of averages int PRICE_MA = PRICE_CLOSE; // method of the calculation of averages int PERIOD = PERIOD_H1; // the period to work with //parameters of averages double MacdCur, MacdPre, SignalCur; double SignalPre, MaCur, MaPre; //---- get the value MacdCur=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_MAIN,0); MacdPre=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_MAIN,1); SignalCur=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_SIGNAL,0); SignalPre=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_SIGNAL,1); MaCur=iMA(NULL,0,MA,0,MODE_MA,PRICE_MA,0); MaPre=iMA(NULL,0,MA,0,MODE_MA,PRICE_MA,1); //----- condition for the operation execution if (bEntry) //for buying bEntry==true { if(MacdCur<0 && MacdCur>SignalCur && MacdPre<SignalPre && MathAbs(MacdCur)>(MACDOpen*Point) && MaCur>MaPre) return (OP_BUY); if(MacdCur>0 && MacdCur<SignalCur && MacdPre>SignalPre && MacdCur>(MACDOpen*Point) && MaCur<MaPre) return (OP_SELL); } else //for closing bEntry==false { if(MacdCur>0 && MacdCur<SignalCur && MacdPre>SignalPre && MacdCur>(MACDClose*Point)) return (OP_BUY); if(MacdCur>0 && MacdCur<SignalCur && MacdPre>SignalPre && MacdCur>(MACDOpen*Point) && MaCur<MaPre) return (OP_BUY); if(MacdCur<0 && MacdCur>SignalCur && MacdPre<SignalPre && MathAbs(MacdCur)>(MACDClose*Point)) return (OP_SELL); if(MacdCur<0 && MacdCur>SignalCur && MacdPre<SignalPre && MathAbs(MacdCur)>(MACDOpen*Point) && MaCur>MaPre) return (OP_SELL); } return (-1); //no signal }
A lógica do sistema no idioma MQL não será muito diferente. Todas as funções se tornam globais. E para diferenciar as ordens de um sistema de trading das ordens de outro, teremos de adicionar o parâmetro SignalID (isto é, MAGIA) em todas as funções que trabalham com ordens.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1499
![Linguagem MQL4 para Iniciantes. Indicadores personalizados (Parte 1)](https://c.mql5.com/2/15/516_15.gif)
![Como implementar seus próprios critérios de otimização](https://c.mql5.com/2/14/460_29.jpg)
![Indicador Taichi - uma ideia simples de formalizar os valores do Ichimoku Kinko Hyo](https://c.mql5.com/2/15/509_25.gif)
![Linguagem MQL4 para Iniciantes. Indicadores técnicos e funções integradas](https://c.mql5.com/2/15/466_27.gif)
![MQL5 - Linguagem para estratégias de negociação inseridas no terminal do cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso