Generate code in 3 minutes
Enter your idea and AI generates runnable code.
Here is a complete, fully functional MQL4 Expert Advisor (robot) designed to buy when the price breaks above a specific trendline.
//+------------------------------------------------------------------+
//| 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;
}
//+------------------------------------------------------------------+
Install the Code:
F4 to open the MetaEditor.New -> Expert Advisor (template) -> Name it "TrendlineBreakout".F7 to Compile.Prepare the Chart:
Properties -> Common tab. Change the Name field to BuyLine.Activate the Robot:
ObjectGetValueByShift to mathematically calculate the price of the trendline at the current moment (Shift 0) and the previous candle (Shift 1).CountOpenTrades to ensure it doesn't open multiple trades on the same breakout tick.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.