Table of contents:
Forex Diagram is MT5 code generator. It helps you create MT5 Expert Advisors (EA) using diagrams with building blocks.
Only MT5 supported at this time. If you are looking for a tool to create MT4 EA then please look at Forex Generator .
Technical requirement for diagrams: recent Internet browser such as Chrome, Firefox or MS Edge. Old Internet Explorer browsers are not supported.
Start your first EA with just handful of blocks. Your first EA can just check one or few market conditions and open positions.
Begin small and grow it. Use "Print to Log" blocks to monitor how other blocks get executed.
Normal development cycle is: add 4-6 blocks, download code and test EA in the terminal. Repeat.
Subscription gives you unlimited saved diagrams and no limit on how many blocks you can place on the diagram.
Without subscription there is a limit of 15 blocks per diagram.
Consider purchasing subscription for serious EA development.
Download button generates EA source code in MQL5 format.
Downloaded source code has to be compiled before EA can be used by MT5.
Compile it using MetaEditor that comes with the terminal.
You can find folder where to place your downloaded EA inside terminal "Open Data Folder" menu.
Open data folder and navigate into MQL5\Experts subfolder.
Copy EA file into MQL5\Experts subfolder, then open EA file in MetaEditor and compile it.
It is good idea to run download and compilation every 4-6 new blocks that you add into the diagram.
This way if compilation fails you will know what blocks caused the problem.
When fixing compilation errors first look for manually entered functions inside "If..." type blocks.
Manually typed-in functions and indicators tend to cause most problems. Single typo can break compilation.
Building blocks are at the heart of diagram creation process.
Building blocks have input and output connectors. Exception is "On..." type blocks that do not have input connector.
Example: "Open Position" block has two output connectors. If position is open without errors then blocks connected to "Ok" will be executed.
If opening of position fails then blocks connected to "Failed" connector will be executed.
Place multiple blocks on the diagram and connect them to generate functional EA.
Blocks that have more than one connector can be used in few different ways. If you have a block with both "Yes" and "No" connectors then
you can connect other blocks to only "Yes" or only "No" connector or connect different blocks to both connectors.
Reading diagrams is an important skill. Well designed diagrams read like English or any other spoken language.
Start reading diagram from "On..." type block and continue via connectors to the last block in the chain.
One way to read this diagram:
On tick, check if indicator technical analysis is Yes, check if position is not open yet, then Open Position, print to log if fails.
"If" block is used for technical analysis via indicators and functions.
"If Positions Exist" block is used for checking if there is open position already.
Combine this block with one of "Only..." type blocks for more precise checking. "Only..." type blocks covered below.
Typical diagram contains many building blocks. During code generation building blocks get converted into EA source code.
Each block chain becomes sequence of functions connected together.
Note important points: diagrams contain block chains that start with On... type blocks.
After that you have number of If... and/or Only... type blocks.
Block chain usually ends with action blocks. Like "Open Position" or "Close Position", etc.
You can have multiple block chains. Each having different purpose. Do not need to connect them to a single "On Tick" block.
Instead place few "On Tick" blocks, and have few block chains responsible for different features of the EA.
Add blocks by right clicking on the diagram or clicking on main screen "Add" button.
"Add Block" screen lets you add multiple blocks at once. You can also search for a block or sort table by clicking on its header.
Red circle demonstrates that clicking on the Group sorts table by group.
Forex Diagram contains few different types of blocks:
Each block type has a chapter below explaining it in more detail.
Forex Diagram can have few block chains. Each block chain needs "On..." block to start it.
"On Tick" is most common block used to start block chains. It executes connected blocks on every tick.
"On..." type blocks do not have input connector. You can have number of "On..." type blocks in a single diagram.
If you setup few "On Tick" blocks each with its own block chain then each chain will execute on every tick.
"On New Bar" block runs blocks connected to it only when new bar starts.
So if you have EA placed on H1 timeframe then "If" block will be executed only once an hour.
It also means that if you have no "On Tick" block in your diagram all the events that happen during that hour will be ignored by EA.
A lot of action can happen in Forex market in 1 hour.
There are cases when "On New Bar" block is useful. One example would be trading on long timeframes.
"If..." blocks check for conditions and events.
Whenever you need to check for specific market situation, check current already open positions, check your EAs recent trading history
or check any other conditions then you need one or few "If..." blocks.
Each "If..." block asks a question, gets an answer and executes specific connected block chain.
Most answers are of Yes/No variety.
There is generic "If" block used to compare indicators, functions, variables and fixed values.
It is main block for technical analysis.
"If..." blocks can be used for so much more than just technical analysis.
In the diagram above "If Positions Exist" checks if there is already position open. If answer is "No" then new position is open.
This is simple way to prevent opening more positions when there is already at least one position open.
Many "If..." blocks need to compare values. Typical notation when comparing values is using greater and less signs:
> means "greater than"
< means "less than"
>= means "greater than or equal"
=< means "less than or equal"
== means "equal"
!= means "not equal"
In the diagram above we compare profit:
if it is greater than 10 pips then close positions.
"If Positions Profit" sums all the profits of positions. Combine it with "Only..." blocks and you can calculate profits of only selected positions.
select positions with magic numbers and if sum of them is below -100 pips (100pip loss) then close selected positions and stop EA.
"Only..." blocks select specific positions, pending and history orders.
Once filter is applied use "If..." and action blocks to work with selected positions, pending and history orders.
Example: if you only interested in specific open positions with unique Magic numbers then use "Only Positions Magic" or "Only Positions List" blocks.
Once you connect them all blocks connected after "Only..." block will only see current filtered positions (filtered by Magic numbers).
Red circles show points where filtering has been applied.
"If Positions Exist" only checks if there are positions with specific Magic numbers. If there are no such positions then new position is open.
"Modify Positions" block also modifies only positions with specific Magic numbers.
Diagram displayed above will close all positions.
Diagram above will close all positions of the type set in "Only Positions Type" block.
Diagram above will close all positions of the type set in "Only Positions Type" and magic numbers set in "Only Positions Magic" blocks.
Each "Only..." selects specific postions for following "Close Positions" to close.
This arrangement above is not correct. "Only Positions Type" is useless here.
"Only Positions Type" will select positions based on type but next "Only Positions Magic" will cancel that selection
and only select positions based on Magic numbers to be closed by "Close Positions".
This shows that each "Only..." is independent from all other "Only" blocks, and resets any prior filters before making new selection.
If you want to select positions that have magic number in the list and are of specific type use "Only Positions List".
"Only Positions List" is combination of "Only Positions Type" and "Only Positions Magic" blocks.
Another way to think about "Only..." blocks is that they are queries or selectors.
Useful if you want to select specific open positions, pending or history orders and then ask questions or perform actions on them.
Ask questions using "If..." blocks.
By themselves "Only..." blocks are not very useful. They just select specific positions or orders. You need other blocks in order to use selected list.
Therefore it is important to use "Only..." blocks in combination with "If..." or action blocks.
In this example "Only Positions Magic" filters all open positions except positions with specific magic number.
Then Trailing Stop block trails only those positions.
First use "Only..." type block to get only positions, pending or history orders you are interested in.
Then use "If..." or action blocks on them.
Action blocks perform operations: open, modify or close orders. Most action blocks can be used anywhere.
But they are most useful at the ends of long chains of blocks after "Only..." and "If..." blocks.
Example: "Close Positions" block will close all open positions if connected directly to "On Tick" block.
If you add "Only Positions Type" in front of it, then only specific position specified in "Only Positions Type" will be closed.
By combining "Only..." blocks with other blocks you can select only specific positions or orders and perform actions on them.
This diagram has three action type blocks: "Close Positions", "Open Position" and "Trailing Stop".
Trailing Stop and Break Even blocks are expectional since they have to check current open positions and may modify them on every tick.
They combine monitor/modify operations into one single block. Connect them directly or almost directly via "Only..." to a "On Tick" block.
If Trailing Stop and Break Even block is not going to receive every tick then it will miss an opportunity to trail open positions.
Number of action blocks let you attach additional blocks to "Failed" connector.
Failures can happen for number of reasons: requotes, invalid stoploss or takeprofit, connection problems, etc.
It makes sense to execute special action on failure. Example: retry same action but with wider stoploss and takeprofit.
Or simply print failure information to log for analysis later.
You can attach additional blocks to both "Ok" and "Failed" connector.
In this case "Delete Pending" will get executed no matter if "Close Positions" fails or succeeds.
There are blocks that do not perform trading actions but help diagnose problems or provide additional information during trading.
"Print to Log" is one such block.
"Print to Log" block provides simple insight into executing EA. You can place it anywhere after "On..." type block.
Make sure to enter unique text message to be printed in the MT5 Experts tab.
In this example message will be printed to MT5 Experts tab if indicator crosses down.
During testing you might have number of "Print to Log" blocks placed throughout the diagram. It is simple but effective way to monitor EA execution.
"Print Functions" block prints value of expression into the chart window. You can print indicators, functions and even complex expressions.
It is simple way to see functions and indicator values during EA execution.
Use this block as a quick way to make sure formula you have crafted produces expected result and can be used in other blocks.
Once position is open and market price moves away from it price gap forms. It is a gap between original position opening price and current bid/ask.
If position is in profit then gap is positive and if position is in loss then gap is negative.
Ability to track price gap and react to it at certain levels is important. Example: close position at 10 pips of profit.
There are few blocks that help you work with the price gap. One of them is "Only Positions Gap" block.
It selects all the positions that are in set price gap range. Once positions selected you can work with them using other blocks.
Other blocks that work with price gap are: "Break Even" and "Trailing Stop" blocks.
Negative gap can be useful for tracking losses and closing retracted positions. When gap is negative then scale is inverted.
Best way to read it is to look at "Below" value. In the diagram -10 reads as:
once position is loosing 11 pips, then close it.
Same idea applies to blocks that work with "Profit". If profit is negative then it is a loss.
If you want to track loss then use "Profit" parameter but enter it with minus sign.
You may also need to adjust other parameters of the block to property work with negative value.
"Only Positions Gap" is very versatile block.
In the first diagram above it acts as virtual takeprofit. Takeprofit is set in the EA and broker does not see it.
It acts as virtual stoploss in the second diagram.
It can work in many different scenarios when combined with other blocks.
Example: watch first position for 10 pip profit (10 pip Gap) and then open second position to hedge or to add to existing position.
You can also have multiple steps of building up the position by combining few "Only Positions Gap" and "if Condition" blocks.
Let say you have a very long block chain that uses "Only..." and performs some actions.
But after actions are performed you also want to use "If..." or action blocks on all positions or orders again.
Simplest solution is to create another separate block chain. But sometimes it results in a lot of duplicated blocks.
Another solution is to select all positions and orders. After "Select All" another "If..." and action can be used targeting all positions and orders.
Block "Select All" is like filter reset.
You should use "Select All", when you want to work with all positions and orders if filtering was used in chain of blocks.
No need to use it just after any of "On..." blocks because if there is no filtering yet, then there is no need to reset filters with "Select All".
Diagram produces currency pair isolated code.
When EA is attached to the chart inside MT5 it can only see and work with orders placed on that same currency pair.
So if you have another EA placed on other currency pair then they will not directly interfere.
Two EAs placed on different currency pairs will still share global variables such as account balance, margin, etc.
If first EA will deplete account balance second EA will not be able to trade.
Magic number is additional information (integer number) you can assign to the orders opened by your EA.
You can pick the numbers and use them to better identify your orders. Then use blocks "Only Positions Magic" and
"Only Pending Magic" to filter orders with specific magic numbers.
Simple example of Magic number use is to assign 1 to first and 2 to second open position. Now you can trail the first
position and perform partial close on the second position because each can be identified by unique Magic number.
Magic numbers are magical in a sense that you can use them in any way you see fit.
You can also use ranges of magic numbers. If magic number falls into the range above 0 and below 10 perform one action on it.
If magic number is in range above 10 and below 20 do something else.
Possibilities are infinite. But can get confusing if you do not have clear system on how to use them.
If you are working on your very first EA it might be better to avoid magic numbers.
You can specify ranges of magic numbers.
There is however one important Magic number assigned by the terminal. Positions and orders opened manually have Magic number zero.
Zero is a default value for manual orders.
It is important to know if you want to create EAs that manage orders originally opened outside of EA.
Open position is main block for opening simple buy and sell positions.
This diagram "If" block checks market for conditions then uses "If Positions Exist" then if no position is currently open
opens new position with magic number 1.
Both magic number and type are important since you can use them later and select open positions using "Only Positions Magic",
"Only Positions Type" and "Only Positions List" blocks.
You can setup your indicators based on MT5 built-in or imported custom indicator.
Once indicator is setup use it in "If" and other blocks that need them.
Give your indicators memorable and clear names.
It helps to have a naming system. That way names are consistent and convey meaning to you.
If you import custom indicator from .mq5 file it has to be in your MT5 "Indicators" folder to be loaded by the terminal and EA.
Custom indicator you are importing has to be in source code format with file extension .mq5.
While all MT5 built-in indicators return values some custom indicators found online do not return values.
When custom indicator does not return value it can not be directly used by EA.
If you find nice and useful custom indicator online make sure it has documentation on the values it returns.
Without documentation indicator is not very useful unless you can read the source code and find what values it returns.
Each indicator has its own set of parameters. Most parameters are self-explanatory.
Check boxes next to parameters let you export them. Exported indicator parameters become EA input parameters.
"bar_index" is a special parameter available for all indicators. It defaults to a current value of the bar.
It also lets you read not just current value of the indicator but prior values as well.
Access prior values by adding numeric index to the current value.
current is case sensitive.
When "bar_index" is set to current+1 it will return indicator's prior bar value.
If you want prior prior value use current+2 and so on.
Each increase in index will take you one more step back-in-time.
"If Cross Up" and "If Cross Down" building blocks use "current" for internal operations.
You have to use "current" when working with these blocks.
When indicator is setup you can use it in number of blocks.
current is case sensitive.
Use it to access bar values in a way similar to how you access indicator prior values.
Each increase in index takes you one more step back-in-time.
Close(current) will give you current bar close value.
Close(current+1) will give you prior bar close value.
Close(current+2) will give you prior prior bar close value.
and so on...
Once you get used to how indexing works you can omit word "current" all together, and use zero for current bar:
Close(0) will give you current bar close value.
Close(1) will give you prior bar close value.
Close(2) will give you prior prior bar close value.
You can compare bar values using "If" block. Diagram above reads as:
If current bar close is greater than previous previous bar close then open position.
You can compare bar values with indicator values using "If" block too. Diagram above reads as:
If previous bar close is less than MyMovingAverage then open position.
If you are using currency pair that has pip values in 4th-digit then you can also add or remove pip values.
Example: EURUSD. In this case 1 pip is 0.0001.
Close(current+1) + 0.0002 will add 2 pips to prior bar close value.
Close(current) - Close(current+1) + 0.0005 will take a difference of current bar close value and prior bar close value and add 5 pips.
You can compare bar values with fixed values. Diagram above reads as:
If difference between previous bar close and previous previous bar close is more than 15 pips then open position.
Close(1) - Close(2) is the same as Close(current+1) - Close(current+2) when used inside "If" block.
Use whatever feels more natural to you.
You can compare bar values with fixed negative values. Diagram above reads as:
If difference between previous bar close and current bar close is more than -15 pips then open position.
You are not limited to only positive number values.
Number of indicator and block parameters can be exported. Once exported they are accessible when placed on the chart and backtesting.
Diagram source code generator names exported parameters for you. Name is made by combining indicator name and parameter name.
When you hover over the checkbox with a mouse pointer exported name is displayed.
When parameter is exported default value is set to the value you have entered in the diagram.
Exception is "bar_index" indicator parameter. It defaults to zero (current bar).
You can enter functions and indicators directly into fields that expect them.
For longer expressions and multiple functions use expression builder accessible via "..." button.
Start building expressions using simple logic first.
Make sure indicator you are using returns value in range you expect.
There are on-screen buttons for basic math operations. But all expressions let you edit them directly via keyboard.
Example: Close(current) - Close(current+1) will give you current bar closed value minus last closed bar value.
You get difference in how price changed between current and previous bar.
Keep in mind that if prior bar was higher then price has fallen and result of this expression will be below zero (negative).
Sometimes it is not possible to express logic that you need using just functions and built-in indicators.
In that case consider looking for custom indicator online. There are thousands of custom indicators built for MT5.
All you need is documentation on indicator return values and source code file with extension .mq5.
"If" is most important block for checking market conditions.
"If Cross Up" and "If Cross Down" are easier to use but only work when you want to check indicator crossing.
The way you connect blocks makes a big difference. There are two basic ways to connect blocks: sequential and parallel.
Read blocks connected one after the other (sequentially) as if they are joined with word "and".
If this condition is met and this second condition is met then Open Pending.
Read blocks connected in parallel as if they are joined with word "or".
If this condition is met or this other condition is met then Open Pending.
There are trading scenarios when EA has to remember certain market condition and then use that saved condition later
as an additional piece of information to perform actions.
Use "Set Condition" and "If Condition" blocks in this case.
In this simple example we save indicator cross down condition. Then we can combine this information with other technical
analysis blocks later after many ticks and new bars. Combined information will let us act on both new information and old.
Condition names are case sensitive. If you plan to have many of them it is best to have a system on how to name them consistently.
"If Condition" check has to use the same Condition name.
There is also "Unset Condition" block that removes prior condition.
Conditions are important tool when you need to combine different signals and act on information gathered in the past.
Conditions are cleared if EA is restarted.
You can find order history in MT5 History tab.
Blocks that start with "If Last..." and "Only History..." work with that history.
It is important to remember that history is shared with all the EAs that use or have used same currency pair.
If you restart same EA it will also see its prior orders in history. Depending on your EA design this may cause problems.
This makes working with history a bit tricky. Special attention might be required for cases when EA is restarted.
Restarted EA might pick up last closed orders from history and make wrong decisions.
Depending on EA setup you might need to clear history before using blocks that work with history.
History deal profits values are in monetary amounts not in pips.
"On Init" block executes only once when EA starts. It runs before any other blocks during EA initialization.
One way to know if EA has been restarted is to use "On Init" and "Set Condition" blocks to set condition indicating restart.
Later during rest of EA execution use "Unset Condition" to remove restart condition flag when you no longer need it.
Opens new position with lot volume based on last closed position.
In the example above 50 % Percent means that new position will be open with half of the lots of prior already closed position.
"Open Risk Last" can be used in number of order management techniques including Martingale. If Percent parameter is 200 % then
new order lots will be doubled.
It might be important to clear history before using EA with this block.
"Break Even Lots" closes part of the position at break even point.
In the diagram above break even point is 10 pips away. Select only older positions then once market price moves 10 pips into profit direction
execute partial close on the positions and leave only 0.1 lots open per position.
"Trailing Stop" trails open position by monitoring and modifying it in the process.
Once current market price moves away from the opening price trailing stop will modify stoploss and takeprofit by moving it closer to market price.
There are number of parameters that change how trailing is performed and if takeprofit is also trailed.
You can setup small diagram that opens just one position and then trails it. Adjust trailing parameters to see how they affect trailing.
In the diagram above trailing stop works only on positions with specific magic numbers because of "Only Positions Magic" block.
Minimum Profit is one of the main parameters. If it is zero then trailing will start as soon as Initial Trailing Step is met.
Example: If Minimum Profit is 5 pips then trailing can start only when at least 5 pips can be profited.
If Lock Lots parameter is not zero then "Trailing Stop" will also perform partial close of the position at each trailing step.
Example: if original position was 0.4 lots and Lock Lots is set to 0.1 then on each trailing step block will partial close 0.1 lots.
That way in four steps position will be closed completely.
If original position was open with zero takeprofit (infinite takeprofit) then trailing stop will not trail takeprofit.
"Trailing Stop" block is complex, and even small changes to its parameters result in big differences in its execution.
"Trailing Stop SAR" and "Trailing Stop MA" blocks trail using SAR or Moving Average (MA) indicators.
SAR seems to be better suited signal for trailing than Moving Average.
"Execute After N" skips number of triggers come from blocks connected to the input.
"If" block compares few indicators and executes connected "Execute After N" block when conditions are met.
"Execute After N" does not execute "Open Position" instantly but waits for 5 ticks (5 signals from "If" block) to confirm it.
5 ticks maybe none consecutive.
"Execute After N" has no reset mechanism making this block less useful just by itself.
Combine this block with "if/Set Condition" blocks.
Diagram has slightly changed but execution is very different.
"Execute After N" does not execute "If" instantly but only every 5 ticks.
"If" block compares few indicators and executes connected "Open Position" block when conditions are met.
You can switch off block chains during testing and experimentation.
Use "Disabled" block to turn off part of the EA.
You can also export Disabled parameter and make it possible to switch on/off parts of EA when it is placed on the MT5 chart.
"Disabled" block should be rarely used.
Having too many "Disabled" blocks in a diagram makes it hard to understand what parts disabled and what parts are enabled.
You can stop EA and remove it from the chart. Useful for critical situations when trading has to stop for investigation and analysis.
In this scenario once break even has been triggered we terminate EA.
Not a critical situation just want to stop EA trading when break even happens.
Note that "Terminate" block does not have any output connectors.
You can use "Save As" to create unrelated EA diagrams.
There is also another way of using "Save As".
Create base diagram with common components. Then try different scenarios of final EA and refine.
"Save As" is helpful at exploring vast space of your EA possibilities via step-by-step process.
By saving diagram multiple times during your exploration you can go back in time and create a separate branch
with yet unexplored possibilities.
Diagram is checked for basic errors when saved.
If block is not connected then validation will warn you. You can still compile and download EA but unconnected blocks will not execute.
If blocks are connected in the loop then validation will warn you. You can still generate and download EA but entangled blocks are
likely to cause infinite loop slowing your EA during execution and making it useless.
Sometimes loops are not as obvious as in this diagram. Especially if you have over 50+ blocks on it.
You can turn off all validations in Settings but it is not recommended. Infinite loops may cause problems for generated EA.
When testing EA use both Strategy Tester for back testing and demo account for forward testing in the terminal.
Some building blocks do not work well in back testing and can only be tested in demo (forward) testing.
Back testing is a simulation. Functions like local time, market price spread and history are simulated and artificially created
in terminal during back testing. If you want more accurate results use forward testing.
Sometimes when you run strategy in Strategy Tester it may not be obvious why certain trades have been placed.
Use Visual Mode to see exactly what is going on. Place all the indicators you use when running Strategy Tester in Visual Mode.
Then stop at the point when trades are placed. It is best to use small date time periods for initial testing - one to two days.
If you run Strategy Tester all the way thru all the trades to the end without stopping, and then scroll the chart back sometimes it
looks like EA entered trade for no reason. You need to run it in Visual Mode in Strategy Tester and stop at exactly the point when
trade is entered. Make sure to have indicators open on chart when in Visual Mode.
You can experiment in order to understand how one or other block works.
Best way to experiment is to setup small diagram with just few blocks.
This small setup opens single position only once. It is good starting point for experimentation.
Attach your experimental blocks to the first "On Tick" block in the diagram above.
"Execute Once" is useful when you want to execute action once on the first tick only.
It is good idea to start experiments with block's default parameter values. Change parameter values later during experimentation.
Default parameter values are picked to be safe to use on many brokers and accounts.
Some brokers do not allow stoploss and takeprofit values to be too small. Too small stoploss value will cause [invalid stops] error.
Same applies to lots volume. If your broker smallest lot value is 0.1 trying to open 0.01 lots likely to cause [invalid volume] error.
One and the same EA may give different trading results depending on what Forex broker and account it is running on.
You might have developed and tested your EA using one broker and it worked fine. You moved it to a different broker and
results are terrible: some orders do not execute, cannot place tight stoploss, you are getting many requotes, etc.
That is unfortunate truth – brokers supply very different execution environments. While they all MT5 based but they all
somewhat a little different. Retest your EA if you move to another broker.
While spread is obviously different between brokers there are also not-so-obvious other parameters.
Example: many brokers do not let you place your SL and TP too-close to the opening price.
This is very important when scalping. If broker does not let you place SL and TP too-close you will be getting a lot of requotes
placing orders. Usually there is not much can be done: either change broker or do not use scalping.
Diagrams with over 150 blocks will load and save slower than usual.
Maximum supported block count is 200 blocks. Over that limit diagrams will still generate code but loading and
saving time will increase even more.