336 lines
11 KiB
MQL4
336 lines
11 KiB
MQL4
//+------------------------------------------------------------------+
|
|
//| XAU_USD_Scalper_M1.mq4 |
|
|
//| Copyright 2024, Forex Scalper Bot |
|
|
//| https://www.fbs.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024, Forex Scalper Bot"
|
|
#property link "https://www.fbs.com"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//--- Input Parameters
|
|
input double LotSize = 0.01; // Tamanho do lote
|
|
input int StopLoss = 15; // Stop Loss em pontos
|
|
input int TakeProfit = 45; // Take Profit em pontos
|
|
input int TrailingStop = 10; // Trailing Stop em pontos
|
|
input int MagicNumber = 12345; // Número mágico
|
|
input int MaxSpread = 30; // Spread máximo permitido (pontos)
|
|
input int MinDistance = 20; // Distância mínima entre ordens (pontos)
|
|
input bool UseTrailingStop = true; // Usar Trailing Stop
|
|
input bool UseBreakEven = true; // Usar Break Even
|
|
input int BreakEvenPoints = 10; // Pontos para ativar Break Even
|
|
input int MaxOrders = 1; // Máximo de ordens simultâneas
|
|
input int RSI_Period = 14; // Período do RSI
|
|
input int RSI_Overbought = 70; // Nível de sobrecompra RSI
|
|
input int RSI_Oversold = 30; // Nível de sobrevenda RSI
|
|
input int MA_Fast = 5; // Média móvel rápida
|
|
input int MA_Slow = 13; // Média móvel lenta
|
|
input int MA_Method = MODE_EMA; // Tipo de média móvel
|
|
|
|
//--- Global Variables
|
|
double g_point;
|
|
int g_digits;
|
|
datetime g_lastBarTime = 0;
|
|
int g_ticket = 0;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
// Configurações básicas
|
|
g_digits = (int)MarketInfo(Symbol(), MODE_DIGITS);
|
|
g_point = MarketInfo(Symbol(), MODE_POINT);
|
|
|
|
// Verificar se é XAU/USD
|
|
if(StringFind(Symbol(), "XAUUSD") < 0)
|
|
{
|
|
Print("Este EA foi projetado para XAU/USD. Símbolo atual: ", Symbol());
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
// Verificar timeframe
|
|
if(Period() != PERIOD_M1)
|
|
{
|
|
Print("Este EA foi projetado para timeframe M1. Timeframe atual: ", Period());
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
Print("XAU/USD Scalper M1 inicializado com sucesso!");
|
|
Print("Lot Size: ", LotSize);
|
|
Print("Stop Loss: ", StopLoss, " pontos");
|
|
Print("Take Profit: ", TakeProfit, " pontos");
|
|
Print("Spread máximo: ", MaxSpread, " pontos");
|
|
Print("Magic Number: ", MagicNumber);
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
Print("XAU/USD Scalper M1 finalizado. Razão: ", reason);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
// Verificar se é uma nova barra
|
|
if(g_lastBarTime == Time[0]) return;
|
|
g_lastBarTime = Time[0];
|
|
|
|
// Verificar spread
|
|
if(MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread)
|
|
{
|
|
Print("Spread muito alto: ", MarketInfo(Symbol(), MODE_SPREAD));
|
|
return;
|
|
}
|
|
|
|
// Verificar se já há ordens abertas
|
|
if(CountOpenOrders() >= MaxOrders) return;
|
|
|
|
// Verificar sinais de entrada
|
|
int signal = GetEntrySignal();
|
|
|
|
if(signal != 0)
|
|
{
|
|
OpenOrder(signal);
|
|
}
|
|
|
|
// Gerenciar ordens abertas
|
|
ManageOpenOrders();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para obter sinal de entrada |
|
|
//+------------------------------------------------------------------+
|
|
int GetEntrySignal()
|
|
{
|
|
double rsi = iRSI(Symbol(), Period(), RSI_Period, PRICE_CLOSE, 1);
|
|
double ma_fast = iMA(Symbol(), Period(), MA_Fast, 0, MA_Method, PRICE_CLOSE, 1);
|
|
double ma_slow = iMA(Symbol(), Period(), MA_Slow, 0, MA_Method, PRICE_CLOSE, 1);
|
|
double ma_fast_prev = iMA(Symbol(), Period(), MA_Fast, 0, MA_Method, PRICE_CLOSE, 2);
|
|
double ma_slow_prev = iMA(Symbol(), Period(), MA_Slow, 0, MA_Method, PRICE_CLOSE, 2);
|
|
|
|
// Sinal de compra
|
|
if(rsi < RSI_Oversold && ma_fast > ma_slow && ma_fast_prev <= ma_slow_prev)
|
|
{
|
|
return(1); // Compra
|
|
}
|
|
|
|
// Sinal de venda
|
|
if(rsi > RSI_Overbought && ma_fast < ma_slow && ma_fast_prev >= ma_slow_prev)
|
|
{
|
|
return(-1); // Venda
|
|
}
|
|
|
|
return(0); // Sem sinal
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para abrir ordem |
|
|
//+------------------------------------------------------------------+
|
|
void OpenOrder(int signal)
|
|
{
|
|
double price, sl, tp;
|
|
int cmd;
|
|
string comment;
|
|
|
|
if(signal == 1) // Compra
|
|
{
|
|
cmd = OP_BUY;
|
|
price = Ask;
|
|
sl = price - StopLoss * g_point;
|
|
tp = price + TakeProfit * g_point;
|
|
comment = "XAU Scalper Buy";
|
|
}
|
|
else if(signal == -1) // Venda
|
|
{
|
|
cmd = OP_SELL;
|
|
price = Bid;
|
|
sl = price + StopLoss * g_point;
|
|
tp = price - TakeProfit * g_point;
|
|
comment = "XAU Scalper Sell";
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Verificar distância mínima
|
|
if(!CheckMinDistance(price, cmd)) return;
|
|
|
|
g_ticket = OrderSend(Symbol(), cmd, LotSize, price, 3, sl, tp, comment, MagicNumber, 0, clrGreen);
|
|
|
|
if(g_ticket > 0)
|
|
{
|
|
Print("Ordem aberta: ", cmd == OP_BUY ? "Compra" : "Venda", " Ticket: ", g_ticket, " Preço: ", price);
|
|
}
|
|
else
|
|
{
|
|
Print("Erro ao abrir ordem: ", GetLastError());
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para verificar distância mínima |
|
|
//+------------------------------------------------------------------+
|
|
bool CheckMinDistance(double price, int cmd)
|
|
{
|
|
for(int i = 0; i < OrdersTotal(); i++)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
double orderPrice = OrderOpenPrice();
|
|
double distance = MathAbs(price - orderPrice) / g_point;
|
|
|
|
if(distance < MinDistance)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para contar ordens abertas |
|
|
//+------------------------------------------------------------------+
|
|
int CountOpenOrders()
|
|
{
|
|
int count = 0;
|
|
|
|
for(int i = 0; i < OrdersTotal(); i++)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() <= OP_SELL)
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para gerenciar ordens abertas |
|
|
//+------------------------------------------------------------------+
|
|
void ManageOpenOrders()
|
|
{
|
|
for(int i = 0; i < OrdersTotal(); i++)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
// Break Even
|
|
if(UseBreakEven && OrderTakeProfit() != 0)
|
|
{
|
|
ManageBreakEven();
|
|
}
|
|
|
|
// Trailing Stop
|
|
if(UseTrailingStop)
|
|
{
|
|
ManageTrailingStop();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para gerenciar Break Even |
|
|
//+------------------------------------------------------------------+
|
|
void ManageBreakEven()
|
|
{
|
|
double currentPrice = (OrderType() == OP_BUY) ? Bid : Ask;
|
|
double openPrice = OrderOpenPrice();
|
|
double profit = (OrderType() == OP_BUY) ? (currentPrice - openPrice) : (openPrice - currentPrice);
|
|
|
|
if(profit >= BreakEvenPoints * g_point)
|
|
{
|
|
double newSL = openPrice + (OrderType() == OP_BUY ? 2 * g_point : -2 * g_point);
|
|
|
|
if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrBlue))
|
|
{
|
|
Print("Break Even ativado para ticket: ", OrderTicket());
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para gerenciar Trailing Stop |
|
|
//+------------------------------------------------------------------+
|
|
void ManageTrailingStop()
|
|
{
|
|
double currentPrice = (OrderType() == OP_BUY) ? Bid : Ask;
|
|
double currentSL = OrderStopLoss();
|
|
double newSL;
|
|
|
|
if(OrderType() == OP_BUY)
|
|
{
|
|
newSL = currentPrice - TrailingStop * g_point;
|
|
if(newSL > currentSL + g_point)
|
|
{
|
|
if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrRed))
|
|
{
|
|
Print("Trailing Stop atualizado para compra: ", newSL);
|
|
}
|
|
}
|
|
}
|
|
else if(OrderType() == OP_SELL)
|
|
{
|
|
newSL = currentPrice + TrailingStop * g_point;
|
|
if(newSL < currentSL - g_point || currentSL == 0)
|
|
{
|
|
if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrRed))
|
|
{
|
|
Print("Trailing Stop atualizado para venda: ", newSL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Função para monitorar ordens executadas |
|
|
//+------------------------------------------------------------------+
|
|
void OnTrade()
|
|
{
|
|
// Esta função é chamada quando uma ordem é executada
|
|
// Monitora ordens fechadas e registra informações
|
|
static datetime lastCheckTime = 0;
|
|
|
|
if(TimeCurrent() != lastCheckTime)
|
|
{
|
|
lastCheckTime = TimeCurrent();
|
|
|
|
// Verificar ordens fechadas recentemente
|
|
for(int i = OrdersHistoryTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
if(OrderCloseTime() >= TimeCurrent() - 60) // Último minuto
|
|
{
|
|
string orderType = (OrderType() == OP_BUY) ? "Compra" : "Venda";
|
|
double profit = OrderProfit() + OrderSwap() + OrderCommission();
|
|
|
|
Print("Ordem fechada: ", orderType, " Ticket: ", OrderTicket(),
|
|
" Lucro: ", DoubleToStr(profit, 2), " USD");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|