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.
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.
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.