Technology9 minute read

Forex Algorithmic Trading: A Practical Tale for Engineers

The foreign exchange (forex) market is the most liquid market in the world. Learn from a software developer’s firsthand experience creating forex algorithmic trading strategies—and more—in this trading tutorial.


Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

The foreign exchange (forex) market is the most liquid market in the world. Learn from a software developer’s firsthand experience creating forex algorithmic trading strategies—and more—in this trading tutorial.


Toptalauthors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.
Rogelio Nicolas Mengual
Verified Expert in Engineering

Rogelio is a versatile and motivated full-stack engineer with more than 13 years of work experience in many languages, frameworks, and platforms.

Read More

PREVIOUSLY AT

IBM
Share

Editor’s note: This article was updated by our editorial team on July 21, 2022. It has been modified to include recent sources and to align with our current editorial standards.

As you may know, the Foreign Exchange (forex or FX) market is used for trading between currency pairs. But you might not be aware that it’s the most liquid market in the world. (Yes, even compared to crypto, forex is generally considered to be safer and more profitable.)

A few years ago, driven by curiosity, I took my first steps into the world of algorithmic trading in forex by creating a demo account and playing out simulations (with fake money) on the Meta Trader 4 trading platform.

After a week of “trading,” I’d almost doubled my money. Spurred on by my successful algorithmic trading, I dug deeper and eventually signed up for a number of FX forums. Soon, I was spending hours reading about algorithmic trading systems in forex (rule sets that determine whether you should buy or sell), custom indicators, market moods, and more.

My First Client for Forex Automated Trading

Around this time, coincidentally, I heard that someone was trying to find a software developer to build a simple, automated forex trading system. This was back in my college days when I was learning about concurrent programming in Java (threads, semaphores, and more). I thought that this forex automated trading system couldn’t be much more complicated than my advanced data science coursework, so I inquired about the job and came on board.

The client wanted algorithmic trading software built with MQL4, a functional programming language used by the Meta Trader 4 platform for performing stock-related actions.

MQL5 has since been released. As you might expect, it addresses some of MQL4's issues and comes with more built-in functions, which makes life easier.


The role of the trading platform (Meta Trader 4, in this case) is to provide a connection to a forex broker. The broker then provides a platform with real-time information about the market and executes buy/sell orders. For readers unfamiliar with forex algorithmic trading, here’s the information provided by the data feed:

This diagram demonstrates the data involved in algorithmic trading in forex.

Through Meta Trader 4, you can access all this data with internal functions, accessible in various time frames: M1 (every minute), M5 (every five minutes), M15, M30, H1 (every hour), H4, D1 (every day), W1 (every week), and MN (monthly).

The movement of the current price is called a tick. A tick is a change in the bid or ask price for a currency pair. During active markets, there may be numerous ticks per second. During slow markets, minutes may elapse without a tick. The tick is the heartbeat of a currency market robot.

When you place an order through such a platform, you buy or sell a certain volume of a certain currency. You also set stop-loss and take-profit limits. The stop-loss limit is the maximum amount of pips (price variations) that you can afford to lose before giving up on a trade. The take-profit limit is the amount of pips that you’ll accumulate in your favor before cashing out.

If you want to learn more about the basics of trading (e.g., pips, order types, spread, slippage, market orders, and more), BabyPips is an excellent resource.


The client’s algorithmic trading specifications were simple: a forex robot based on two indicators. For background, indicators are very helpful when trying to define a market state and make trading decisions, as they’re based on past data (e.g., highest price value in the last n days). Many come built-in to Meta Trader 4. However, the indicators of interest to my client came from a custom forex trading system.

The client wanted to trade every time two of these custom indicators intersected, and only at a certain angle.

This forex trading software example demonstrates my client's requirements.

Hands-on Work With Forex Trading Software

As I got my hands dirty, I learned that MQL4 programs have the following structure:

  • Preprocessor directives
  • External parameters
  • Global variables
  • Init function
  • Deinit function
  • Start function
  • Custom functions

The start function is the heart of every MQL4 program. It executes every time the market moves (ergo, this function executes once per tick). This is the case regardless of a given time frame. For example, you could be operating on the H1 (one hour) time frame, yet the start function would execute many thousands of times per hour.

To work around this, I forced the function to execute once per period unit:

    int start()
    {  if(currentTimeStamp == Time[0]) return (0);
       
       currentTimeStamp  = Time[0];

   //  ...

Next, I had to get the values of the indicators:

    // Loading the custom indicator
    extern string indName = "SonicR Solid Dragon-Trend (White)";
    double dragon_min;
    double dragon_max;
    double dragon;
    double trend;
    int start()
    {  
    /// ...
      // Updating the variables that hold indicator values
      actInfoIndicadores();

    // ...
    string actInfoIndicadores()
    {  
        dragon_max=iCustom(NULL, 0, indName, 0, 1);
        dragon_min=iCustom(NULL, 0, indName, 1, 1);
        dragon=iCustom(NULL, 0, indName, 4, 1);
        trend=iCustom(NULL, 0, indName, 5, 1);
    }

Now, we’ll code the decision logic, including the intersection of the indicators and their angles:

    int start()
    {
    // ...
       if(ticket==0) 
       {  
             if (dragon_min > trend && (ordAbierta== "OP_SELL" || primeraOP == true) && anguloCorrecto("BUY") == true && DiffPrecioActual("BUY")== true ) {
                primeraOP =  false;
                abrirOrden("OP_BUY", false);
             }
             if (dragon_max < trend && (ordAbierta== "OP_BUY" || primeraOP == true) && anguloCorrecto("SELL") == true && DiffPrecioActual("SELL")== true ) {
                primeraOP = false;
                abrirOrden("OP_SELL", false);
             }  
       }     
       else
       {       
           if(OrderSelect(ticket,SELECT_BY_TICKET)==true)
           {
               datetime ctm=OrderCloseTime();
               if (ctm>0) { 
                  ticket=0;
                  return(0);
               }
           }
           else
              Print("OrderSelect failed error code is",GetLastError());

           if (ordAbierta == "OP_BUY"  && dragon_min <= trend  ) cerrarOrden(false);
           else if (ordAbierta == "OP_SELL" && dragon_max >= trend ) cerrarOrden(false);
       }
    }

Finally, we’ll want to send the orders:

    void abrirOrden(string tipoOrden, bool log)
    {  
       RefreshRates();
       double volumen = AccountBalance() * point; 
       double pip     = point * pipAPer;   
       double ticket  = 0;
       while( ticket <= 0)
       {  if (tipoOrden == "OP_BUY")   ticket=OrderSend(simbolo, OP_BUY,  volumen, Ask, 3, 0/*Bid - (point * 100)*/, Ask + (point * 50), "Orden Buy" , 16384, 0, Green);
          if (tipoOrden == "OP_SELL")  ticket=OrderSend(simbolo, OP_SELL, volumen, Bid, 3, 0/*Ask + (point * 100)*/, Bid - (point * 50), "Orden Sell", 16385, 0, Red);
          if (ticket<=0)               Print("Error abriendo orden de ", tipoOrden , " : ", ErrorDescription( GetLastError() ) ); 
       }  ordAbierta = tipoOrden;
       
       if (log==true) mostrarOrden();
    }

You can find the complete code on GitHub.

Backtesting Algorithmic Trading in Forex

Once I built my algorithmic trading system, I wanted to know if it was behaving appropriately and if the forex trading strategy it used was any good.

Backtesting is the process of testing a particular system (automated or not) under the events of the past. In other words, you test your system using the past as a proxy for the present.

MT4 comes with an acceptable tool for backtesting a forex trading strategy (nowadays, there are more professional tools that offer greater functionality). To start, you set up your time frames and run your program under a simulation; the tool will simulate each tick, knowing that for each unit it should open at certain price, close at a certain price, and reach specified highs and lows.

After comparing the actions of the program against historic prices, you’ll have a good sense of whether or not it’s executing correctly.

The indicators that my client had chosen, along with the decision logic, were not profitable.

Via backtesting, I had checked the FX robot’s return ratio for some random time intervals; I knew that my client wasn’t going to get rich with the trading strategy used—the chosen indicators, along with the decision logic, were not profitable. Here are the results of running the program over the M15 window for 164 operations:

These are the results of running the forex trading software program I'd developed.

Note that the balance (the blue line) finishes below its starting point.

One caveat: Saying that a system is “profitable” or “unprofitable” isn’t always accurate. Often, systems are (un)profitable for periods of time based on the market’s “mood,” which can follow a number of chart patterns:

A few trends in our algorithmic trading example.

Parameter Optimization—and Its Lies

Although backtesting had made me wary of this FX robot’s usefulness, I was intrigued when I started playing with its external parameters and noticed big differences in the overall return ratio. This is known as parameter optimization.

I did some rough testing to try to infer the significance of the external parameters on the return ratio and arrived at this:

One aspect of a forex algorithm is return ratio.

Cleaned up, it looks like this:

The algorithmic trading return ratio could look like this when cleaned up.

You may think, as I did, that you should use parameter A. But the decision isn’t as straightforward as it may appear. Specifically, note the unpredictability of parameter A: For small error values, its return changes dramatically. In other words, parameter A is very likely to overpredict future results since any uncertainty—any shift at all—will result in worse performance.

But indeed, the future is uncertain! And so the return of parameter A is also uncertain. The best choice, in fact, is to rely on unpredictability. Often, a parameter with a lower maximum return but superior predictability (less fluctuation) will be preferable to a parameter with high return but poor predictability.

The only thing you can know for sure is that you don’t know the future of the market, and it is a mistake to assume you know how the market is going to perform based on past data. As such, you must acknowledge this unpredictability in your forex predictions.

It is a mistake to assume you know how the market is going to perform based on past data.

This does not necessarily mean we should use parameter B because even the lower returns of parameter A perform better than the returns of parameter B; optimizing parameters can result in tests that overstate likely future results, and such thinking is not obvious.

Overall Forex Algorithmic Trading Considerations

Since my first experience with forex algorithmic trading, I’ve built several automated trading systems for clients, and I can tell you that there’s always room to explore and further forex analysis to be done. For example, I recently built a system based on finding so-called “big fish” movements: huge pips variations in very small units of time. This is a subject that fascinates me.

Building your own FX simulation system is an excellent option to learn more about forex market trading, and the possibilities are endless. For example, you could try to decipher the probability distribution of the price variations as a function of volatility in one market (EUR/USD for example), or make a Monte Carlo simulation model using the distribution per volatility state, using whatever degree of accuracy you prefer. I’ll leave this as an exercise for the eager reader.

The forex world can be overwhelming at times, but I encourage you to explore your own strategy for algorithmic trading in forex.

Suggestions for Further Reading

Nowadays, there is a vast pool of tools to build, test, and improve forex trading system automations: Trading Blox for testing, NinjaTrader for trading, and OCaml for programming, to name a few.

I’ve read extensively about the mysterious world that is the currency market. Here are some resources for programmers and enthusiastic readers:

Understanding the basics

  • What is forex trading all about?

    Forex (or FX) trading is buying and selling via currency pairs (e.g., USD vs. EUR) on the foreign exchange market.

  • How does forex make money?

    Forex brokers make money through commissions and fees. Forex traders make (or lose) money based on their timing: If they’re able to sell high enough compared to when they bought, they can turn a profit.

  • What is backtesting a trading strategy?

    Backtesting is the process of testing a particular strategy or system using the events of the past.

  • What is algorithmic trading?

    Algorithmic trading is when a robot/program uses a set of rules that tell it when to buy or sell.

Hire a Toptal expert on this topic.
Hire Now
Rogelio Nicolas Mengual

Rogelio Nicolas Mengual

Verified Expert in Engineering

Jujuy, Argentina

Member since May 6, 2013

About the author

Rogelio is a versatile and motivated full-stack engineer with more than 13 years of work experience in many languages, frameworks, and platforms.

Read More
authors are vetted experts in their fields and write on topics in which they have demonstrated experience. All of our content is peer reviewed and validated by Toptal experts in the same field.

PREVIOUSLY AT

IBM

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

World-class articles, delivered weekly.

Subscription implies consent to our privacy policy

Join the Toptal® community.