Colocação de ordens no MQL5
Introdução
Em qualquer sistema de negociação, temos de lidar com ordens, como abrir posições, definir stop loss e take profit e alterar ordens. Portanto, é muito importante entender como lidar com as operações de ordens na MQL5 ao criar um sistema de negociação para o MetaTrader5. O objetivo deste artigo é fornecer um guia simples para a maioria das operações que envolvem ordens e posições. Para isso, abordaremos os seguintes tópicos:
- Ordens, posições e negociações
- OrderSend()
- Uso do OrderSend()
- Classe CTrade
- Uso da classe CTrade
- Conclusão
Espero que este artigo o ajude no desenvolvimento sem problemas do seu sistema de negociação MetaTrader 5 no que diz respeito à colocação de ordens. Teste todos os recursos anexados a este artigo para ter certeza de que são lucrativos e adequados ao seu estilo de negociação. Seu principal objetivo é exemplificar como criar um sistema de negociação usando dois métodos diferentes para lidar com ordens, negociações e posições.
Ordens, posições e negociações
Nesta parte, falaremos sobre termos importantes para entender como trabalhar efetivamente com ordens. Também veremos a diferença entre três conceitos relacionados a ordens no MetaTrader 5. Esses conceitos são o de ordem, negociação e posição. Podemos pensar nesses termos como as etapas para executar uma negociação.
Uma ordem é uma solicitação recebida pelo servidor de negociação para abrir uma operação de compra ou venda com um determinado lote ou volume a um determinado preço. Há dois tipos de ordens: a mercado e pendente.
- A ordem a mercado pode ser executada imediatamente ao preço atual de mercado.
- A ordem pendente é executada a um preço e horário predefinidos.
As ordens pendentes, por sua vez, podem ser dos seguintes tipos:
- Buy stop - ordem pendente de compra a um preço específico, que é superior ao preço atual no mercado.
- Buy limit - ordem pendente de compra a um preço específico, que é inferior ao preço atual no mercado.
- Sell stop - ordem pendente de venda a um preço específico, que é inferior ao preço atual no mercado.
- Sell limit - ordem pendente de venda a um preço específico, que é superior ao preço atual no mercado.
Após a colocação da ordem, seja ela a mercado ou pendente, ela pode ser encontrada na aba "Negociação" do painel de ferramentas no MetaTrader 5. Veja a seguir um exemplo:
Quando uma ordem é fechada ou cancelada sem ser executada, ela pode ser encontrada na aba "Histórico" na janela "Ferramentas".
A seguir, examinaremos a modificação de ordens abertas.
A negociação é o resultado da execução de uma ordem de negociação. Dito de outra forma, são ações de entrar/sair do mercado. Vamos supor que tenhamos executado uma ordem de compra de um lote. Depois disso, fechamos uma parte da posição em 0,5 lotes e, em seguida, fechamos os 0,5 lotes restantes. A sequência de negociações será a seguinte:
- entrada de 1 lote
- venda de 0.5 lotes
- venda de 0.5 lotes
Podemos exibir as negociações clicando com o botão direito do mouse na aba "Histórico" da janela "Ferramentas" e selecionando "Negociações".
A posição é uma sucessão de operações longas ou curtas para comprar ou vender um ativo financeiro. Podemos encontrar posições ativas na aba "Negociação" ou na aba "Histórico", se selecionarmos a exibição de posições.
O preço de execução de uma ordem de compra é o preço Ask, enquanto o preço de execução para o fechamento é o preço Bid. Por outro lado, o preço de execução de uma ordem de venda é o preço Bid, enquanto o preço de execução para o fechamento é o preço Ask.
OrderSend()
Uma vez que já examinamos os termos importantes relacionados à execução de negociações na MetaTrader 5, vamos aprender como executar ordens automaticamente no MQL5. Lembre que você pode consultar a seção "Funções de Negociação" na ajuda do MQL5.
Vamos examinar a função OrderSend(), que pode ser usada para realizar operações de negociação enviando pedidos ao servidor de negociação. Em outras palavras, pode ser usada para colocar, modificar e fechar ordens.
Vejamos a seguir a estrutura dessa função:
bool OrderSend( MqlTradeRequest& request, MqlTradeResult& result );
Como podemos ver, a função tem dois parâmetros:
- Estrutura MqlTradeRequest contém os parâmetros da ordem e todos os campos ou variáveis necessárias para realizar operações de negociação. Os objetos são passados por referência, de acordo com os sinais de adição (&). TradeRequest é o método de interação entre o terminal do cliente e o servidor de negociação para a execução de ordens.
- Estrutura MqlTradeResult: TradeResult retorna os resultados do pedido de ordem. Os objetos também são passados por referência.
Estrutura MqlTradeRequest:
A estrutura é um conjunto de dados relacionados de diferentes tipos. A estrutura MqlTradeRequest é definida da seguinte forma:
struct MqlTradeRequest { ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type ulong magic; // Expert Advisor ID (magic number) ulong order; // Order ticket string symbol; // Trade symbol double volume; // Requested volume for a deal in lots double price; // Price double stoplimit; // StopLimit level of the order double sl; // Stop Loss level of the order double tp; // Take Profit level of the order ulong deviation; // Maximal possible deviation from the requested price ENUM_ORDER_TYPE type; // Order type ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type ENUM_ORDER_TYPE_TIME type_time; // Order expiration type datetime expiration; // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type) string comment; // Order comment ulong position; // Position ticket ulong position_by; // The ticket of an opposite position };
Podemos declarar um objeto MqlTradeRequest usando a seguinte linha de código:
MqlTradeRequest request;
Então, podemos atribuir parâmetros de negociação às variáveis do objeto de pedido criado, adicionando um ponto (.) após o objeto, como mostrado no exemplo a seguir:
request.symbol = _Symbol; request.volume = 0.01; request.type = ORDER_TYPE_BUY;
A seguir, uma lista de todos os membros ou variáveis da estrutura MqlTradeRequest, bem como os valores que ela aceita.
Variável | Descrição | Valor aceito para atribuição |
---|---|---|
action | Tipo de operação de negociação | Um dos ENUM_TRADE_REQUEST_ACTIONS (TRADE_ACTION_DEAL, TRADE_ACTION_PENDING, TRADE_ACTION_SLTP, TRADE_ACTION_MODIFY, TRADE_ACTION_REMOVE, TRADE_ACTION_CLOSE_BY) |
magic | ID do Expert Advisor para identificação de ordens colocadas por um determinado EA | Qualquer valor ulong |
order | Número do ticket da ordem. Necessário ao usar TRADE_ACTION_MODIFY ou TRADE_ACTION_REMOVE na variável de ação. | Qualquer valor ulong |
symbol | O símbolo ou instrumento especificado a ser negociado. (_SYMBOL) representa o atual | Qualquer símbolo em forma de string |
volume | Volume de negociação ou lotes | Qualquer valor double permitido |
price | Preço de abertura | Valor double |
stoplimit | Preço de abertura de uma ordem pendente limit. A ação deve ser TRADE_ACTION_PENDING, e a variável de tipo deve ser ORDER_TYPE_BUY_STOP_LIMIT ou ORDER_TYPE_SELL_STOP_LIMIT. Variável necessária para ordens stop-limit | Valor double |
sl | Preço de stop-loss da negociação | Valor double |
tp | Preço de take-profit da negociação | Valor double |
deviation | Desvio máximo de preço em pontos | Valor ulong |
type | Tipo de ordem | Um dos ENUM_ORDER_TYPE (ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY_STOP, ORDER_TYPE_SELL_STOP, ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT, ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT) |
type_filling | Tipo ou política de execução da ordem | Um dos ENUM_ORDER_TYPE_FILLING (ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_BOC, ORDER_FILLING_RETURN) |
type_time | Tipo de expiração da ordem pendente | Um dos ENUM_ORDER_TYPE_TIME (ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY) |
expiration | Tempo de expiração da ordem pendente. Necessário se type_time for ORDER_TIME_SPECIFIED | Valor datetime |
comment | Comentário à ordem | Valor string |
position | Ticket da posição. Necessário ao modificar ou fechar uma posição para sua identificação. | Valor ulong |
position_by | Ticket da posição oposta. Usado ao fechar uma posição oposta para o mesmo símbolo. | Valor ulong |
Agora, vamos destacar algumas ações importantes a serem usadas ao colocar ordens no MQL5.
- Ordem a mercado
- Adição de stop-loss e take-profit
- Ordem pendente
- Modificação de ordem pendente
- Remoção de ordem pendente
Ordem a mercado:
Nesse tipo de ação, precisamos colocar uma ordem a mercado, o que significa que a ordem será colocada ao preço de mercado atual. Usaremos a ação (TRADE_ACTION_DEAL). Se for uma ordem de compra, será colocada ao preço Ask atual, e se for uma ordem de venda, ao preço Bid atual. Veja como fazer isso:
Após declarar os objetos MqlTradeRequest e MqlTradeResult, atribuímos os seguintes valores às variáveis necessárias:
request.action = TRADE_ACTION_DEAL; &nbsthe p; //market order palcement request.type = ORDER_TYPE_BUY; //type of order is buy request.symbol = _Symbol; //applied for the cuurrent symbol request.volume = 0.1; //the lot size request.type_filling = ORDER_FILLING_FOK; //the filling policy fill or kill request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); //the price is the current ask for buy request.sl = 0; //stop loss is 0 request.tp = 0; //take profit is 0 request.deviation = 50; //slippage is 50 OrderSend(request, result); //calling the OrderSend function
Como podemos ver, não adicionamos valores de stop-loss e take-profit. Podemos adicionar esses valores ao código junto com outras variáveis, ou podemos adicioná-los usando outra ação, conforme mostrado na próxima seção.
Adicionando stop-loss e take-profit:
Quando precisamos adicionar stop-loss e take-profit, atribuímos TRADE_ACTION_SLTP à variável action, como mostrado no exemplo a seguir.
request.action = TRADE_ACTION_SLTP; //adding sl and tp request.symbol = _Symbol; //applied for the cuurrent symbol request.sl = 1.07000; //sl price request.sl = 1.09000; //tp price OrderSend(request, result); //calling the OrderSend function
Ordem pendente:
Se quisermos colocar uma ordem pendente, podemos usar outra ação (TRADE_ACTION_PENDING). Em seguida, definimos o tipo de ordem. Podemos definir um tempo se precisarmos de um tempo de expiração para a ordem pendente.
request.action = TRADE_ACTION_PENDING; //pending order placement request.type = ORDER_TYPE_BUY_STOP; //type of order is buy stop request.symbol = _Symbol; //applied for the cuurrent symbol request.volume = 0.1; //the lot size request.price = 1.07000; //opening price request.sl = 1.06950; //stop loss request.tp = 1.07100; //take profit request.type_time = ORDER_TIME_SPECIFIED; //to set an expiration time request.expiration = D'2023.08.31 00.00'; //expiration time - datetime constant request.type_filling = ORDER_FILLING_FOK; //the filling policy fill or kill request.stoplimit = 0; //for stoplimit order only OrderSend(request, result); //calling the OrderSend function
Modificação de ordem pendente:
Ao modificar uma ordem pendente, precisamos obter o número do seu ticket. Para isso, podemos usar a função OrderGetTicket. Essa função retorna o ticket da ordem correspondente, ticket esse com o qual podemos selecionar a ordem e trabalhar com ela.
ulong OrderGetTicket( int index // Number in the list of orders );
Suponhamos que temos uma variável 'ticket' que contém o ticket da ordem. Podemos usar essa variável para atribuir um ticket de ordem à variável de ordem do objeto-solicitação. Então, podemos modificar a ordem usando a ação (TRADE_ACTION_MODIFY), como no exemplo a seguir.
request.action = TRADE_ACTION_MODIFY; //pending order modyfying request.order = ticket; //ticket variable that holds the pending order ticket to modify request.price = 1.07050; //new opening price request.sl = 1.07000; //new stop loss request.tp = 1.07150; //new take profit request.type_time = ORDER_TIME_SPECIFIED; //to set an expiration time request.expiration = D'2023.09.01 00.00'; //new expiration time - datetime constant OrderSend(request, result); //calling the OrderSend function
Remoção de ordem pendente:
Se precisarmos remover uma ordem pendente, podemos fazer isso com a ação (TRADE_ACTION_REMOVE). Também precisaremos do número do ticket da ordem pendente que queremos remover. Podemos usar o ticket da variável sabendo que ele contém o número do ticket necessário.
request.action = TRADE_ACTION_REMOVE; //pending order remove request.order = ticket; //ticket variable that holds the pending order ticket to remove OrderSend(request, result); //calling the OrderSend function
Estrutura mqltraderesult:
A estrutura MqlTradeResult retorna o resultado da execução da ordem após seu posicionamento pela função OrderSend(). Ela contém informações do servidor de negociação, como o número do ticket, volume e preço.
Veja a seguir como é definida a estrutura MqlTradeResult:
struct MqlTradeResult { uint retcode; // Operation return code ulong deal; // Deal ticket, if it is performed ulong order; // Order ticket, if it is placed double volume; // Deal volume, confirmed by broker double price; // Deal price, confirmed by broker double bid; // Current Bid price double ask; // Current Ask price string comment; // Broker comment to operation (by default it is filled by description of trade server return code) uint request_id; // Request ID set by the terminal during the dispatch int retcode_external; // Return code of an external trading system };
Podemos declarar um objeto chamado result e passá-lo como segundo parâmetro após o primeiro (request) ao chamar a função OrderSend().
MqlTradeResult result;
Como podemos ver nas variáveis da estrutura MqlTradeResult, a variável retcode é muito importante, pois ela retorna um código do servidor de negociação para indicar se o pedido foi bem-sucedido.
Se a negociação não for colocada, o código de retorno indica um erro. Você pode consultar a lista de códigos de retorno na documentação do MQL5. É extremamente importante incluir em nosso sistema de negociação um código que reporte se um erro foi retornado ou não, como mostrado no exemplo a seguir:
if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED) { Print("Trade Placed Successfully"); } else { Print("Trade Not Placed, Error ", result.retcode); }
Como podemos ver, após a solicitação, é exibida uma mensagem com o resultado, e são preenchidas as variáveis de resultado. Ao abrir uma negociação, receberemos uma mensagem e, se houver algum problema, um código de erro nos será enviado.
Uso do OrderSend()
Precisamos criar um sistema de negociação simples que possa executar negociações usando a função OrderSend(). Esse sistema de negociação envolve um simples cruzamento de média móvel e a ação é apenas colocar uma ordem a mercado.
O objetivo aqui é entender as diferenças ao criar o mesmo sistema de negociação usando OrderSend() e a classe CTrade. Abaixo temos as etapas para criar um cruzamento MA usando a função OrderSend().
Criamos duas variáveis inteiras (simpleMA, barTotal) no escopo global, sem atribuição. Essa atribuição será feita mais tarde, no OnInit.
int simpleMA; int barsTotal;
SimpleMA será atribuída à função iMA, que retorna o handle do indicador técnico de média móvel. Os parâmetros são os seguintes:
- symbol - nome do símbolo, _Símbolo representa o instrumento atual.
- period - timeframe. Usaremos PERIOD_H1 - timeframe de uma hora.
- ma_period - período da média móvel. Utilizaremos 50.
- ma_shift - deslocamento horizontal.
- ma_method - tipo de média móvel. Especificaremos uma média simples.
- applied_price - tipo de preço para o cálculo da média móvel. Usaremos o preço de fechamento.
BarsTotal será atribuído pela função iBars, que retorna o número de barras. Parâmetros:
- symbol - nome do símbolo
- timeframe - período do timeframe
simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,PERIOD_H1);
No OnTick(), criaremos dois arrays: um para os preços, usando MqlRates para armazenar informações sobre preços, volumes e spreads, e outro para a média móvel do tipo double
MqlRates priceArray[]; double mySMAArray[];
Determinação dos preços de Ask e Bid
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
Criaremos dois objetos para a função OrderSend(): um para request usando MqlTradeRequest e outro para result usando MqlTradeResult, e então reiniciaremos a variável request por referência.
ZeroMemory(request);
Definimos o flag AS_SERIES para os dois arrays criados priceArray e mySMAArray, usando a função ArraySetAsSeries. Parâmetros:
- array[] - o array necessário
- flag - direção da indexação do array.
ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true);
Obtemos dados históricos MqlRates com a função CopyRates. Parâmetros:
- symbol - nome do símbolo ou _Symbol para o símbolo ou instrumento atual.
- time frame - timeframe ou _period para o timeframe atual.
- start position - posição de início.
- count - quantidade de dados para copiar.
- rates_array - array de destino para a cópia.
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
Obtemos o buffer de dados do indicador com a função CopyBuffer. Parâmetros:
- indicator_handle - handle do indicador (MA).
- buffer_num - número do buffer do indicador.
- start_pos - posição de início do cálculo.
- count - quantidade para copiar.
- buffer[] - array de destino.
CopyBuffer(simpleMA,0,0,3,mySMAArray);
Determinamos do último e do penúltimo preço de fechamento, e dos últimos e penúltimos valores de SMA
double lastClose=(priceArray[1].close); double prevClose=(priceArray[2].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
Criamos uma variável inteira chamada bar e a atribuiremos a iBars.
int bars=iBars(_Symbol,PERIOD_H1);
Verificamos se barsTotal e a variável bars são iguais
if(barsTotal != bars)
Atualizamos o valor de barsTotal para que seja igual a bars, se eles não forem iguais.
barsTotal=bars;
Verificamos a condição da estratégia para abrir uma negociação: se o último fechamento for maior que o último valor da SMA após o fechamento anterior ter sido menor que o valor anterior da SMA
if(prevClose<prevSMAVal && lastClose>SMAVal)
Abrimos uma ordem a mercado de compra usando as variáveis adequadas relacionadas à função MqlTradeRequest.
request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_BUY; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); request.sl = Ask-(500*_Point); request.tp = Ask+(1000*_Point); request.deviation = 50; OrderSend(request, result);
Verificamos a condição da estratégia para abrir uma negociação de venda: se o último fechamento for menor que o último valor da SMA após o fechamento anterior ter sido maior que o valor anterior da SMA
if(prevClose>prevSMAVal && lastClose<SMAVal)
Abrimos uma ordem a mercado de venda usando as variáveis adequadas relacionadas à função MqlTradeRequest. request.type = ORDER_TYPE_SELL; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID); request.sl = Bid+(500*_Point); request.tp = Bid-(1000*_Point); request.deviation = 50; OrderSend(request, result);
Segue o código completo para criar este tipo de sistema de negociação usando a função OrderSend().
//+------------------------------------------------------------------+ //| OrderSend_Trading_system.mq5 | //+------------------------------------------------------------------+ int simpleMA; int barsTotal; int OnInit() { simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,PERIOD_H1); return(INIT_SUCCEEDED); } void OnTick() { MqlRates priceArray[]; double mySMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true); int Data=CopyRates(_Symbol,_Period,0,3,priceArray); CopyBuffer(simpleMA,0,0,3,mySMAArray); double lastClose=(priceArray[1].close); double prevClose=(priceArray[2].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits); int bars=iBars(_Symbol,PERIOD_H1); if(barsTotal != bars) { barsTotal=bars; if(prevClose<prevSMAVal && lastClose>SMAVal) { request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_BUY; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK); request.sl = Ask-(500*_Point); request.tp = Ask+(1000*_Point); request.deviation = 50; OrderSend(request, result); } if(prevClose>prevSMAVal && lastClose<SMAVal) { request.action = TRADE_ACTION_DEAL; request.type = ORDER_TYPE_SELL; request.symbol = _Symbol; request.volume = 0.1; request.type_filling = ORDER_FILLING_FOK; request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID); request.sl = Bid+(500*_Point); request.tp = Bid-(1000*_Point); request.deviation = 50; OrderSend(request, result); } } }
Classe CTrade
Aprendemos a colocar ordens usando a função OrderSend() e encontramos uma maneira fácil de acessar as funções de negociação. Podemos usar a classe CTrade pronta que o MQL5 traz ou criar a nossa própria classe. Como posso usar a classe CTrade pronta no MQL5? Você pode encontrar mais informações na seção CTrade da documentação do MQL5.
Primeiramente, podemos encontrar o arquivo de classe CTrade na pasta Trade da pasta include nos arquivos de instalação do MetaTrader 5. Tudo o que precisamos fazer é incluir esse arquivo no Expert Advisor para chamar e usar todas as funções de negociação, conforme indicado abaixo:
#include <Trade\Trade.mqh>
Criamos um objeto da classe CTrade.
CTrade trade;
Após isso, poderemos usar todas as funções de negociação na classe CTrade, usando trade seguido de ponto (.) e a função desejada. Podemos usar todas as funções de operações com ordens e posições, acesso aos parâmetros do último pedido, resultados de verificação e execução do último pedido e outros.
Mencionaremos algumas funções importantes da mesma forma que com OrderSend(), para entender as diferenças entre os dois métodos. Vamos entender como realizar o seguinte:
- Ordem a mercado
- Adição de stop-loss e take-profit
- Ordem pendente
- Modificação de ordem pendente
- Remoção de ordem pendente
Ordem a mercado:
Depois de criar nosso objeto de negociação, podemos usar a função PositionOpen para colocar uma ordem a mercado, com os seguintes parâmetros:
- symbol - símbolo necessário
- order_type - tipo de ordem para abrir a posição
- volume - tamanho do lote
- price - preço de abertura da posição
- sl - preço do stop-loss
- tp - preço do take-profit
- comment - comentário ou NULL
Veja a seguir um exemplo:
trade.PositionOpen( _Symbol, //to be applied for the current symbol ORDER_TYPE_BUY, //to place buy order 0.1, //lot size or volume Ask, //opening price of the order - current ask Ask-(500*_Point), //sl Ask+(1000*_Point), //tp NULL //NULL );
Para abrir uma ordem a mercado, também podemos usar métodos adicionais em CTrade, como Buy ou Sell, em vez de PositionOpen.
Adicionando stop-loss e take-profit:
Podemos modificar uma posição por símbolo ou número de ticket usando a função PositionModify, com os parâmetros:
- symbol or ticket - ao modificar a posição por símbolo, especificamos o símbolo; ao modificar por ticket, especificamos o número do ticket.
- sl - novo preço do stop-loss
- tp - preço do take-profit
Exemplo de modificação conforme o símbolo:
trade.PositionModify( EURUSD, //the symbol name 1.06950, //the new sl 1.07100, //the new tp );
Exemplo de mudança com base no ticket:
trade.PositionModify( ticket, //the ticket variable that holds the needed ticket number to modify 1.06950, //the new sl 1.07100, //the new tp );
Ordem pendente:
Se precisarmos colocar uma ordem pendente usando a classe CTrade, podemos usar a função OrderOpen. Parâmetros:
- symbol - nome do símbolo
- order_type - tipo da ordem pendente
- volume - tamanho do lote
- limit_price - preço do stop limit
- price - preço de execução da ordem pendente
- sl - stop-loss
- tp - take-profit
- type_time - tipo de expiração
- expiration - variável de data e hora de expiração
- comment - comentário
No exemplo a seguir, mostramos como colocar uma ordem pendente de compra usando a função OrderOpen.
trade.OrderOpen( "EURUSD", // symbol ORDER_TYPE_BUY_LIMIT, // order type 0.1, // order volume 0, // StopLimit price 1.07000, // execution price 1.06950, // Stop Loss price 1.07100, // Take Profit price ORDER_TIME_SPECIFIED, // type by expiration D'2023.08.31 00.00', // expiration "" // comment );
Modificação de ordem pendente:
Se precisarmos modificar uma ordem pendente colocada, podemos fazer isso usando a classe CTrade com a função OrderModify. Parâmetros:
- ticket - ticket da ordem pendente que precisa ser modificado
- price - novo preço de execução
- sl - novo preço do stop-loss
- tp - novo preço do take-profit
- type_time - tipo de expiração
- expiration - variável de data e hora de expiração
- stoplimit - preço do limite da ordem
Abaixo está um exemplo de modificação de uma ordem pendente
trade.OrderModify( ticket, // ticket number of the pending order to modify 1.07050, // execution price 1.07000, // Stop Loss price 1.07150, // Take Profit price ORDER_TIME_SPECIFIED, // type by expiration D'2023.08.31 00.00', // expiration 0, // StopLimit price );
Remoção de ordem pendente:
Se você precisar remover uma ordem pendente, poderá fazê-lo usando a função OrderDelete. O número do ticket da ordem pendente é necessário para removê-la. Veja abaixo um exemplo dessa função.
trade.OrderDelete(
ticket, // tick number of the pending order to delete
);
Uso da classe CTrade
Vamos criar o mesmo sistema de negociação que criamos com OrderSend(). Usaremos a classe CTrade para entender as diferenças no funcionamento das funções.
Abaixo estão os únicos passos distintos necessários para criar um sistema de negociação usando a classe CTrade. O restante dos passos é igual ao discutido acima.
Incluímos o arquivo Trade com o pré-processador #include
#include <Trade\Trade.mqh>
Criamos um objeto de negociação da classe CTrade.
CTrade trade;
Ao satisfazer a condição de compra, usamos PositionOpen, o tipo de ordem será ORDER_TYPE_BUY ou um método adicional de compra, como no código a seguir.
trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
Ao satisfazer a condição de venda, usamos PositionOpen junto com o tipo de ordem ORDER_TYPE_SELL ou um método adicional de venda, conforme mostrado no código a seguir.
trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
Segue o código completo para criar um sistema de negociação usando a classe CTrade:
//+------------------------------------------------------------------+ //| CTrade_Trading_System.mq5 | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> int simpleMA; int barsTotal; CTrade trade; int OnInit() { simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE); barsTotal=iBars(_Symbol,PERIOD_H1); return(INIT_SUCCEEDED); } void OnTick() { MqlRates priceArray[]; double mySMAArray[]; double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); ArraySetAsSeries(priceArray,true); ArraySetAsSeries(mySMAArray,true); int Data=CopyRates(_Symbol,_Period,0,3,priceArray); CopyBuffer(simpleMA,0,0,3,mySMAArray); double lastClose=(priceArray[1].close); double prevClose=(priceArray[2].close); double SMAVal = NormalizeDouble(mySMAArray[1],_Digits); double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits); int bars=iBars(_Symbol,PERIOD_H1); if(barsTotal != bars) { barsTotal=bars; if(prevClose<prevSMAVal && lastClose>SMAVal) { trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL); } if(prevClose>prevSMAVal && lastClose<SMAVal) { trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL); } } }
Conclusão
Exploramos como funcionam as ordens, as posições e as negociações no MQL5 e vimos como criar um sistema de negociação usando dois métodos usados nas operações de negociação: OrderSend e CTrade.
Também definimos como colocar ordens a mercado e pendentes, adicionar stop-loss e take-profit, modificar ordens pendentes e remover ordens pendentes usando esses dois métodos.
Além disso, analisamos dois casos simples para criar o mesmo sistema de negociação de cruzamento de média móvel usando ambos os métodos.
- OpenSend_Trading_System
- CTrade_Trading_System
O objetivo desses aplicativos é somente dar a você uma noção prática das diferenças entre eles, por isso, tome cuidado: você deve testá-los antes de usá-los em qualquer conta real para ter certeza de que são lucrativos e adequados para fazer suas operações.
Creio que você já percebeu como é fácil usar a classe CTrade pronta ao trabalhar com operações de negociação. Ela economiza muito tempo e esforço, sem contar outros recursos de classe na programação em geral.
Se quiser saber mais sobre programação orientada a objetos no MQL5, leia meu artigo anterior "Programação orientada a objetos (OOP) em MQL5". Espero que ele seja útil para você. MQL5 fornece as ferramentas necessárias para o desenvolvimento simples e eficaz de aplicativos de negociação.
Espero que este artigo seja útil para você e ajude a alcançar seus objetivos de negociação. Na seção "Artigos" do meu perfil, você pode encontrar uma série de artigos sobre a criação de sistemas de negociação baseados nos indicadores técnicos mais populares. Espero que eles também sejam úteis.
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/13229
- 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