Grid MACD System (Non-Repaint) MetaTrader 4 Expert Advisor

The Grid MACD System (Non-Repaint) is an Expert Advisor designed to leverage the Moving Average Convergence Divergence (MACD) indicator for trading. This EA employs a grid-based approach combined with MACD signals to guide trading decisions. The non-repaint feature ensures that once a signal is generated, it remains consistent and does not change, providing clear and stable trading signals.

extern double Lots = 1;  // Number of lots to trade (usually, 1 lot is $100k) (unlimited)
extern double TrailingStop = 55;   // The amount of the trailing stop needed to maximize profit (unlimited)
extern int MACD_level = 500;       // (1-12) [low works for GBPUSD], high works for others
extern int MAGIC = 123456;          // Magic number for orders
extern int tp_limit = 100;          // Limit for take profit
int limit = 1000;                   // Limit for bars
int gap = 1;                        // Gap for MACD calculation
extern int wait_time_b4_SL = 10000; // Time to wait before applying stop loss

int trend = 0, last_trend = 0, pending_time, ticket, total, pace, tp_cnt;
bool sell_flag, buy_flag, find_highest = false, find_lowest = false;
double MACD_Strength = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
    return(0); // Initialization code here (if any)
}

//+------------------------------------------------------------------+
//| Expert de-initialization function                                 |
//+------------------------------------------------------------------+
int deinit() {
    return(0); // Cleanup code here (if any)
}

//+------------------------------------------------------------------+
//| Function to determine the best trading deal based on MACD       |
//+------------------------------------------------------------------+
int best_deal() {
    double MACDSignal1, MACDSignal2;

    // Calculate MACD values for current and previous bars
    MACDSignal2 = iMA(NULL, PERIOD_M1, MACD_level, 0, MODE_EMA, Close[0], 0) - iMA(NULL, PERIOD_M1, MACD_level + 1, 0, MODE_EMA, Close[0], 0);
    MACDSignal1 = iMA(NULL, PERIOD_M1, MACD_level, 0, MODE_EMA, Close[gap], gap) - iMA(NULL, PERIOD_M1, MACD_level + 1, 0, MODE_EMA, Close[gap], gap);

    // Check conditions for finding the highest or lowest
    if ((find_highest && Close[0] > OrderOpenPrice() + Point * 5) && MACDSignal2 < MACDSignal1) {
        find_highest = false;
        return (1); // Signal to execute trade
    } 
    else if ((find_lowest && Close[0] < OrderOpenPrice() - Point * 5) && MACDSignal2 > MACDSignal1) {
        find_lowest = false;
        return (1); // Signal to execute trade
    }

    return (0); // No signal
}

//+------------------------------------------------------------------+
//| Function to determine the MACD direction                        |
//+------------------------------------------------------------------+
int MACD_Direction() {
    double MACDSignal1, MACDSignal2;
    double ind_buffer1[100]; // Unused buffer in current code
    MACDSignal2 = iMA(NULL, PERIOD_M1, 100, 0, MODE_EMA, Close[0], 0) - iMA(NULL, PERIOD_M1, MACD_level, 0, MODE_EMA, Close[0], 0);
    MACDSignal1 = iMA(NULL, PERIOD_M1, 100, 0, MODE_EMA, Close[gap], gap) - iMA(NULL, PERIOD_M1, MACD_level, 0, MODE_EMA, Close[gap], gap);

    // Calculate MACD Strength and its direction
    MACD_Strength = MathAbs(MACDSignal2 - MACDSignal1);

    if (MACDSignal1 < 0) return (-1); 
    if (MACDSignal1 > 0) return (1); 
    return (0); // No clear direction
}

//+------------------------------------------------------------------+
//| Function to close pending orders                                |
//+------------------------------------------------------------------+
void ClosePending() {
    if (OrderType() <= OP_SELL && OrderSymbol() == Symbol()) {
        if (OrderType() == OP_BUY) {
            OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet); 
        } else {
            OrderClose(OrderTicket(), OrderLots(), Ask, 3, Violet); 
        }
        pending_time = 0; 
    }
}

//+------------------------------------------------------------------+
//| Function to execute a trading order                             |
//+------------------------------------------------------------------+
void do_order(int type) {
    if (type == 1) { // Buy order
        ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, 0, "PM", MAGIC, 0, White);
        if (ticket > 0) {
            if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) {
                Print("BUY order opened : ", OrderOpenPrice()); // Confirm buy order
                pace = tp_limit; tp_cnt = 0; pending_time = 0; find_highest = true;
            }
        } else {
            Print("Error opening BUY order : ", GetLastError());
        }
        buy_flag = false;
    } else if (type == 2) { // Sell order
        ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, 0, 0, "PM", MAGIC, 0, Red);
        if (ticket > 0) {
            if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) {
                Print("SELL order opened : ", OrderOpenPrice()); // Confirm sell order
                pace = tp_limit; tp_cnt = 0; pending_time = 0; find_lowest = true;
            }
        } else {
            Print("Error opening SELL order : ", GetLastError());
        }
        sell_flag = false;
    }
}

//+------------------------------------------------------------------+
//| Function to manage trailing stop                                |
//+------------------------------------------------------------------+
int trailing_stop(int type) {
    pace++;
    if (TrailingStop > 0 && type == 1 && pace > tp_limit && tp_cnt < tp_limit) { // Buy order trailing stop
        if (Bid - OrderOpenPrice() > Point * TrailingStop) {
            if (OrderStopLoss() < Bid - Point * TrailingStop) {
                OrderModify(OrderTicket(), OrderOpenPrice(), Bid - Point * TrailingStop, OrderTakeProfit(), 0, Green);
                pace = 0; tp_cnt++; pending_time = 0; return (1);
            }
        }
    } else if (TrailingStop > 0 && type == 2 && pace > tp_limit && tp_cnt < tp_limit) { // Sell order trailing stop
        if ((OrderOpenPrice() - Ask) > (Point * TrailingStop)) {
            if ((OrderStopLoss() > (Ask + Point * TrailingStop)) || (OrderStopLoss() == 0)) {
                OrderModify(OrderTicket(), OrderOpenPrice(), Ask + Point * TrailingStop, OrderTakeProfit(), 0, Red);
                pace = 0; tp_cnt++; pending_time = 0; return (1);
            }
        }
    }
    if (TrailingStop > 0 && tp_cnt >= tp_limit) {
        ClosePending(); // Close pending orders if trailing stop limit reached
    }
    return (0);
}

//+------------------------------------------------------------------+
//| Main function called on each new tick                           |
//+------------------------------------------------------------------+
int start() {
    int count;

    if (Bars < 100) { 
        Print("Bars less than 100"); 
        return (0); 
    }

    last_trend = trend;
    trend = MACD_Direction();
    total = OrdersTotal();

    for (count = 0; count < total; count++) {
        pending_time++;
        OrderSelect(count, SELECT_BY_POS, MODE_TRADES);
        if (OrderType() <= OP_SELL && OrderSymbol() == Symbol()) {
            if (OrderType() == OP_BUY) {
                trailing_stop(1); // Manage trailing stop for buy orders

                if (trend < 0 && last_trend > 0 && Close[0] > OrderOpenPrice() + Point * 5) {
                    ClosePending(); 
                    return (0);
                }

                if (best_deal() == 1) {
                    ClosePending(); 
                    pending_time = 0; 
                    find_highest = false;
                    return (0);
                }

                if (find_highest && pending_time > wait_time_b4_SL && Close[0] <= OrderOpenPrice() + Point * (pending_time - wait_time_b4_SL)) {
                    ClosePending(); 
                    pending_time = 0; 
                    find_highest = false;
                    return (0);
                }
            } else { // For sell orders
                trailing_stop(2);

                if (trend > 0 && last_trend < 0 && Close[0] < OrderOpenPrice() - Point * 5) {
                    ClosePending(); 
                    return (0);
                }

                if (best_deal() == 1) {
                    ClosePending(); 
                    pending_time = 0; 
                    find_lowest = false;
                    return (0);
                }

                if (find_lowest && pending_time > wait_time_b4_SL && Close[0] >= OrderOpenPrice() - Point * (pending_time - wait_time_b4_SL)) {
                    ClosePending(); 
                    pending_time = 0; 
                    find_lowest = false;
                    return (0);
                }
            }
        }
        return (0);
    }

    // Set flags for new trades based on trend direction
    if (trend > 0 && last_trend < 0) { 
        buy_flag = true; 
        sell_flag = false; 
        last_trend = trend; 
    } else if (trend < 0 && last_trend > 0) { 
        sell_flag = true; 
        buy_flag = false; 
        last_trend = trend; 
    }

    // Execute orders based on flags
    if (sell_flag || buy_flag) { 
        if (buy_flag) do_order(1); 
        if (sell_flag) do_order(2); 
    }
    
    return (0);
}

Key Components of the EA

Initialization and De-initialization

Every EA begins with an initialization phase. This is where the EA sets up necessary parameters and prepares to start trading. Once trading is done, the de-initialization phase cleans up any resources or settings. In our case, these functions are relatively straightforward and don’t perform any complex operations.

See also  Delta Envelope Project (Non-Repaint) MetaTrader 4 Expert Advisor

MACD-Based Trading Signals

One of the core elements of this EA is its reliance on the Moving Average Convergence Divergence (MACD) indicator. The EA uses MACD to generate trading signals. Here’s how it works:

  • MACD Calculation: The EA calculates two MACD values using different periods and compares them. This comparison helps determine whether the market is trending upwards or downwards.
  • Trading Signals: Based on these calculations, the EA decides whether to open or close a trade. For example, if the calculated MACD value suggests a strong upward trend, the EA might signal a buy order. Conversely, a downward trend could prompt a sell order.

Trailing Stop Mechanism

A trailing stop is a dynamic stop loss that moves with the market price. It helps lock in profits as the market moves in a favorable direction.

  • Trailing Stop for Buy Orders: When the EA detects that a buy order has gained a certain amount, it adjusts the stop loss to secure those gains. If the price moves against the order, the stop loss helps minimize losses.
  • Trailing Stop for Sell Orders: Similarly, for sell orders, the trailing stop moves to protect profits or limit losses if the market moves unfavorably.

Order Management

Managing open orders is crucial for any EA. This EA includes functions to handle both buy and sell orders effectively:

  • Order Execution: When a trading signal is generated, the EA places a buy or sell order. It ensures that the order is executed at the best possible price and records the order details.
  • Order Closure: The EA can close orders based on specific conditions, such as hitting a trailing stop or meeting other predefined criteria.
See also  Trend Signal v1.0 (NRP+MTF) MetaTrader 4 Indicator

High and Low Price Conditions

The EA also monitors for high and low price conditions to decide when to close orders. If the market price moves significantly in one direction from the order’s opening price, the EA might close the order to secure profits or limit losses.

Conclusion

This Expert Advisor is designed to help traders automate their trading strategy based on MACD signals and trailing stop mechanisms. By understanding how it calculates signals, manages orders, and adjusts stop losses, traders can gain insights into its operation and make more informed decisions. Remember, while this EA incorporates sophisticated mechanisms, it’s important to thoroughly test any EA in a demo environment before applying it to live trading. This ensures that it meets your trading needs and aligns with your strategy.

Leave a Comment