Error invalid Stop Loss in my Expert Advisor

 
Good evening, I am trying to create my own expert advisor for the U.S. indices, I have implemented various controls and they seem to work well, such as whether a symbol is valid, whether the market is closed or open, the program shows me the moving averages and RSI correctly but when it tries to open any trade (either buy or sell) it returns this following error:

2024.07.22 18:09:04.749 TradingBotDanny (US500Cash,M1) CTrade::OrderSend: market sell 0.10 US500Cash sl: 5539.76 tp: 5539.31 [invalid stops].

I attach below my code:





//+------------------------------------------------------------------+
//|                                         ScalpingEAWithMarketCheck.mq5 |
//|                        Copyright 2024, Your Name                 |
//|                                        https://www.yourwebsite.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Your Name"
#property link      "https://www.yourwebsite.com"
#property version   "1.04"
#property strict

#include <Trade\Trade.mqh>

// Declaration of global variables
CTrade trade;
input int FastEMAPeriod = 9;                // Fast EMA period
input int SlowEMAPeriod = 21;               // Slow EMA period
input int RSIPeriod = 14;                   // RSI period
input double LotSize = 0.1;                 // Lot size
input double StopLossPips = 10.0;           // Stop Loss in pips
input double TakeProfitPips = 20.0;         // Take Profit in pips
input string TradingSymbols = "US500Cash,US30Cash"; // Symbols for trading
static datetime lastPrintTime = 0;
static double lastFastEMA = 0;
static double lastSlowEMA = 0;
static double lastRSI = 0;

// Handles for indicators
int FastEMAHandle;
int SlowEMAHandle;
int RSIHandle;

// Arrays for indicator values
double FastEMABuffer[];
double SlowEMABuffer[];
double RSIBuffer[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialization of indicator handles
    FastEMAHandle = iMA(_Symbol, PERIOD_CURRENT, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    SlowEMAHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    RSIHandle = iRSI(_Symbol, PERIOD_CURRENT, RSIPeriod, PRICE_CLOSE);
    
    if(FastEMAHandle == INVALID_HANDLE || SlowEMAHandle == INVALID_HANDLE || RSIHandle == INVALID_HANDLE)
    {
        Print("Error initializing indicators");
        return INIT_FAILED;
    }
    
    // Setting arrays as time series
    ArraySetAsSeries(FastEMABuffer, true);
    ArraySetAsSeries(SlowEMABuffer, true);
    ArraySetAsSeries(RSIBuffer, true);
    
    // Check if the current symbol is valid for trading
    if(!IsValidSymbol())
    {
        Print("Invalid symbol for trading: ", _Symbol);
        return INIT_FAILED;
    }
    
    if(!IsMarketOpen())
    {
        Print("Initialization completed, but the market is currently closed.");
    }
    else
    {
        Print("Initialization completed successfully. The market is open.");
    }
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    IndicatorRelease(FastEMAHandle);
    IndicatorRelease(SlowEMAHandle);
    IndicatorRelease(RSIHandle);
    Print("Expert Advisor deinitialized");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    if(!IsMarketOpen())
    {
        return;
    }
    
    if(!UpdateIndicators())
    {
        Print("Error updating indicators");
        return;
    }
    
    PrintIndicatorValues();
    
    if(PositionsTotal() == 0)
    {
        CheckAndOpenPosition();
    }
}

//+------------------------------------------------------------------+
//| Check if the current symbol is valid for trading                 |
//+------------------------------------------------------------------+
bool IsValidSymbol()
{
    string symbols[];
    StringSplit(TradingSymbols, ',', symbols);
    
    for(int i = 0; i < ArraySize(symbols); i++)
    {
        if(StringCompare(_Symbol, CustomTrim(symbols[i]), false) == 0)
        {
            return true;
        }
    }
    return false;
}

//+------------------------------------------------------------------+
//| Custom function to remove whitespace                             |
//+------------------------------------------------------------------+
string CustomTrim(string str)
{
    int start = 0;
    int end = StringLen(str) - 1;
    
    // Remove spaces at the beginning
    while(start <= end && StringGetCharacter(str, start) == ' ')
        start++;
    
    // Remove spaces at the end
    while(end >= start && StringGetCharacter(str, end) == ' ')
        end--;
    
    // Extract the substring without spaces
    return StringSubstr(str, start, end - start + 1);
}
static datetime lastAlertTime = 0;

//+------------------------------------------------------------------+
//| Check if the market is open                                      |
//+------------------------------------------------------------------+
bool IsMarketOpen()
{
    MqlDateTime dt;
    TimeToStruct(TimeLocal(), dt);
    
    string dayNames[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    bool isOpen = false;
    string message = "";

    // Check for Saturday and Sunday
    if(dt.day_of_week == 0 || dt.day_of_week == 6)
    {
        message = "Market closed: " + dayNames[dt.day_of_week];
    }
    // Check for opening hours from Monday to Friday
    else if(dt.day_of_week >= 1 && dt.day_of_week <= 5)
    {
        if(dt.hour > 1 || (dt.hour == 1 && dt.min >= 5))
        {
            if(dt.hour < 23 || (dt.hour == 23 && dt.min <= 55))
            {
                isOpen = true;
            }
            else
            {
                message = "Market closed: Outside trading hours";
            }
        }
        else
        {
            message = "Market closed: Outside trading hours";
        }
    }

    // If the market is closed and we haven't sent an alert in the last 60 minutes
    if(!isOpen && TimeLocal() - lastAlertTime > 60 * 60)
    {
        Alert(message);
        Print(message);
        lastAlertTime = TimeLocal();
    }

    return isOpen;
}

//+------------------------------------------------------------------+
//| Update indicator values                                          |
//+------------------------------------------------------------------+
bool UpdateIndicators()
{
    return (CopyBuffer(FastEMAHandle, 0, 0, 2, FastEMABuffer) == 2 &&
            CopyBuffer(SlowEMAHandle, 0, 0, 2, SlowEMABuffer) == 2 &&
            CopyBuffer(RSIHandle, 0, 0, 2, RSIBuffer) == 2);
}

//+------------------------------------------------------------------+
//| Print indicator values                                           |
//+------------------------------------------------------------------+
void PrintIndicatorValues()
{
    datetime currentTime = TimeLocal();
    
    // Ensure we have valid data before accessing the arrays
    if(ArraySize(FastEMABuffer) > 0 && ArraySize(SlowEMABuffer) > 0 && ArraySize(RSIBuffer) > 0)
    {
        if(MathAbs(FastEMABuffer[0] - lastFastEMA) > 0.0001 || 
           MathAbs(SlowEMABuffer[0] - lastSlowEMA) > 0.0001 || 
           MathAbs(RSIBuffer[0] - lastRSI) > 0.1 ||
           currentTime - lastPrintTime > 300)
        {
            Print("Symbol: ", _Symbol);
            Print("Fast EMA: ", FastEMABuffer[0], ", Slow EMA: ", SlowEMABuffer[0]);
            Print("RSI: ", RSIBuffer[0]);
            
            lastFastEMA = FastEMABuffer[0];
            lastSlowEMA = SlowEMABuffer[0];
            lastRSI = RSIBuffer[0];
            lastPrintTime = currentTime;
        }
    }
    else
    {
        Print("Error: Indicator data not available");
    }
}

//+------------------------------------------------------------------+
//| Check and open a position if necessary                           |
//+------------------------------------------------------------------+
void CheckAndOpenPosition()
{
    // Check if automatic trading is enabled
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        Print("Error: Automatic trading is disabled. Enable it in the MetaTrader terminal.");
        return;
    }

    if(IsBuySignal())
    {
        OpenBuyPosition(StopLossPips, TakeProfitPips);
    }
    else if(IsSellSignal())
    {
        OpenSellPosition(StopLossPips, TakeProfitPips);
    }
}

//+------------------------------------------------------------------+
//| Open a buy position                                              |
//+------------------------------------------------------------------+
void OpenBuyPosition(double stopLossPips, double takeProfitPips)
{
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        Print("Error: Automatic trading is disabled. Unable to open a buy position.");
        return;
    }

    double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    
    // Get the minimum stop level in points and increase it slightly
    long stopLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
    double minStopDistance = (stopLevel + 5) * pointSize; // Add 5 extra points

    // Calculate stop loss and take profit prices
    double stopLossPrice = NormalizeDouble(askPrice - (stopLossPips * pointSize), digits);
    double takeProfitPrice = NormalizeDouble(askPrice + (takeProfitPips * pointSize), digits);
    
    // Ensure that stop loss and take profit respect the minimum distance
    if (askPrice - stopLossPrice < minStopDistance)
    {
        stopLossPrice = NormalizeDouble(askPrice - minStopDistance, digits);
        Print("Stop Loss adjusted to respect the minimum distance");
    }
    
    if (takeProfitPrice - askPrice < minStopDistance)
    {
        takeProfitPrice = NormalizeDouble(askPrice + minStopDistance, digits);
        Print("Take Profit adjusted to respect the minimum distance");
    }
    
    // Check if the stops are valid before opening the position
    if (askPrice - stopLossPrice >= minStopDistance && takeProfitPrice - askPrice >= minStopDistance)
    {
        Print("Attempting to open buy position - Ask: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        if(!trade.Buy(LotSize, _Symbol, askPrice, stopLossPrice, takeProfitPrice, "Scalping EA Buy"))
        {
            Print("Error opening buy position: ", GetLastError());
            Print("Ask: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
            Print("Minimum required distance: ", minStopDistance);
            Print("Current SL distance: ", askPrice - stopLossPrice, " Current TP distance: ", takeProfitPrice - askPrice);
        }
        else
        {
            Print("Buy position opened successfully");
            Print("Entry: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        }
    }
    else
    {
        Print("Unable to open position: Invalid stop loss or take profit");
        Print("Ask: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        Print("Minimum required distance: ", minStopDistance);
        Print("Current SL distance: ", askPrice - stopLossPrice, " Current TP distance: ", takeProfitPrice - askPrice);
    }
}

//+------------------------------------------------------------------+
//| Open a sell position                                             |
//+------------------------------------------------------------------+
void OpenSellPosition(double stopLossPips, double takeProfitPips)
{
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        Print("Error: Automatic trading is disabled. Unable to open a sell position.");
        return;
    }

    double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    
    // Get the minimum stop level in points and increase it slightly
    long stopLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
    double minStopDistance = (stopLevel + 5) * pointSize; // Add 5 extra points

    // Calculate stop loss and take profit prices
    double stopLossPrice = NormalizeDouble(bidPrice + (stopLossPips * pointSize), digits);
    double takeProfitPrice = NormalizeDouble(bidPrice - (takeProfitPips * pointSize), digits);
    
    // Ensure that stop loss and take profit respect the minimum distance
    if (stopLossPrice - bidPrice < minStopDistance)
    {
        stopLossPrice = NormalizeDouble(bidPrice + minStopDistance, digits);
        Print("Stop Loss adjusted to respect the minimum distance");
    }
    
    if (bidPrice - takeProfitPrice < minStopDistance)
    {
        takeProfitPrice = NormalizeDouble(bidPrice - minStopDistance, digits);
        Print("Take Profit adjusted to respect the minimum distance");
    }
    
    // Check if the stops are valid before opening the position
    if (stopLossPrice - bidPrice >= minStopDistance && bidPrice - takeProfitPrice >= minStopDistance)
    {
        Print("Attempting to open sell position - Bid: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        if(!trade.Sell(LotSize, _Symbol, bidPrice, stopLossPrice, takeProfitPrice, "Scalping EA Sell"))
        {
            Print("Error opening sell position: ", GetLastError());
            Print("Bid: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
            Print("Minimum required distance: ", minStopDistance);
            Print("Current SL distance: ", stopLossPrice - bidPrice, " Current TP distance: ", bidPrice - takeProfitPrice);
        }
        else
        {
            Print("Sell position opened successfully");
            Print("Entry: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        }
    }
    else
    {
        Print("Unable to open position: Invalid stop loss or take profit");
        Print("Bid: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        Print("Minimum required distance: ", minStopDistance);
        Print("Current SL distance: ", stopLossPrice - bidPrice, " Current TP distance: ", bidPrice - takeProfitPrice);
    }
}

//+------------------------------------------------------------------+
//| Check the signal of buy                               |
//+------------------------------------------------------------------+
bool IsBuySignal()
{
    return (FastEMABuffer[1] > SlowEMABuffer[1] &&
            FastEMABuffer[0] <= SlowEMABuffer[0] &&
            RSIBuffer[0] < 70);
}

//+------------------------------------------------------------------+
//| Check the signal of sell                        |
//+------------------------------------------------------------------+
bool IsSellSignal()
{
    return (FastEMABuffer[1] < SlowEMABuffer[1] &&
            FastEMABuffer[0] >= SlowEMABuffer[0] &&
            RSIBuffer[0] > 30);
}



 
Danny01_Good evening, I am trying to create my own expert advisor for the U.S. indices, I have implemented various controls and they seem to work well, such as whether a symbol is valid, whether the market is closed or open, the program shows me the moving averages and RSI correctly but when it tries to open any trade (either buy or sell) it returns this following error: 2024.07.22 18:09:04.749 TradingBotDanny (US500Cash,M1) CTrade::OrderSend: market sell 0.10 US500Cash sl: 5539.76 tp: 5539.31 [invalid stops]. I attach below my code:

Try using the function below to normalize SL and TP, instead of NormalizeDouble():

//+--------------------------------------------------------------------------------------------------------------------+
//| This function normalizes and adjusts the price to the TICK SIZE                                                    |
//+--------------------------------------------------------------------------------------------------------------------+
bool NormalizePrice(string symbol, double &price)
  {
//--- Local variables
   long   decimal_digits = 0;
   double tick_size = 0.0;

//--- Get the minimal price change
   if(!SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE, tick_size))
     {
      Print(__FUNCTION__, " - Error getting the SYMBOL_TRADE_TICK_SIZE: ", GetLastError(), " - ", symbol);
      return(false);
     }

//--- Get the number of decimal digits
   if(!SymbolInfoInteger(symbol, SYMBOL_DIGITS, decimal_digits))
     {
      Print(__FUNCTION__, " - Error getting the SYMBOL_DIGITS: ", GetLastError(), " - ", symbol);
      return(false);
     }

//--- Return the price normalized
   if(tick_size == 0.0)
     {
      price = NormalizeDouble(price, (int)decimal_digits);
     }
//--- Return the price normalized and adjusted to the TICK SIZE
   else
     {
      price = NormalizeDouble(MathRound(price / tick_size) * tick_size, (int)decimal_digits);
     }

//--- Successful normalization
   return(true);
  }
 
Vinicius Pereira De Oliveira #:

Try using the function below to normalize SL and TP, instead of NormalizeDouble():

//+------------------------------------------------------------------+
//|                                         ScalpingEAWithMarketCheck.mq5 |
//|                        Copyright 2024, Your Name                 |
//|                                        https://www.yourwebsite.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Your Name"
#property link      "https://www.yourwebsite.com"
#property version   "1.04"
#property strict

#include <Trade\Trade.mqh>

// Declaration of global variables
CTrade trade;
input int FastEMAPeriod = 9;                // Fast EMA period
input int SlowEMAPeriod = 21;               // Slow EMA period
input int RSIPeriod = 14;                   // RSI period
input double LotSize = 0.1;                 // Lot size
input double StopLossPips = 10.0;           // Stop Loss in pips
input double TakeProfitPips = 20.0;         // Take Profit in pips
input string TradingSymbols = "US500Cash,US30Cash"; // Symbols for trading
static datetime lastPrintTime = 0;
static double lastFastEMA = 0;
static double lastSlowEMA = 0;
static double lastRSI = 0;

// Handles for indicators
int FastEMAHandle;
int SlowEMAHandle;
int RSIHandle;

// Arrays for indicator values
double FastEMABuffer[];
double SlowEMABuffer[];
double RSIBuffer[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialization of indicator handles
    FastEMAHandle = iMA(_Symbol, PERIOD_CURRENT, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    SlowEMAHandle = iMA(_Symbol, PERIOD_CURRENT, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    RSIHandle = iRSI(_Symbol, PERIOD_CURRENT, RSIPeriod, PRICE_CLOSE);
    
    if(FastEMAHandle == INVALID_HANDLE || SlowEMAHandle == INVALID_HANDLE || RSIHandle == INVALID_HANDLE)
    {
        Print("Error initializing indicators");
        return INIT_FAILED;
    }
    
    // Setting arrays as time series
    ArraySetAsSeries(FastEMABuffer, true);
    ArraySetAsSeries(SlowEMABuffer, true);
    ArraySetAsSeries(RSIBuffer, true);
    
    // Check if the current symbol is valid for trading
    if(!IsValidSymbol())
    {
        Print("Invalid symbol for trading: ", _Symbol);
        return INIT_FAILED;
    }
    
    if(!IsMarketOpen())
    {
        Print("Initialization completed, but the market is currently closed.");
    }
    else
    {
        Print("Initialization completed successfully. The market is open.");
    }
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    IndicatorRelease(FastEMAHandle);
    IndicatorRelease(SlowEMAHandle);
    IndicatorRelease(RSIHandle);
    Print("Expert Advisor deinitialized");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    if(!IsMarketOpen())
    {
        return;
    }
    
    if(!UpdateIndicators())
    {
        Print("Error updating indicators");
        return;
    }
    
    PrintIndicatorValues();
    
    if(PositionsTotal() == 0)
    {
        CheckAndOpenPosition();
    }
}

//+------------------------------------------------------------------+
//| Check if the current symbol is valid for trading                 |
//+------------------------------------------------------------------+
bool IsValidSymbol()
{
    string symbols[];
    StringSplit(TradingSymbols, ',', symbols);
    
    for(int i = 0; i < ArraySize(symbols); i++)
    {
        if(StringCompare(_Symbol, CustomTrim(symbols[i]), false) == 0)
        {
            return true;
        }
    }
    return false;
}

//+------------------------------------------------------------------+
//| Custom function to remove whitespace                             |
//+------------------------------------------------------------------+
string CustomTrim(string str)
{
    int start = 0;
    int end = StringLen(str) - 1;
    
    // Remove spaces at the beginning
    while(start <= end && StringGetCharacter(str, start) == ' ')
        start++;
    
    // Remove spaces at the end
    while(end >= start && StringGetCharacter(str, end) == ' ')
        end--;
    
    // Extract the substring without spaces
    return StringSubstr(str, start, end - start + 1);
}
static datetime lastAlertTime = 0;

//+------------------------------------------------------------------+
//| Check if the market is open                                      |
//+------------------------------------------------------------------+
bool IsMarketOpen()
{
    MqlDateTime dt;
    TimeToStruct(TimeLocal(), dt);
    
    string dayNames[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    bool isOpen = false;
    string message = "";

    // Check for Saturday and Sunday
    if(dt.day_of_week == 0 || dt.day_of_week == 6)
    {
        message = "Market closed: " + dayNames[dt.day_of_week];
    }
    // Check for opening hours from Monday to Friday
    else if(dt.day_of_week >= 1 && dt.day_of_week <= 5)
    {
        if(dt.hour >= 0 && dt.hour < 22)
        {
            isOpen = true;
        }
        else
        {
            message = "Market closed: Outside trading hours";
        }
    }

    // If the market is closed and we haven't sent an alert in the last 60 minutes
    if(!isOpen && TimeLocal() - lastAlertTime > 60 * 60)
    {
        Alert(message);
        Print(message);
        lastAlertTime = TimeLocal();
    }

    return isOpen;
}

//+------------------------------------------------------------------+
//| Update indicator values                                          |
//+------------------------------------------------------------------+
bool UpdateIndicators()
{
    return (CopyBuffer(FastEMAHandle, 0, 0, 2, FastEMABuffer) == 2 &&
            CopyBuffer(SlowEMAHandle, 0, 0, 2, SlowEMABuffer) == 2 &&
            CopyBuffer(RSIHandle, 0, 0, 2, RSIBuffer) == 2);
}

//+------------------------------------------------------------------+
//| Print indicator values                                           |
//+------------------------------------------------------------------+
void PrintIndicatorValues()
{
    datetime currentTime = TimeLocal();
    
    // Ensure we have valid data before accessing the arrays
    if(ArraySize(FastEMABuffer) > 0 && ArraySize(SlowEMABuffer) > 0 && ArraySize(RSIBuffer) > 0)
    {
        if(MathAbs(FastEMABuffer[0] - lastFastEMA) > 0.0001 || 
           MathAbs(SlowEMABuffer[0] - lastSlowEMA) > 0.0001 || 
           MathAbs(RSIBuffer[0] - lastRSI) > 0.1 ||
           currentTime - lastPrintTime > 300)
        {
            Print("Symbol: ", _Symbol);
            Print("Fast EMA: ", FastEMABuffer[0], ", Slow EMA: ", SlowEMABuffer[0]);
            Print("RSI: ", RSIBuffer[0]);
            
            lastFastEMA = FastEMABuffer[0];
            lastSlowEMA = SlowEMABuffer[0];
            lastRSI = RSIBuffer[0];
            lastPrintTime = currentTime;
        }
    }
    else
    {
        Print("Error: Indicator data not available");
    }
}

//+------------------------------------------------------------------+
//| Check and open a position if necessary                           |
//+------------------------------------------------------------------+
void CheckAndOpenPosition()
{
    // Check if automatic trading is enabled
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        Print("Error: Automatic trading is disabled. Enable it in the MetaTrader terminal.");
        return;
    }

    if(IsBuySignal())
    {
        OpenBuyPosition(StopLossPips, TakeProfitPips);
    }
    else if(IsSellSignal())
    {
        OpenSellPosition(StopLossPips, TakeProfitPips);
    }
}

//+------------------------------------------------------------------+
//| Open a buy position                                              |
//+------------------------------------------------------------------+
void OpenBuyPosition(double stopLossPips, double takeProfitPips)
{
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        Print("Error: Automatic trading is disabled. Unable to open a buy position.");
        return;
    }

    double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    
    // Get the minimum stop level in points and increase it slightly
    long stopLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
    double minStopDistance = (stopLevel + 5) * pointSize; // Add 5 extra points

    // Calculate stop loss and take profit prices
    double stopLossPrice = askPrice - (stopLossPips * pointSize);
    double takeProfitPrice = askPrice + (takeProfitPips * pointSize);
    
    // Normalize prices using the new function
    if(!NormalizePrice(_Symbol, stopLossPrice) || !NormalizePrice(_Symbol, takeProfitPrice) || !NormalizePrice(_Symbol, askPrice))
    {
        Print("Error in price normalization");
        return;
    }
    
    // Ensure that stop loss and take profit respect the minimum distance
    if (askPrice - stopLossPrice < minStopDistance)
    {
        stopLossPrice = askPrice - minStopDistance;
        if(!NormalizePrice(_Symbol, stopLossPrice))
        {
            Print("Error in Stop Loss normalization");
            return;
        }
        Print("Stop Loss adjusted to respect minimum distance");
    }
    
    if (takeProfitPrice - askPrice < minStopDistance)
    {
        takeProfitPrice = askPrice + minStopDistance;
        if(!NormalizePrice(_Symbol, takeProfitPrice))
        {
            Print("Error in Take Profit normalization");
            return;
        }
        Print("Take Profit adjusted to respect minimum distance");
    }
    
    // Check if stops are valid before opening the position
    if (askPrice - stopLossPrice >= minStopDistance && takeProfitPrice - askPrice >= minStopDistance)
    {
        Print("Attempting to open buy position - Ask: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        if(!trade.Buy(LotSize, _Symbol, askPrice, stopLossPrice, takeProfitPrice, "Scalping EA Buy"))
        {
            Print("Error opening buy position: ", GetLastError());
            Print("Ask: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
            Print("Minimum required distance: ", minStopDistance);
            Print("Current SL distance: ", askPrice - stopLossPrice, " Current TP distance: ", takeProfitPrice - askPrice);
        }
        else
        {
            Print("Buy position opened successfully");
            Print("Entry: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        }
    }
    else
    {
        Print("Unable to open position: Invalid stop loss or take profit");
        Print("Ask: ", askPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        Print("Minimum required distance: ", minStopDistance);
        Print("Current SL distance: ", askPrice - stopLossPrice, " Current TP distance: ", takeProfitPrice - askPrice);
    }
}

//+------------------------------------------------------------------+
//| Open a sell position                                             |
//+------------------------------------------------------------------+
void OpenSellPosition(double stopLossPips, double takeProfitPips)
{
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
    {
        Print("Error: Automatic trading is disabled. Unable to open a sell position.");
        return;
    }

    double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
    int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
    
    // Get the minimum stop level in points and increase it slightly
    long stopLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
    double minStopDistance = (stopLevel + 5) * pointSize; // Add 5 extra points

    // Calculate stop loss and take profit prices
    double stopLossPrice = bidPrice + (stopLossPips * pointSize);
    double takeProfitPrice = bidPrice - (takeProfitPips * pointSize);
    
    // Normalize prices using the new function
    if(!NormalizePrice(_Symbol, stopLossPrice) || !NormalizePrice(_Symbol, takeProfitPrice) || !NormalizePrice(_Symbol, bidPrice))
    {
        Print("Error in price normalization");
        return;
    }
    
    // Ensure that stop loss and take profit respect the minimum distance
    if (stopLossPrice - bidPrice < minStopDistance)
    {
        stopLossPrice = bidPrice + minStopDistance;
        if(!NormalizePrice(_Symbol, stopLossPrice))
        {
            Print("Error in Stop Loss normalization");
            return;
        }
        Print("Stop Loss adjusted to respect minimum distance");
    }
    
    if (bidPrice - takeProfitPrice < minStopDistance)
    {
        takeProfitPrice = bidPrice - minStopDistance;
        if(!NormalizePrice(_Symbol, takeProfitPrice))
        {
            Print("Error in Take Profit normalization");
            return;
        }
        Print("Take Profit adjusted to respect minimum distance");
    }
    
    // Check if stops are valid before opening the position
    if (stopLossPrice - bidPrice >= minStopDistance && bidPrice - takeProfitPrice >= minStopDistance)
    {
        Print("Attempting to open sell position - Bid: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        if(!trade.Sell(LotSize, _Symbol, bidPrice, stopLossPrice, takeProfitPrice, "Scalping EA Sell"))
        {
            Print("Error opening sell position: ", GetLastError());
            Print("Bid: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
            Print("Minimum required distance: ", minStopDistance);
            Print("Current SL distance: ", stopLossPrice - bidPrice, " Current TP distance: ", bidPrice - takeProfitPrice);
        }
        else
{
            Print("Sell position opened successfully");
            Print("Entry: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        }
    }
    else
    {
        Print("Unable to open position: Invalid stop loss or take profit");
        Print("Bid: ", bidPrice, " SL: ", stopLossPrice, " TP: ", takeProfitPrice);
        Print("Minimum required distance: ", minStopDistance);
        Print("Current SL distance: ", stopLossPrice - bidPrice, " Current TP distance: ", bidPrice - takeProfitPrice);
    }
}

//+------------------------------------------------------------------+
//| This function normalizes and adjusts the price to the TICK SIZE  |
//+------------------------------------------------------------------+
bool NormalizePrice(string symbol, double &price)
{
    //--- Local variables
    long   decimal_digits = 0;
    double tick_size = 0.0;

    //--- Get the minimal price change
    if(!SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE, tick_size))
    {
        Print(__FUNCTION__, " - Error getting the SYMBOL_TRADE_TICK_SIZE: ", GetLastError(), " - ", symbol);
        return(false);
    }

    //--- Get the number of decimal digits
    if(!SymbolInfoInteger(symbol, SYMBOL_DIGITS, decimal_digits))
    {
        Print(__FUNCTION__, " - Error getting the SYMBOL_DIGITS: ", GetLastError(), " - ", symbol);
        return(false);
    }

    //--- Return the price normalized
    if(tick_size == 0.0)
    {
        price = NormalizeDouble(price, (int)decimal_digits);
    }
    //--- Return the price normalized and adjusted to the TICK SIZE
    else
    {
        price = NormalizeDouble(MathRound(price / tick_size) * tick_size, (int)decimal_digits);
    }

    //--- Successful normalization
    return(true);
}

//+------------------------------------------------------------------+
//| Check for buy signal                                             |
//+------------------------------------------------------------------+
bool IsBuySignal()
{
    return (FastEMABuffer[1] > SlowEMABuffer[1] &&
            FastEMABuffer[0] <= SlowEMABuffer[0] &&
            RSIBuffer[0] < 70);
}

//+------------------------------------------------------------------+
//| Check for sell signal                                            |
//+------------------------------------------------------------------+
bool IsSellSignal()
{
    return (FastEMABuffer[1] < SlowEMABuffer[1] &&
            FastEMABuffer[0] >= SlowEMABuffer[0] &&
            RSIBuffer[0] > 30);
}
Replacing the NormalizeDouble() function with NormalizePrice I keep getting the same error
The Craziest & Most Affordable Hosting Deal Ever!
The Craziest & Most Affordable Hosting Deal Ever!
  • monsterhost.com
Powerful & Fast WP sites
 

Indices markets don't use the same symbol margin initial as in forex markets, it's an entirely different exchange. The points in indices means something different... you have 10 in the input for stoplosspips, try 10000, and you'll see how narrow the stop loss will still be

In EURUSD and other currency pairs, 1 standard lot is equal to 100,000 units of the base currency. In US30, 1 standard lot is equal to 1 unit of the base currency...but varies between brokers.

In MT4 and MT5 right click a symbol in the Market Watch window and click Specification. The Contract Size field tells how many units are in one lot, from this you can get an idea for how the SL and TP should be calculated