356 lines
No EOL
13 KiB
MQL4
356 lines
No EOL
13 KiB
MQL4
//+------------------------------------------------------------------+
|
|
//| EURUSD_Scalper.mq4 |
|
|
//| Copyright 2024, Forex Robot |
|
|
//| https://www.forex.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024, Forex Robot"
|
|
#property link "https://www.forex.com"
|
|
#property version "2.00"
|
|
#property strict
|
|
|
|
//--- Parâmetros de entrada para HFT M1
|
|
extern double LotSize = 0.01; // Tamanho do lote (menor para HFT)
|
|
extern int StopLoss = 10; // Stop Loss em pips (mais apertado)
|
|
extern int TakeProfit = 15; // Take Profit em pips (1.5x o stop)
|
|
extern int MA_Fast = 5; // Média móvel rápida (mais sensível)
|
|
extern int MA_Slow = 10; // Média móvel lenta (mais sensível)
|
|
extern int RSI_Period = 7; // Período do RSI (mais rápido)
|
|
extern int RSI_Overbought = 75; // Nível de sobrecompra (mais restritivo)
|
|
extern int RSI_Oversold = 25; // Nível de sobrevenda (mais restritivo)
|
|
extern int MinDistance = 5; // Distância mínima do spread em pips
|
|
extern bool UseTrailingStop = true; // Usar trailing stop (ativo por padrão)
|
|
extern int TrailingStop = 5; // Trailing stop em pips (mais apertado)
|
|
extern int MagicNumber = 12345; // Número mágico para identificação
|
|
extern int MaxOrders = 3; // Máximo de ordens simultâneas
|
|
extern int MinBarsAfterTrade = 3; // Mínimo de barras entre trades
|
|
extern bool UseSpeedFilter = true; // Usar filtro de velocidade do preço
|
|
extern double MinPriceSpeed = 0.0003; // Velocidade mínima do preço (pips por tick)
|
|
extern bool UseVolumeFilter = false; // Usar filtro de volume (se disponível)
|
|
|
|
//--- Variáveis globais
|
|
double g_point;
|
|
int g_digits;
|
|
datetime g_lastBarTime = 0;
|
|
datetime g_lastTradeTime = 0;
|
|
double g_lastPrice = 0;
|
|
int g_consecutiveLosses = 0;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
// Configurações básicas
|
|
g_digits = (int)MarketInfo(Symbol(), MODE_DIGITS);
|
|
g_point = MarketInfo(Symbol(), MODE_POINT);
|
|
|
|
// Ajustar para 5 dígitos (alguns brokers)
|
|
if(g_digits == 3 || g_digits == 5)
|
|
g_point *= 10;
|
|
|
|
// Verificar se o símbolo é EUR/USD
|
|
if(StringFind(Symbol(), "EURUSD") < 0)
|
|
{
|
|
Print("ERRO: Este robô foi projetado para EUR/USD apenas!");
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
// Verificar se o timeframe é M1
|
|
if(Period() != PERIOD_M1)
|
|
{
|
|
Print("ERRO: Este robô foi projetado para timeframe M1 apenas!");
|
|
return(INIT_FAILED);
|
|
}
|
|
|
|
g_lastPrice = Close[0];
|
|
|
|
Print("EURUSD HFT Scalper M1 inicializado com sucesso!");
|
|
Print("Stop Loss: ", StopLoss, " pips");
|
|
Print("Take Profit: ", TakeProfit, " pips");
|
|
Print("Média Móvel Rápida: ", MA_Fast);
|
|
Print("Média Móvel Lenta: ", MA_Slow);
|
|
Print("Máximo de ordens: ", MaxOrders);
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
Print("EURUSD HFT Scalper finalizado. Razão: ", reason);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
// Para HFT, verificamos a cada tick, não apenas em nova barra
|
|
|
|
// Verificar se há ordens abertas e gerenciar
|
|
if(CountOpenOrders() > 0)
|
|
{
|
|
if(UseTrailingStop)
|
|
ManageTrailingStop();
|
|
ManageOpenOrders();
|
|
return;
|
|
}
|
|
|
|
// Verificar se passou tempo mínimo desde último trade
|
|
if(TimeCurrent() - g_lastTradeTime < MinBarsAfterTrade * 60)
|
|
return;
|
|
|
|
// Verificar se já temos muitas ordens
|
|
if(CountOpenOrders() >= MaxOrders)
|
|
return;
|
|
|
|
// Verificar filtro de velocidade se ativado
|
|
if(UseSpeedFilter && !CheckPriceSpeed())
|
|
return;
|
|
|
|
// Verificar condições de entrada a cada tick
|
|
int signal = GetSignalHFT();
|
|
|
|
if(signal == 1) // Sinal de compra
|
|
{
|
|
OpenBuyOrder();
|
|
}
|
|
else if(signal == -1) // Sinal de venda
|
|
{
|
|
OpenSellOrder();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Verificar velocidade do preço para HFT |
|
|
//+------------------------------------------------------------------+
|
|
bool CheckPriceSpeed()
|
|
{
|
|
double currentPrice = (Ask + Bid) / 2;
|
|
double priceChange = MathAbs(currentPrice - g_lastPrice);
|
|
g_lastPrice = currentPrice;
|
|
|
|
return (priceChange >= MinPriceSpeed * g_point);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 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)
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Obter sinal de entrada otimizado para HFT |
|
|
//+------------------------------------------------------------------+
|
|
int GetSignalHFT()
|
|
{
|
|
// Calcular médias móveis com períodos mais curtos
|
|
double ma_fast_0 = iMA(Symbol(), Period(), MA_Fast, 0, MODE_EMA, PRICE_CLOSE, 0);
|
|
double ma_slow_0 = iMA(Symbol(), Period(), MA_Slow, 0, MODE_EMA, PRICE_CLOSE, 0);
|
|
double ma_fast_1 = iMA(Symbol(), Period(), MA_Fast, 0, MODE_EMA, PRICE_CLOSE, 1);
|
|
double ma_slow_1 = iMA(Symbol(), Period(), MA_Slow, 0, MODE_EMA, PRICE_CLOSE, 1);
|
|
|
|
// Calcular RSI atual
|
|
double rsi = iRSI(Symbol(), Period(), RSI_Period, PRICE_CLOSE, 0);
|
|
|
|
// Verificar momentum das médias móveis
|
|
bool ma_fast_rising = ma_fast_0 > ma_fast_1;
|
|
bool ma_fast_falling = ma_fast_0 < ma_fast_1;
|
|
|
|
// Verificar cruzamento das médias
|
|
bool bullish_cross = (ma_fast_0 > ma_slow_0) && (ma_fast_1 <= ma_slow_1);
|
|
bool bearish_cross = (ma_fast_0 < ma_slow_0) && (ma_fast_1 >= ma_slow_1);
|
|
|
|
// Verificar condições de preço
|
|
double current_price = (Ask + Bid) / 2;
|
|
bool price_above_ma = current_price > ma_fast_0;
|
|
bool price_below_ma = current_price < ma_fast_0;
|
|
|
|
// Condições de entrada para compra (mais agressivas para HFT)
|
|
if((bullish_cross || (ma_fast_0 > ma_slow_0 && ma_fast_rising && price_above_ma)) &&
|
|
rsi > 30 && rsi < RSI_Overbought)
|
|
{
|
|
return 1; // Sinal de compra
|
|
}
|
|
|
|
// Condições de entrada para venda (mais agressivas para HFT)
|
|
if((bearish_cross || (ma_fast_0 < ma_slow_0 && ma_fast_falling && price_below_ma)) &&
|
|
rsi < 70 && rsi > RSI_Oversold)
|
|
{
|
|
return -1; // Sinal de venda
|
|
}
|
|
|
|
return 0; // Sem sinal
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Abrir ordem de compra |
|
|
//+------------------------------------------------------------------+
|
|
void OpenBuyOrder()
|
|
{
|
|
double price = Ask;
|
|
double sl = price - StopLoss * g_point;
|
|
double tp = price + TakeProfit * g_point;
|
|
|
|
// Verificar spread
|
|
double spread = (Ask - Bid) / g_point;
|
|
if(spread > MinDistance)
|
|
{
|
|
Print("Spread muito alto (", spread, " pips) para entrada de compra");
|
|
return;
|
|
}
|
|
|
|
// Ajustar lote baseado em perdas consecutivas (opcional)
|
|
double adjustedLot = LotSize;
|
|
if(g_consecutiveLosses >= 3)
|
|
adjustedLot = LotSize * 0.5; // Reduzir lote após perdas
|
|
|
|
int ticket = OrderSend(Symbol(), OP_BUY, adjustedLot, price, 3, sl, tp,
|
|
"HFT Scalper Buy", MagicNumber, 0, clrGreen);
|
|
|
|
if(ticket > 0)
|
|
{
|
|
g_lastTradeTime = TimeCurrent();
|
|
Print("Ordem de compra HFT: Ticket #", ticket, " Preço: ", price,
|
|
" SL: ", sl, " TP: ", tp, " Spread: ", spread, " pips");
|
|
}
|
|
else
|
|
{
|
|
Print("Erro ao abrir ordem de compra: ", GetLastError());
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Abrir ordem de venda |
|
|
//+------------------------------------------------------------------+
|
|
void OpenSellOrder()
|
|
{
|
|
double price = Bid;
|
|
double sl = price + StopLoss * g_point;
|
|
double tp = price - TakeProfit * g_point;
|
|
|
|
// Verificar spread
|
|
double spread = (Ask - Bid) / g_point;
|
|
if(spread > MinDistance)
|
|
{
|
|
Print("Spread muito alto (", spread, " pips) para entrada de venda");
|
|
return;
|
|
}
|
|
|
|
// Ajustar lote baseado em perdas consecutivas (opcional)
|
|
double adjustedLot = LotSize;
|
|
if(g_consecutiveLosses >= 3)
|
|
adjustedLot = LotSize * 0.5; // Reduzir lote após perdas
|
|
|
|
int ticket = OrderSend(Symbol(), OP_SELL, adjustedLot, price, 3, sl, tp,
|
|
"HFT Scalper Sell", MagicNumber, 0, clrRed);
|
|
|
|
if(ticket > 0)
|
|
{
|
|
g_lastTradeTime = TimeCurrent();
|
|
Print("Ordem de venda HFT: Ticket #", ticket, " Preço: ", price,
|
|
" SL: ", sl, " TP: ", tp, " Spread: ", spread, " pips");
|
|
}
|
|
else
|
|
{
|
|
Print("Erro ao abrir ordem de venda: ", GetLastError());
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Gerenciar ordens abertas |
|
|
//+------------------------------------------------------------------+
|
|
void ManageOpenOrders()
|
|
{
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
// Verificar se a ordem está em lucro mínimo para fechar rápido
|
|
double currentProfit = OrderProfit();
|
|
|
|
if(OrderType() == OP_BUY)
|
|
{
|
|
double currentPrice = Bid;
|
|
double pipProfit = (currentPrice - OrderOpenPrice()) / g_point;
|
|
|
|
// Fechar rapidamente se tiver lucro mínimo (para HFT)
|
|
if(pipProfit >= 5)
|
|
{
|
|
if(OrderClose(OrderTicket(), OrderLots(), currentPrice, 3, clrBlue))
|
|
{
|
|
Print("Ordem de compra fechada com lucro rápido: ", pipProfit, " pips");
|
|
g_consecutiveLosses = 0;
|
|
}
|
|
}
|
|
}
|
|
else if(OrderType() == OP_SELL)
|
|
{
|
|
double currentPrice = Ask;
|
|
double pipProfit = (OrderOpenPrice() - currentPrice) / g_point;
|
|
|
|
// Fechar rapidamente se tiver lucro mínimo (para HFT)
|
|
if(pipProfit >= 5)
|
|
{
|
|
if(OrderClose(OrderTicket(), OrderLots(), currentPrice, 3, clrBlue))
|
|
{
|
|
Print("Ordem de venda fechada com lucro rápido: ", pipProfit, " pips");
|
|
g_consecutiveLosses = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Gerenciar trailing stop otimizado para HFT |
|
|
//+------------------------------------------------------------------+
|
|
void ManageTrailingStop()
|
|
{
|
|
for(int i = 0; i < OrdersTotal(); i++)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
if(OrderType() == OP_BUY)
|
|
{
|
|
double newSL = Bid - TrailingStop * g_point;
|
|
if(newSL > OrderStopLoss() + g_point && newSL < Bid - g_point)
|
|
{
|
|
bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrBlue);
|
|
if(result)
|
|
Print("Trailing Stop atualizado para compra: ", newSL);
|
|
}
|
|
}
|
|
else if(OrderType() == OP_SELL)
|
|
{
|
|
double newSL = Ask + TrailingStop * g_point;
|
|
if((newSL < OrderStopLoss() - g_point || OrderStopLoss() == 0) && newSL > Ask + g_point)
|
|
{
|
|
bool result = OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrBlue);
|
|
if(result)
|
|
Print("Trailing Stop atualizado para venda: ", newSL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |