Automated Trading EA for Entry & Close on Horizontal Line Break
I asked ChatGPT (GPTs) to create a useful tool (Expert Advisor – EA) that enables automatic entry and position closure based on a horizontal line break.
This EA allows you to set buy and sell horizontal lines on the chart. When the price breaks above or below these lines, the EA executes buy entries and closes sell positions, or executes sell entries and closes buy positions accordingly.
The EA also includes parameters for entry-only, close-only, and stop-loss settings.
GPT Used: EA Creator
Development Request & Results
I had to make several modifications and adjustments, but the final EA is fully functional and ready to use.
First Request
I requested an EA with the following specifications:
# Parameters
- Lot Size: Number of lots per order
- Buy Line Name: Used for buy entry & sell position closure
- Sell Line Name: Used for sell entry & buy position closure
- Entry & Close Check Interval (Seconds): Default is 1 second
- Additional parameters as needed
# Functionality
- The EA operates on the currency pair of the attached chart.
- It checks entry and close conditions at the interval specified by the user.
- Entry Conditions:
- No open positions exist.
- When a candle closes above the buy line, a buy entry is executed.
- When a candle closes below the sell line, a sell entry is executed.
- Position Close Conditions:
- If holding a buy position and the price closes below the sell line, the buy position is closed.
- If holding a sell position and the price closes above the buy line, the sell position is closed.
ChatGPT Output (First Version of the EA)
The following MQL4 code was generated. This EA monitors specified horizontal lines and executes buy/sell entries and position closures accordingly.
MQL4 Code Snippet:
//+------------------------------------------------------------------+ //| EA_LineBreakTrader | //| Copyright 2023, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property strict input double LotSize = 0.1; // Order lot size input string BuyLineName = "BuyLine"; // Buy horizontal line name input string SellLineName = "SellLine"; // Sell horizontal line name input int CheckIntervalSeconds = 1; // Entry & close check interval datetime lastCheckTime = 0; //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { datetime currentTime = TimeCurrent(); if (currentTime - lastCheckTime >= CheckIntervalSeconds) { lastCheckTime = currentTime; double buyLineLevel = ObjectGetDouble(0, BuyLineName, OBJPROP_PRICE); double sellLineLevel = ObjectGetDouble(0, SellLineName, OBJPROP_PRICE); CheckEntryConditions(buyLineLevel, sellLineLevel); CheckCloseConditions(buyLineLevel, sellLineLevel); } } //+------------------------------------------------------------------+ //| Check entry conditions | //+------------------------------------------------------------------+ void CheckEntryConditions(double buyLineLevel, double sellLineLevel) { if (OrdersTotal() == 0) { double open = iOpen(NULL, 0, 1); double close = iClose(NULL, 0, 1); if (close > buyLineLevel && open < buyLineLevel) { OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, 0, 0, "", 0, 0, clrGreen); } if (close < sellLineLevel && open > sellLineLevel) { OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, 0, 0, "", 0, 0, clrRed); } } } //+------------------------------------------------------------------+ //| Check close conditions | //+------------------------------------------------------------------+ void CheckCloseConditions(double buyLineLevel, double sellLineLevel) { for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS)) { double open = iOpen(NULL, 0, 1); double close = iClose(NULL, 0, 1); if (OrderType() == OP_BUY && close < sellLineLevel && open > sellLineLevel) { OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrBlue); } if (OrderType() == OP_SELL && close > buyLineLevel && open < buyLineLevel) { OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrOrange); } } } }
EA Explanation
Parameters
- LotSize: Order lot size
- BuyLineName: Name of the buy entry & sell close horizontal line
- SellLineName: Name of the sell entry & buy close horizontal line
- CheckIntervalSeconds: Interval for checking entry/close conditions (seconds)
OnTick Function
- Executes at the defined interval.
- Retrieves the horizontal line prices.
- Checks entry and close conditions.
Entry Condition Check
- If no open positions exist:
- If the last candle closed above the buy line, a buy order is executed.
- If the last candle closed below the sell line, a sell order is executed.
Close Condition Check
- If holding a buy position and the price closes below the sell line, the buy position is closed.
- If holding a sell position and the price closes above the buy line, the sell position is closed.
This EA automatically enters and exits positions based on horizontal lines drawn on the chart.
Second Request (Enhancements & Additional Features)
I requested the following enhancements to the EA:
Enhancements & Additional Features
- EA Name: Prefix “EA_” added to the name.
- OrderSend() Error Handling:
- Return values are checked.
- Errors are printed for debugging.
- Additional Parameters:
- Mode: (0 = Both, 1 = Entry Only, 2 = Close Only)
- PreventReEntry: Option to prevent re-entry at the same price.
- Updated Functionality:
- If “Entry Only” mode is selected, close conditions are ignored.
- If “Close Only” mode is selected, entry conditions are ignored.
- If “Prevent Re-Entry” is enabled, the EA does not re-enter at the same price unless the horizontal line is moved.
ChatGPT Output (Second Version of the EA)
//+------------------------------------------------------------------+ //| EA_LineBreakTrader | //| Copyright 2023, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ #property strict input double LotSize = 0.1; // Order lot size input string BuyLineName = "BuyLine"; // Buy horizontal line name input string SellLineName = "SellLine"; // Sell horizontal line name input int CheckIntervalSeconds = 1; // Entry & close check interval input int Mode = 0; // 0: Both, 1: Entry Only, 2: Close Only input bool PreventReEntry = true; // Prevent re-entry at the same price datetime lastCheckTime = 0; double lastBuyLineLevel = 0; double lastSellLineLevel = 0; //+------------------------------------------------------------------+ //| Initialization function | //+------------------------------------------------------------------+ int OnInit() { lastBuyLineLevel = ObjectGetDouble(0, BuyLineName, OBJPROP_PRICE); lastSellLineLevel = ObjectGetDouble(0, SellLineName, OBJPROP_PRICE); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Tick function | //+------------------------------------------------------------------+ void OnTick() { datetime currentTime = TimeCurrent(); if (currentTime - lastCheckTime >= CheckIntervalSeconds) { lastCheckTime = currentTime; double buyLineLevel = ObjectGetDouble(0, BuyLineName, OBJPROP_PRICE); double sellLineLevel = ObjectGetDouble(0, SellLineName, OBJPROP_PRICE); if (Mode == 0 || Mode == 1) CheckEntryConditions(buyLineLevel, sellLineLevel); if (Mode == 0 || Mode == 2) CheckCloseConditions(buyLineLevel, sellLineLevel); lastBuyLineLevel = buyLineLevel; lastSellLineLevel = sellLineLevel; } } //+------------------------------------------------------------------+ //| Entry Conditions Check | //+------------------------------------------------------------------+ void CheckEntryConditions(double buyLineLevel, double sellLineLevel) { if (OrdersTotal() == 0) { double open = iOpen(NULL, 0, 1); double close = iClose(NULL, 0, 1); if (close > buyLineLevel && open < buyLineLevel && (!PreventReEntry || buyLineLevel != lastBuyLineLevel)) { int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, 0, 0, "", 0, 0, clrGreen); if (ticket < 0) { Print("Buy OrderSend failed with error #", GetLastError()); } } if (close < sellLineLevel && open > sellLineLevel && (!PreventReEntry || sellLineLevel != lastSellLineLevel)) { int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, 0, 0, "", 0, 0, clrRed); if (ticket < 0) { Print("Sell OrderSend failed with error #", GetLastError()); } } } } //+------------------------------------------------------------------+ //| Close Conditions Check | //+------------------------------------------------------------------+ void CheckCloseConditions(double buyLineLevel, double sellLineLevel) { for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS)) { double open = iOpen(NULL, 0, 1); double close = iClose(NULL, 0, 1); if (OrderType() == OP_BUY && close < sellLineLevel && open > sellLineLevel) { if (!OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrBlue)) { Print("Buy OrderClose failed with error #", GetLastError()); } } if (OrderType() == OP_SELL && close > buyLineLevel && open < buyLineLevel) { if (!OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrOrange)) { Print("Sell OrderClose failed with error #", GetLastError()); } } } } }
Request Details (3rd to 7th revision)
Please make the following modifications:
- Remove the initialization (OnInit) process that retrieves the initial price of the horizontal line.
- If a horizontal line is drawn before the EA is set, the initial entry will not be executed.
- The update of the line level for re-entry prevention should only be performed upon order completion, separately for buy and sell orders.
- After executing a buy trade, selling should still be possible, and vice versa.
The parameter Slippage is missing, so please add it.
Please make the following modifications:
Parameters
- Stop Loss Width (Specified in pips. Default value is 0. Determines the position of the stop-loss order relative to the order price.)
Specifications
- When placing an order, set a stop-loss order at a negative value relative to the order price, based on the specified stop-loss width.
- If the stop-loss width is set to 0, no stop-loss order will be placed.
Please make the following modifications:
Parameters
- Name of the Buy Stop Horizontal Line
- Name of the Sell Stop Horizontal Line
Specifications
- For a buy order, if the buy stop horizontal line is set below the order price, set the stop-loss order at the price of that line.
- For a sell order, if the sell stop horizontal line is set above the order price, set the stop-loss order at the price of that line.
- This takes priority over the stop-loss width setting.
Please make the following modifications:
If BuyStopLine does not exist,
buyStopLineLevel
will be set to0
. Since this value is always smaller thanAsk
, the stop-loss order will be placed at0
.
- Please add a condition to check that
buyStopLineLevel != 0
.- Remove the “no open positions” condition from the entry requirements.
ChatGPT Output (Seventh Version of the EA)
We will modify and provide the EA’s MQL4 code based on the following specifications.
Changes:
- Added parameters for the names of horizontal lines for Buy Stop and Sell Stop.
- When placing a Buy order, if the price of the Buy Stop horizontal line is below the order price, the stop-loss is set to that line’s price.
- When placing a Sell order, if the price of the Sell Stop horizontal line is above the order price, the stop-loss is set to that line’s price.
- The price of the horizontal line takes precedence over the stop-loss width setting.
//+------------------------------------------------------------------+ //| EA_LineBreakTrader | //| Copyright 2024, SeSe | //| https://fx-trading-gym.info/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, SeSe" #property link "https://fx-trading-gym.info/" #property version "1.00" #property strict input double LotSize = 0.1; // Order lot size input string BuyLineName = "BuyLine"; // Name of the horizontal line for Buy entry input string SellLineName = "SellLine"; // Name of the horizontal line for Sell entry input string BuyStopLineName = "BuyStopLine"; // Name of the horizontal line for Buy Stop input string SellStopLineName = "SellStopLine"; // Name of the horizontal line for Sell Stop input int CheckIntervalSeconds = 1; // Interval (in seconds) for checking entry and close conditions input int Mode = 0; // 0: Both, 1: Entry only, 2: Position close only input bool PreventReEntry = true; // Enable/disable re-entry prevention input int Slippage = 3; // Slippage input double StopLossPips = 0; // Stop-loss width (specified in pips) datetime lastCheckTime = 0; double lastBuyLineLevel = 0; double lastSellLineLevel = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { datetime currentTime = TimeCurrent(); if (currentTime - lastCheckTime >= CheckIntervalSeconds) { lastCheckTime = currentTime; // Retrieve the price of the horizontal lines double buyLineLevel = ObjectGetDouble(0, BuyLineName, OBJPROP_PRICE); double sellLineLevel = ObjectGetDouble(0, SellLineName, OBJPROP_PRICE); double buyStopLineLevel = ObjectGetDouble(0, BuyStopLineName, OBJPROP_PRICE); double sellStopLineLevel = ObjectGetDouble(0, SellStopLineName, OBJPROP_PRICE); // Check entry conditions if (Mode == 0 || Mode == 1) CheckEntryConditions(buyLineLevel, sellLineLevel, buyStopLineLevel, sellStopLineLevel); // Check close conditions if (Mode == 0 || Mode == 2) CheckCloseConditions(buyLineLevel, sellLineLevel); } } //+------------------------------------------------------------------+ //| Check entry conditions | //+------------------------------------------------------------------+ void CheckEntryConditions(double buyLineLevel, double sellLineLevel, double buyStopLineLevel, double sellStopLineLevel) { if (OrdersTotal() == 0) { double open = iOpen(NULL, 0, 1); double close = iClose(NULL, 0, 1); // Buy entry conditions if (close > buyLineLevel && open < buyLineLevel && (!PreventReEntry || buyLineLevel != lastBuyLineLevel)) { double sl = 0; if (buyStopLineLevel < Ask) { sl = buyStopLineLevel; } else if (StopLossPips > 0) { sl = NormalizeDouble(Ask - StopLossPips * Point, Digits); } int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, sl, 0, "", 0, 0, clrGreen); if (ticket < 0) { Print("Buy OrderSend failed with error #", GetLastError()); } else { lastBuyLineLevel = buyLineLevel; // Update upon successful order placement } } // Sell entry conditions if (close < sellLineLevel && open > sellLineLevel && (!PreventReEntry || sellLineLevel != lastSellLineLevel)) { double sl = 0; if (sellStopLineLevel > Bid) { sl = sellStopLineLevel; } else if (StopLossPips > 0) { sl = NormalizeDouble(Bid + StopLossPips * Point, Digits); } int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, sl, 0, "", 0, 0, clrRed); if (ticket < 0) { Print("Sell OrderSend failed with error #", GetLastError()); } else { lastSellLineLevel = sellLineLevel; // Update upon successful order placement } } } } //+------------------------------------------------------------------+ //| Check close conditions | //+------------------------------------------------------------------+ void CheckCloseConditions(double buyLineLevel, double sellLineLevel) { for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS)) { double open = iOpen(NULL, 0, 1); double close = iClose(NULL, 0, 1); // Close Buy positions if (OrderType() == OP_BUY && close < sellLineLevel && open > sellLineLevel) { if (!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrBlue)) { Print("Buy OrderClose failed with error #", GetLastError()); } } // Close Sell positions if (OrderType() == OP_SELL && close > buyLineLevel && open < buyLineLevel) { if (!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrOrange)) { Print("Sell OrderClose failed with error #", GetLastError()); } } } } }
Explanation
Parameters:
- LotSize: Order lot size
- BuyLineName: Name of the horizontal line for Buy entry
- SellLineName: Name of the horizontal line for Sell entry
- BuyStopLineName: Name of the horizontal line for Buy Stop
- SellStopLineName: Name of the horizontal line for Sell Stop
- CheckIntervalSeconds: Interval (in seconds) for checking entry and close conditions
- Mode:
0 = Both
,1 = Entry only
,2 = Position close only
- PreventReEntry: Enable/disable re-entry prevention
- Slippage: Slippage
- StopLossPips: Stop-loss width (specified in pips)
Initialization (OnInit)
- No specific initialization required.
Tick Event (OnTick)
- Checks positions at specified intervals.
- Retrieves the price of horizontal lines and evaluates entry and close conditions.
Entry Condition Check (CheckEntryConditions)
- Evaluates Buy and Sell entry conditions based on the price of horizontal lines.
- If the Buy Stop line is below the order price, it is used as the stop-loss.
- If the Sell Stop line is above the order price, it is used as the stop-loss.
- If the stop-loss width is non-zero, it is set upon order placement, but the horizontal line price takes precedence.
- If conditions are met, a new order is placed. Errors are displayed if the order fails.
- If the order is successful, the horizontal line level is updated to prevent re-entry.
Close Condition Check (CheckCloseConditions)
- Evaluates Buy and Sell position close conditions.
- If conditions are met, the respective position is closed. Errors are displayed if closing fails.
📥 Download the Indicator
🚀 Get instant access to the Higher Timeframe MA & High/Low Indicator!
You can download the created EA below. While basic functionality has been tested, we cannot compensate for any losses incurred from its use. Please use it at your own risk and verify its operation thoroughly.
👉 Download Now (Unlock content to access the file)
📢 Looking for More Trading Tools?
Explore my blog for more free MT4 indicators and trading strategies!
👉 Visit FX Trading Gym
🚀 Thank You for Using Our Tools! A Small Favor to Ask 🚀
Thank you so much for choosing our FX indicators and tools!
To support your success in FX trading, we’ve carefully selected some services that can help you achieve better results.
If you find them useful, we’d greatly appreciate your support.
Your participation will not only motivate us but also help us continue to develop even better tools for you in the future!
💼 Increase Your Profits with an Overseas FX Account!
🌍 Exness Account – The Broker I Trust the Most!
- Industry-low spreads to reduce trading costs
- Fully compatible with MT4/MT5, perfect for automated trading (EA)
- Instant withdrawals for smooth fund management
👉 Open an Exness Account Now (Special Offer)
💸 Reduce Trading Costs with Cashback from Overseas FX Accounts!
🚀 TariTali – High Cashback Rates That Make a Difference!
- Maximize savings with high-rate cashback on every trade
- Supports a wide range of MT4/MT5 brokers, ideal for EAs
- Real-time tracking of your cashback history
- Fast withdrawals to domestic bank accounts
👉 Cut Your Trading Costs Smartly with TariTali!
🔥 Money Charger – The New Standard for Forex Cashback!
- Automatic cashback on every trade → The more you trade, the more you earn!
- Industry-leading cashback rates for maximum profit efficiency
- Simple registration with instant cashback available
- Supports multiple brokers, giving you flexible account choices
👉 Start Earning Cashback with Money Charger Today!
More details: Complete Guide to Forex Cashback
🤖 Accelerate Your Profits with Automated Trading Systems (EAs)!
🔥 Introducing High-Performance EAs I’ve Developed
- Poundeur (HL Band M15 for GJ) → The best choice for stable profits
- BBHL Band H1 for EJ & BBHL Band H1 for AJ → Excellent performance even in high-volatility markets
👉 Discover Our Profitable MT4 EAs for FX Traders
📊 Check Out the Most Popular EAs!
- Handpicked EAs trusted by many traders
- Performance records and profit data are publicly available
👉 See the Top-Ranked EAs Now
コメント