I have been fascinated with the grid trading concept since crypto, and I wanted to do it on a safer asset, and forex seemed like a good choice initially, not so much now, since I need to take into account funding rates.
Anyway, in this post, I’m going show you how I wrote a simple grid trading bot in MQL4 for MT4.
Some caveats before starting, I am still learning MQL4, so I have no idea if what I am doing is considered best practices.
This bot will place a defined number of buy limit or buy stop limit orders that are equally spaced between the defined upper and lower range.
To create a new mq4 file, on your MetaEditor, Go to File -> New ->Expert Advisor (Template) -> (enter a name for your file e.g. SimpleGridTest) -> and click on Next until you reach Finish. This should create a file name SimpleGridTest.mq4.
Usually I would removed all the commented lines, which means all the gray lines. I will also remove all the #property tags, leaving me with this.
User Inputs
In a grid trading bot we will need some standard inputs from the user. This includes:
- upperRange – This defines the high price.
- lowerRange – This defines the low price.
- gridLevels – This defines the number of level (or orders) to place within the given range.
- lotSize – self explanatory
- magicnumber – This defines the magic number that you will use for this EA
We will place these before the OnInit()
function.
The default value of all the inputs are set to 0. If we accidentally run the bot without any input, no orders will be placed, since the upper and lower ranges are set to 0.
Defining variables and struct
Next we will create a struct
named OrderDetails
. This will hold the details of an grid order, in this case, it just holds the price
and the takeProfit
levels. This can go after the inputs.
When creating a grid bot, we need to calculate the number of orders, the price and take profit levels for each order. We store all these details in an array called startingOrderlistForRange[]
.
We also need another array called CurrentTicketsTakeProfitList[]
to store all the take profit levels of all pending orders and positions.
OnInit function
Now that we have declared all the inputs and global variables that we need, it is time to move on to the OnInit()
function. It is going to look something like this.
We will do some simple checks to make sure that the input parameters are not 0.
We will also populate the initial list of price and take profit levels based on the given inputs. This will be done in a function called PopulateStartingOrderList
.
OnTick function
Next we move on to the OnTick()
function. This is where the logic of the grid bot takes place.
We start off with a simple logic.
If there are no existing pending orders or positions, we will create the initial orders. If the current pending orders and orders are less than the gridlevels, then we will need to create new orders to replace the closed positions.
Creating the initial orders
There are 2 things that we do here:
- Loop through the
StartingOrderlistForRange[]
- Determine if it will be a Buy Limit Order or a Buy Stop Order
The PlaceOrder
is a simple function to place buylimit or buystop orders.
Replacing closed positions
In order to create new orders to replaced the closed positions, we will create 2 functions GetCurrentTickets
and PlaceMissingOrders
.
GetCurrentTickets
– to get the profit price list of all the pending orders and positions.PlaceMissingOrders
– to create new orders to replace the closed positions
The GetCurrentTickets
will loop through existing orders and positions and write the profit price to an array.
The
will use compare the and find the missing order and place the order.PlaceMissingOrders
To run it, you just need to compile the code. And on the strategy tester, you can then back test it.
Please note that you should not be using this for live trading, as this is a very basic and simple piece of code. I have not added much error handling to it.