//±-----------------------------------------------------------------+
//|                                                     ZZ_EA.mq4   |
//|                              Copyright © 2023, Gabriele Bassi   |
//|                          Added LotSize & Spread                 |
//|                          Added MagicNumber & Custom OrdersTotal |
//±-----------------------------------------------------------------+
#property copyright "Gabriele Bassi" 
string version = "ZZ_EA v.0.1";

// External input parameters for the EA
input double LotSize = 0.1; // Fixed lot size for each trade
input double TakeProfitPips = 400; // Take profit in pips
input double StopLossPips = 150; // Stop loss in pips
input double TrailingStopPips = 10; // Trailing stop in pips
input int MagicNumber = 12345; // Magic number to identify trades by this EA
input double MaximumSpread = 3; // Maximum allowed spread in pips


// External input parameters for the indicator
input int CCI_Period = 12;
input int Momentum_Period = 21;
input int RSI_Period = 14;
input double SAR_Step = 0.01;
input double SAR_Maximum = 0.2;

// OnInit is called when the expert is loaded onto a chart
int OnInit() {
    // Initialization code here
    return INIT_SUCCEEDED;
}

int deinit() {
    // Deinitialization code here
    return(0);
}

// Custom function to count only our own trades with the MagicNumber and on the current symbol
int CountOrdersByMagicAndSymbol() {
    int count = 0;
    for (int i = 0; i < OrdersTotal(); i++) {
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
        if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()) {
            count++;
        }
    }
    return count;
}

// OnTick is called on every new tick
void OnTick() {
    // Get the current spread in pips
    double spread = (Ask - Bid) / Point;

    // Check the spread against the maximum allowable spread before trading
    if (spread > MaximumSpread) {
        // Spread is too high, do not place the trade
        // Print("Spread is too high: ", spread); // Uncomment this line to print to the log
        return; // Exit the OnTick function
    }

    // Get last bar index in the chart (0 is the currently forming bar, 1 is the last fully formed bar)
    int lastBarIndex = 1;

    // Retrieve the last known values for the indicator signals
    double arrowUp = iCustom(Symbol(), 0, "ZZZZZ", CCI_Period, Momentum_Period, RSI_Period, SAR_Step, SAR_Maximum, 0, lastBarIndex);
    double arrowDown = iCustom(Symbol(), 0, "ZZZZZ", CCI_Period, Momentum_Period, RSI_Period, SAR_Step, SAR_Maximum, 1, lastBarIndex);

    // If there are no current orders with our MagicNumber, check for a buy or sell signal
    if (CountOrdersByMagicAndSymbol() == 0) {
        if (arrowUp != EMPTY_VALUE) {
            // If an up arrow (buy signal) is present, send a buy order
            double sl = NormalizeDouble(Bid - StopLossPips * Point, Digits);
            double tp = NormalizeDouble(Bid + TakeProfitPips * Point, Digits);
            int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp, "Buy order based on ZZZZZ", MagicNumber, 0, clrGreen);
            if (ticket < 0) {
                Print("OrderSend error: ", GetLastError());
            }
        } else if (arrowDown != EMPTY_VALUE) {
            // If a down arrow (sell signal) is present, send a sell order
            double sl = NormalizeDouble(Ask + StopLossPips * Point, Digits);
            double tp = NormalizeDouble(Ask - TakeProfitPips * Point, Digits);
            int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp, "Sell order based on ZZZZZ", MagicNumber, 0, clrRed);
            if (ticket < 0) {
                Print("OrderSend error: ", GetLastError());
            }
        }
    } else {
        // Update the trailing stop for existing orders
        TrailingStopFunc();
    }
}

// TrailingStopFunc adjusts the stop loss to enable a trailing stop
void TrailingStopFunc() {
    for (int i = OrdersTotal() - 1; i >= 0; --i) {
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
        
        // Verify that the selected order is for the current symbol with our MagicNumber
        if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
            double newStopLoss;
            
            if (OrderType() == OP_BUY) {
                // Current price is far enough from the opening price to move stop loss
                if (Bid - OrderOpenPrice() > TrailingStopPips * Point) {
                    newStopLoss = Bid - TrailingStopPips * Point;
                    
                    // Update the stop loss if it is less than the current stop loss
                    if (newStopLoss > OrderStopLoss()) {
                        OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrGreen);
                    }
                }
            } else if (OrderType() == OP_SELL) {
                // Current price is far enough from the opening price to move stop loss
                if (OrderOpenPrice() - Ask > TrailingStopPips * Point) {
                    newStopLoss = Ask + TrailingStopPips * Point;
                    
                    // Update the stop loss if it is greater than the current stop loss
                    if (newStopLoss < OrderStopLoss()) {
                        OrderModify(OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, clrRed);
                    }
                }
            }
        }
    }
}

//±-----------------------------------------------------------------+

ho questo errore: 'ticket' - variable already defined	zzz_ea4.mq4	82	17