[EA / 4756 ERROR / 0.0 (Broker Stated Minimum TP/SL)

 
Hi,

How do I overcome the 4756 error and move into being able to execute trades algorithmically via my EA?

Invalid SL/TP...

It must be set relative to the current ticker price (for your information).

Ticker: NAS100_SB

Lot size:0.1

I do welcome your inputs as to what could be going wrong.

My lot size is fine (as I know that is the Broker minimum for this ticker).
// Declare input variables for the EMA periods
input int EMA9Period = 9;
input int EMA12Period = 12;
input int EMA50Period = 50;
input int EMA72Period = 72;
input int EMA200Period = 200;
input double LotSize = 0.1;  // Lot size to use for trades
input int TrailingStart = 200;  // Start trailing stop after 20 pips (200 points for most symbols)

// Declare variables for storing EMA handles
int handle_ema9, handle_ema12, handle_ema50, handle_ema72, handle_ema200;

// Function to initialize the handles for EMAs
void InitEMAs() {
    handle_ema9 = iMA(Symbol(), PERIOD_M1, EMA9Period, 0, MODE_EMA, PRICE_CLOSE);
    handle_ema12 = iMA(Symbol(), PERIOD_M1, EMA12Period, 0, MODE_EMA, PRICE_CLOSE);
    handle_ema50 = iMA(Symbol(), PERIOD_M1, EMA50Period, 0, MODE_EMA, PRICE_CLOSE);
    handle_ema72 = iMA(Symbol(), PERIOD_M1, EMA72Period, 0, MODE_EMA, PRICE_CLOSE);
    handle_ema200 = iMA(Symbol(), PERIOD_M1, EMA200Period, 0, MODE_EMA, PRICE_CLOSE);

    // Check if the handles are valid
    if (handle_ema9 == INVALID_HANDLE || handle_ema12 == INVALID_HANDLE || handle_ema50 == INVALID_HANDLE ||
        handle_ema72 == INVALID_HANDLE || handle_ema200 == INVALID_HANDLE) {
        Print("Failed to create handle for EMA indicator");
    }
}

// Function to check if there is an open trade
bool HasOpenTrade() {
    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        if (PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_MAGIC) == 123456) {
            return true;
        }
    }
    return false;
}

// Function to retrieve EMA values and check for crossovers at the close of the previous candle
void RetrieveEMAValues() {
    if (HasOpenTrade()) {
        // If there's an open trade, handle the trailing stop logic
        HandleTrailingStop();
        return;  // No new trade is opened if there's an active one
    }

    double ema9_value[], ema12_value[], ema50_value[], ema72_value[], ema200_value[];

    // Copy the values from the EMA buffers (we want the previous bar, so we copy from index 1)
    int copied_ema9 = CopyBuffer(handle_ema9, 0, 1, 1, ema9_value);  // Previous candle
    int copied_ema12 = CopyBuffer(handle_ema12, 0, 1, 1, ema12_value);
    int copied_ema50 = CopyBuffer(handle_ema50, 0, 1, 1, ema50_value);
    int copied_ema72 = CopyBuffer(handle_ema72, 0, 1, 1, ema72_value);
    int copied_ema200 = CopyBuffer(handle_ema200, 0, 1, 1, ema200_value);

    // Check if buffer copying succeeded
    if (copied_ema9 <= 0 || copied_ema12 <= 0 || copied_ema50 <= 0 || copied_ema72 <= 0 || copied_ema200 <= 0) {
        Print("Failed to copy EMA buffer values");
        return;
    }

    // Access the EMA values from the previous closed candle
    double prev_ema9 = ema9_value[0];
    double prev_ema12 = ema12_value[0];
    double prev_ema50 = ema50_value[0];
    double prev_ema72 = ema72_value[0];
    double prev_ema200 = ema200_value[0];

    // Print EMA values for debugging
    Print("Previous EMA9: ", prev_ema9, " Previous EMA12: ", prev_ema12);
    Print("Previous EMA50: ", prev_ema50, " Previous EMA72: ", prev_ema72, " Previous EMA200: ", prev_ema200);

    // Buy Condition: EMA 9 crosses above EMA 12 (on the previous candle close)
    if (prev_ema9 > prev_ema12) {
        PlaceBuyOrder();
        Print("Buy signal triggered: EMA 9 crossed above EMA 12");
    }

    // Buy Condition: EMA 50 crosses above EMA 72, and EMA 200 is below EMA 50 (on the previous candle close)
    if (prev_ema50 > prev_ema72 && prev_ema200 < prev_ema50) {
        PlaceBuyOrder();
        Print("Buy signal triggered: EMA 50 crossed above EMA 72 with EMA 200 below EMA 50");
    }

    // Sell Condition: EMA 9 crosses below EMA 12 (on the previous candle close)
    if (prev_ema9 < prev_ema12) {
        PlaceSellOrder();
        Print("Sell signal triggered: EMA 9 crossed below EMA 12");
    }

    // Sell Condition: EMA 50 crosses below EMA 72, and EMA 200 is above EMA 50 (on the previous candle close)
    if (prev_ema50 < prev_ema72 && prev_ema200 > prev_ema50) {
        PlaceSellOrder();
        Print("Sell signal triggered: EMA 50 crossed below EMA 72 with EMA 200 above EMA 50");
    }
}

// Function to send a buy order
void PlaceBuyOrder() {
    MqlTradeRequest request;
    MqlTradeResult result;
    double ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);  // Get the current Ask price

    // Prepare the trade request
    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = LotSize;
    request.type = ORDER_TYPE_BUY;
    request.price = ask;

    // No Stop-Loss or Take-Profit initially
    request.sl = 0;
    request.tp = 0;

    request.deviation = 3;  // Slippage in pips
    request.magic = 123456;  // Unique identifier for this EA

    // Send the buy order
    if (!OrderSend(request, result)) {
        int errorCode = GetLastError();
        Print("Error placing buy order: ", errorCode);
    }
}

// Function to send a sell order
void PlaceSellOrder() {
    MqlTradeRequest request;
    MqlTradeResult result;
    double bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);  // Get the current Bid price

    // Prepare the trade request
    request.action = TRADE_ACTION_DEAL;
    request.symbol = Symbol();
    request.volume = LotSize;
    request.type = ORDER_TYPE_SELL;
    request.price = bid;

    // No Stop-Loss or Take-Profit initially
    request.sl = 0;
    request.tp = 0;

    request.deviation = 3;  // Slippage in pips
    request.magic = 123456;  // Unique identifier for this EA

    // Send the sell order
    if (!OrderSend(request, result)) {
        int errorCode = GetLastError();
        Print("Error placing sell order: ", errorCode);
    }
}

// Function to manage trailing stop logic
void HandleTrailingStop() {
    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        if (PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_MAGIC) == 123456) {
            double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
            double stopLoss = PositionGetDouble(POSITION_SL);
            double currentPrice;

            // Determine if the position is buy or sell and set the current price
            if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
                currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);  // For a buy position, trailing stop uses the bid price
            } else {
                currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);  // For a sell position, trailing stop uses the ask price
            }

            double distance = MathAbs(currentPrice - entryPrice);

            // If the trade has secured at least 20 pips (200 points), activate trailing stop
            if (distance >= TrailingStart * _Point) {
                double newSL;
                if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {
                    newSL = currentPrice - (TrailingStart * _Point);
                    if (newSL > stopLoss) {
                        ModifyPosition(PositionGetTicket(i), newSL);
                    }
                } else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) {
                    newSL = currentPrice + (TrailingStart * _Point);
                    if (newSL < stopLoss) {
                        ModifyPosition(PositionGetTicket(i), newSL);
                    }
                }
            }
        }
    }
}

// Function to modify an existing position's stop loss
void ModifyPosition(ulong ticket, double newSL) {
    MqlTradeRequest request;
    MqlTradeResult result;
    request.action = TRADE_ACTION_SLTP;
    request.position = ticket;
    request.sl = newSL;

    if (!OrderSend(request, result)) {
        Print("Error modifying stop loss: ", GetLastError());
    }
}

// Main logic in OnTick function
void OnTick() {
    // Initialize handles for EMAs (done only once)
    InitEMAs();

    // Retrieve the EMA values and place orders based on EMA crossovers
    RetrieveEMAValues();
}