MetaTrader4
Criando um EA de Cruzamento de Médias Móveis no MetaTrader 4
Vamos começar a criar esse EA (Expert Advisor) definindo as variáveis de entrada.
//--- parâmetros de entrada
input int periodo_ma_rapida = 8; // Período da Média Móvel Rápida
input int periodo_ma_lenta = 20; // Período da Média Móvel Lenta
input double takeProfit = 20.0; // Take Profit (pips)
input double stopLoss = 20.0 // Stop Loss (pips)
input double tamanhoLote = 0.10; // Tamanho do Lote
input double minimoEquity = 100.0; // Mínimo Equity ($)
input int slippage = 3; // Slippage
input int numeroMagico = 889; // Número Mágico
Agora, vamos definir as variáveis globais. Essas variáveis com escopo global estarão disponíveis em todas as funções.
// Variáveis Globais
double meuPonto = 0.0;
int minhaSlippage = 0;
int CompraTicket = 0;
int VendaTicket = 0;
Quando o EA é executado, a primeira função chamada é a OnInit(). Usamos essa função para validar e inicializar as variáveis globais que serão utilizadas.
int OnInit()
{
// validação das entradas, sempre valide ao inicializar dados de entrada
if (periodo_ma_rapida >= periodo_ma_lenta || takeProfit < 0.0 || stopLoss < 0.0 || tamanhoLote < 0.01 || minimoEquity < 10){
Alert("ATENÇÃO - Dados de entrada não são válidos");
return (INIT_PARAMETERS_INCORRECT);
}
double volume_minimo=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
if(tamanhoLote<volume_minimo)
{
string mensagem =StringFormat("Volume menor que o permitido de %.2f",volume_minimo);
Alert (mensagem);
return(INIT_PARAMETERS_INCORRECT);
}
meuPonto = GetPipPoint(Symbol());
minhaSlippage = GetSlippage(Symbol(),slippage);
return(INIT_SUCCEEDED);
}
Quando o preço do mercado se move (tick), a função OnTick() será chamada e executará todas as instruções contidas nesse bloco.
Dentro da função OnTick(), chamaremos várias outras funções.
Começamos chamando a função checkMinEquity() para controlar a adequação do equity para operações. Se o equity for suficiente (acima do mínimo), continuamos com a declaração da variável de sinal e chamamos a função NewCandle(), que informa quando uma nova vela é formada.
A função getSignal() irá ler os valores nos dois indicadores de média móvel e retornar a informação sobre um cruzamento, seja para compra ou venda.
Com base nessa informação de sinal, ela será encaminhada para a função transaction(), que definirá as posições de compra ou venda.
Depois, chamamos a função setTPSL(), que serve para definir os preços de take profit e stop loss.Se o equity não atender ao requisito mínimo, um alerta será exibido e o EA será encerrado.
void OnTick()
{
if (checkMinEquity()){
int sinal = -1;
bool novaCandle = NewCandle(Period(), Symbol());
sinal = getSignal(novaCandle);
transaction(novaCandle, sinal);
setTPSL();
}else{
// Parar a operação, pois o equity não é suficiente
Print("EA será encerrado pois o equity é insuficiente");
}
}
A função para setTPSL()
void setTPSL(){
int ordemTotal = 0;
string strMN = "", par = "";
double sl = 0.0, tp = 0.0;
par = Symbol();
ordemTotal = OrdersTotal();
for (int i=ordemTotal-1; i>=0; i--){
bool hrsSelect = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
strMN = IntegerToString(OrderMagicNumber());
if (StringFind(strMN, IntegerToString(numeroMagico), 0) == 0 && StringFind(OrderSymbol(), par, 0) == 0 ){
if (OrderType() == OP_BUY && (OrderTakeProfit() == 0 || OrderStopLoss() == 0) ){
if (takeProfit > 0) {
tp = OrderOpenPrice() + (takeProfit * meuPonto);
}else{
tp = OrderOpenPrice();
}
if (stopLoss > 0) {
sl = OrderOpenPrice() - (stopLoss * meuPonto);
}else{
sl = OrderStopLoss();
}
if (OrderTakeProfit() != tp || OrderStopLoss() != sl ){
if(OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrBlue)){
Print ("Modificação da Ordem Bem Sucedida");
}
}
}
if (OrderType() == OP_SELL && (OrderTakeProfit() == 0 || OrderStopLoss() == 0) ){
if (takeProfit > 0) {
tp = OrderOpenPrice() - (takeProfit * meuPonto);
}else{
tp = OrderOpenPrice();
}
if (stopLoss > 0) {
sl = OrderOpenPrice() + (stopLoss * meuPonto);
}else{
sl = OrderStopLoss();
}
if (OrderTakeProfit() != tp || OrderStopLoss() != sl ){
if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrRed)){
Print ("Modificação da Ordem Bem Sucedida");
}
}
}
}// fim do if número mágico && par
}// fim do for
}
Para educação e compartilhamento, junte-se ao nosso grupo no Telegram t.me/codeMQL
Se você está procurando um App para apoiar suas operações, baixe nosso aplicativo SignalForex na Play Store
https://play.google.com/store/apps/details?id=com.autobotfx.signalforex
2021.03.30