Problem Description
Solution
Here is a complete, fully functional MQL4 Expert Advisor (robot) designed to buy when the price breaks above a specific trendline.
How it works
- Draw a Trendline: You draw a trendline on the chart manually.
- Name the Trendline: You must name the trendline "BuyLine" (or whatever name you set in the inputs) in the object properties.
- Logic: The robot monitors that specific line. If the price crosses from below the line to above the line, it executes a Buy order.
MQL4 Code
//+------------------------------------------------------------------+
//| TrendlineBreakoutBuy.mq4 |
//| Copyright 2023, Quantitative |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input string InpTrendLineName = "BuyLine"; // Name of the trendline to monitor
input double InpLotSize = 0.1; // Trading volume
input int InpStopLoss = 50; // Stop Loss in points (0 = none)
input int InpTakeProfit = 100; // Take Profit in points (0 = none)
input int InpMagicNumber = 8899; // Unique ID for this EA's trades
input int InpSlippage = 3; // Max slippage in points
//--- Global Variables
datetime lastBarTime = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Check if the trendline exists on startup
if(ObjectFind(0, InpTrendLineName) < 0)
{
Print("Warning: Trendline named '", InpTrendLineName, "' not found. Please draw it and rename it.");
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment(""); // Clear chart comments
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. Check if the trendline exists
if(ObjectFind(0, InpTrendLineName) < 0)
{
Comment("Waiting for trendline named: ", InpTrendLineName);
return;
}
// 2. Check if we already have an open trade for this EA
if(CountOpenTrades() > 0)
{
Comment("Trade active. Monitoring...");
return;
}
// 3. Get Trendline Price values
// Price at current bar (Shift 0)
double linePriceCurrent = ObjectGetValueByShift(InpTrendLineName, 0);
// Price at previous bar (Shift 1)
double linePricePrevious = ObjectGetValueByShift(InpTrendLineName, 1);
// 4. Check for Breakout Condition
// Condition: Previous Close was BELOW the line, and Current Ask is ABOVE the line
// This ensures we catch the crossover moment and don't buy if price is already way above.
double prevClose = iClose(Symbol(), Period(), 1);
double currentAsk = Ask;
Comment("Line Price: ", DoubleToString(linePriceCurrent, Digits), "\nAsk Price: ", DoubleToString(currentAsk, Digits));
if(prevClose < linePricePrevious && currentAsk > linePriceCurrent)
{
OpenBuyOrder();
}
}
//+------------------------------------------------------------------+
//| Function to Open Buy Order |
//+------------------------------------------------------------------+
void OpenBuyOrder()
{
double sl = 0;
double tp = 0;
// Calculate Stop Loss
if(InpStopLoss > 0)
sl = NormalizeDouble(Ask - InpStopLoss * Point, Digits);
// Calculate Take Profit
if(InpTakeProfit > 0)
tp = NormalizeDouble(Ask + InpTakeProfit * Point, Digits);
// Send Order
int ticket = OrderSend(Symbol(), OP_BUY, InpLotSize, Ask, InpSlippage, sl, tp, "TL Breakout", InpMagicNumber, 0, clrBlue);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
else
{
Print("Buy Order Opened Successfully. Ticket: ", ticket);
// Optional: Delete the line after trade to prevent re-entry
// ObjectDelete(0, InpTrendLineName);
}
}
//+------------------------------------------------------------------+
//| Helper: Count open trades for this EA |
//+------------------------------------------------------------------+
int CountOpenTrades()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber && OrderType() == OP_BUY)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
How to Setup and Use
-
Install the Code:
- Open MetaTrader 4.
- Press
F4to open the MetaEditor. - Click
New->Expert Advisor (template)-> Name it "TrendlineBreakout". - Paste the code above into the file, replacing everything else.
- Press
F7to Compile.
-
Prepare the Chart:
- Go back to the main MT4 window.
- Draw a Trendline on the chart where you want the breakout to occur.
- Crucial Step: Double-click the trendline to select it, right-click, go to
Properties->Commontab. Change the Name field toBuyLine.
-
Activate the Robot:
- Drag the "TrendlineBreakout" EA from the Navigator onto the chart.
- Ensure "Allow live trading" is checked in the Common tab.
- Ensure the "AutoTrading" button at the top of MT4 is Green.
Strategy Logic Explained
- Object Detection: The code uses
ObjectGetValueByShiftto mathematically calculate the price of the trendline at the current moment (Shift 0) and the previous candle (Shift 1). - Crossover Check: It checks if the Previous Candle Close was below the trendline AND the Current Ask Price is above the trendline. This confirms a fresh breakout.
- Trade Management: It calculates Stop Loss and Take Profit based on points and sends the order. It also checks
CountOpenTradesto ensure it doesn't open multiple trades on the same breakout tick.
Q&A
Q: Can I use a different name for the trendline?
A: Yes. In the Expert Advisor inputs tab when you attach it to the chart, change InpTrendLineName to whatever you prefer.
Q: Will this work for Sell trades?
A: This specific code is hardcoded for Buy trades only. To make it sell, the logic needs to be reversed (Previous Close > Line AND Bid < Line).
Q: What happens if the price is already above the line when I turn the robot on?
A: The robot will not trade. It specifically looks for the moment of the cross (Previous bar below, current price above). This prevents buying at a bad price if you restart the terminal.
Q: Does the trendline need to be extended to the right?
A: No. The function ObjectGetValueByShift calculates the mathematical trajectory of the line infinitely. However, visually extending it (Ray) helps you see where the price needs to go.