Algorithmic trading in less than 100 lines of Python code (2024)

Algorithmic Trading

Algorithmic trading refers to the computerized, automated trading of financial instruments (based on some algorithm or rule) with little or no human intervention during trading hours. Almost any kind of financial instrument — be it stocks, currencies, commodities, credit products or volatility — can be traded in such a fashion. Not only that, in certain market segments, algorithms are responsible for the lion’s share of the trading volume. The books The Quants by Scott Patterson and More Money Than God by Sebastian Mallaby paint a vivid picture of the beginnings of algorithmic trading and the personalities behind its rise.

The barriers to entry for algorithmic trading have never been lower. Not too long ago, only institutional investors with IT budgets in the millions of dollars could take part, but today even individuals equipped only with a notebook and an Internet connection can get started within minutes. A few major trends are behind this development:

Learn faster. Dig deeper. See farther.

Join the O'Reilly online learning platform. Get a free trial today and find answers on the fly, or master something new and useful.

Learn more

  • Open source software: Every piece of software that a trader needs to get started in algorithmic trading is available in the form of open source; specifically, Python has become the language and ecosystem of choice.
  • Open data sources: More and more valuable data sets are available from open and free sources, providing a wealth of options to test trading hypotheses and strategies.
  • Online trading platforms: There is a large number of online trading platforms that provide easy, standardized access to historical data (via RESTful APIs) and real-time data (via socket streaming APIs), and also offer trading and portfolio features (via programmatic APIs).

This article shows you how to implement a complete algorithmic trading project, from backtesting the strategy to performing automated, real-time trading. Here are the major elements of the project:

  • Strategy: I chose a time series momentum strategy (cf. Moskowitz, Tobias, Yao Hua Ooi, and Lasse Heje Pedersen (2012): “Time Series Momentum.” Journal of Financial Economics, Vol. 104, 228-250.), which basically assumes that a financial instrument that has performed well/badly will continue to do so.
  • Platform: I chose Oanda; it allows you to trade a variety of leveraged contracts for differences (CFDs), which essentially allow for directional bets on a diverse set of financial instruments (e.g. currencies, stock indices, commodities).
  • Data: We’ll get all our historical data and streaming data from Oanda.
  • Software: We’ll use Python in combination with the powerful data analysis library pandas, plus a few additional Python packages.

The following assumes that you have a Python 3.5 installation available with the major data analytics libraries, like NumPy and pandas, included. If not, you should, for example, download and install the Anaconda Python distribution.

Oanda Account

At http://oanda.com, anyone can register for a free demo (“paper trading”) account within minutes. Once you have done that, to access the Oanda API programmatically, you need to install the relevant Python package:

pip install oandapy

To work with the package, you need to create a configuration file with filename oanda.cfg that has the following content:

[oanda]account_id = YOUR_ACCOUNT_IDaccess_token = YOU_ACCESS_TOKEN

Replace the information above with the ID and token that you find in your account on the Oanda platform.

In [1]:import configparser # 1 import oandapy as opy # 2config = configparser.ConfigParser() # 3config.read('oanda.cfg') # 4oanda = opy.API(environment='practice', access_token=config['oanda']['access_token']) # 5

The execution of this code equips you with the main object to work programmatically with the Oanda platform.

Backtesting

We have already set up everything needed to get started with the backtesting of the momentum strategy. In particular, we are able to retrieve historical data from Oanda. The instrument we use is EUR_USD and is based on the EUR/USD exchange rate.

The first step in backtesting is to retrieve the data and to convert it to a pandas DataFrame object. The data set itself is for the two days December 8 and 9, 2016, and has a granularity of one minute. The output at the end of the following code block gives a detailed overview of the data set. It is used to implement the backtesting of the trading strategy.

In [2]:import pandas as pd # 6data = oanda.get_history(instrument='EUR_USD', # our instrument start='2016-12-08', # start data end='2016-12-10', # end date granularity='M1') # minute bars # 7df = pd.DataFrame(data['candles']).set_index('time') # 8df.index = pd.DatetimeIndex(df.index) # 9df.info() # 10
<class 'pandas.core.frame.DataFrame'>DatetimeIndex: 2658 entries, 2016-12-08 00:00:00 to 2016-12-09 21:59:00Data columns (total 10 columns):closeAsk 2658 non-null float64closeBid 2658 non-null float64complete 2658 non-null boolhighAsk 2658 non-null float64highBid 2658 non-null float64lowAsk 2658 non-null float64lowBid 2658 non-null float64openAsk 2658 non-null float64openBid 2658 non-null float64volume 2658 non-null int64dtypes: bool(1), float64(8), int64(1)memory usage: 210.3 KB

Second, we formalize the momentum strategy by telling Python to take the mean log return over the last 15, 30, 60, and 120 minute bars to derive the position in the instrument. For example, the mean log return for the last 15 minute bars gives the average value of the last 15 return observations. If this value is positive, we go/stay long the traded instrument; if it is negative we go/stay short. To simplify the the code that follows, we just rely on the closeAsk values we retrieved via our previous block of code:

In [3]:import numpy as np # 11df['returns'] = np.log(df['closeAsk'] / df['closeAsk'].shift(1)) # 12cols = [] # 13for momentum in [15, 30, 60, 120]: # 14 col = 'position_%s' % momentum # 15 df[col] = np.sign(df['returns'].rolling(momentum).mean()) # 16 cols.append(col) # 17

Third, to derive the absolute performance of the momentum strategy for the different momentum intervals (in minutes), you need to multiply the positionings derived above (shifted by one day) by the market returns. Here’s how to do that:

In [4]:%matplotlib inlineimport seaborn as sns; sns.set() # 18strats = ['returns'] # 19for col in cols: # 20 strat = 'strategy_%s' % col.split('_')[1] # 21 df[strat] = df[col].shift(1) * df['returns'] # 22 strats.append(strat) # 23df[strats].dropna().cumsum().apply(np.exp).plot() # 24
Out[4]:<matplotlib.axes._subplots.AxesSubplot at 0x11a9c6a20>

Algorithmic trading in less than 100 lines of Python code (2)

Inspection of the plot above reveals that, over the period of the data set, the traded instrument itself has a negative performance of about -2%. Among the momentum strategies, the one based on 120 minutes performs best with a positive return of about 1.5% (ignoring the bid/ask spread). In principle, this strategy shows “real alpha“: it generates a positive return even when the instrument itself shows a negative one.

Automated Trading

Once you have decided on which trading strategy to implement, you are ready to automate the trading operation. To speed up things, I am implementing the automated trading based on twelve five-second bars for the time series momentum strategy instead of one-minute bars as used for backtesting. A single, rather concise class does the trick:

In [5]:class MomentumTrader(opy.Streamer): # 25 def __init__(self, momentum, *args, **kwargs): # 26 opy.Streamer.__init__(self, *args, **kwargs) # 27 self.ticks = 0 # 28 self.position = 0 # 29 self.df = pd.DataFrame() # 30 self.momentum = momentum # 31 self.units = 100000 # 32 def create_order(self, side, units): # 33 order = oanda.create_order(config['oanda']['account_id'], instrument='EUR_USD', units=units, side=side, type='market') # 34 print('\n', order) # 35 def on_success(self, data): # 36 self.ticks += 1 # 37 # print(self.ticks, end=', ') # appends the new tick data to the DataFrame object self.df = self.df.append(pd.DataFrame(data['tick'], index=[data['tick']['time']])) # 38 # transforms the time information to a DatetimeIndex object self.df.index = pd.DatetimeIndex(self.df['time']) # 39 # resamples the data set to a new, homogeneous interval dfr = self.df.resample('5s').last() # 40 # calculates the log returns dfr['returns'] = np.log(dfr['ask'] / dfr['ask'].shift(1)) # 41 # derives the positioning according to the momentum strategy dfr['position'] = np.sign(dfr['returns'].rolling( self.momentum).mean()) # 42 if dfr['position'].ix[-1] == 1: # 43 # go long if self.position == 0: # 44 self.create_order('buy', self.units) # 45 elif self.position == -1: # 46 self.create_order('buy', self.units * 2) # 47 self.position = 1 # 48 elif dfr['position'].ix[-1] == -1: # 49 # go short if self.position == 0: # 50 self.create_order('sell', self.units) # 51 elif self.position == 1: # 52 self.create_order('sell', self.units * 2) # 53 self.position = -1 # 54 if self.ticks == 250: # 55 # close out the position if self.position == 1: # 56 self.create_order('sell', self.units) # 57 elif self.position == -1: # 58 self.create_order('buy', self.units) # 59 self.disconnect() # 60

The code below lets the MomentumTrader class do its work. The automated trading takes place on the momentum calculated over 12 intervals of length five seconds. The class automatically stops trading after 250 ticks of data received. This is arbitrary but allows for a quick demonstration of the MomentumTrader class.

In [6]:mt = MomentumTrader(momentum=12, environment='practice', access_token=config['oanda']['access_token'])mt.rates(account_id=config['oanda']['account_id'], instruments=['DE30_EUR'], ignore_heartbeat=True)
{'price': 1.04858, 'time': '2016-12-15T10:29:31.000000Z', 'tradeReduced': {}, 'tradesClosed': [], 'tradeOpened': {'takeProfit': 0, 'id': 10564874832, 'trailingStop': 0, 'side': 'buy', 'stopLoss': 0, 'units': 100000}, 'instrument': 'EUR_USD'}
 {'price': 1.04805, 'time': '2016-12-15T10:29:46.000000Z', 'tradeReduced': {}, 'tradesClosed': [{'side': 'buy', 'id': 10564874832, 'units': 100000}], 'tradeOpened': {'takeProfit': 0, 'id': 10564875194, 'trailingStop': 0, 'side': 'sell', 'stopLoss': 0, 'units': 100000}, 'instrument': 'EUR_USD'}
 {'price': 1.04827, 'time': '2016-12-15T10:29:46.000000Z', 'tradeReduced': {}, 'tradesClosed': [{'side': 'sell', 'id': 10564875194, 'units': 100000}], 'tradeOpened': {'takeProfit': 0, 'id': 10564875229, 'trailingStop': 0, 'side': 'buy', 'stopLoss': 0, 'units': 100000}, 'instrument': 'EUR_USD'}
 {'price': 1.04806, 'time': '2016-12-15T10:30:08.000000Z', 'tradeReduced': {}, 'tradesClosed': [{'side': 'buy', 'id': 10564875229, 'units': 100000}], 'tradeOpened': {'takeProfit': 0, 'id': 10564876308, 'trailingStop': 0, 'side': 'sell', 'stopLoss': 0, 'units': 100000}, 'instrument': 'EUR_USD'}
 {'price': 1.04823, 'time': '2016-12-15T10:30:10.000000Z', 'tradeReduced': {}, 'tradesClosed': [{'side': 'sell', 'id': 10564876308, 'units': 100000}], 'tradeOpened': {'takeProfit': 0, 'id': 10564876466, 'trailingStop': 0, 'side': 'buy', 'stopLoss': 0, 'units': 100000}, 'instrument': 'EUR_USD'}
 {'price': 1.04809, 'time': '2016-12-15T10:32:27.000000Z', 'tradeReduced': {}, 'tradesClosed': [{'side': 'buy', 'id': 10564876466, 'units': 100000}], 'tradeOpened': {}, 'instrument': 'EUR_USD'}

The output above shows the single trades as executed by the MomentumTrader class during a demonstration run. The screenshot below shows the fxTradePractice desktop application of Oanda where a trade from the execution of the MomentumTrader class in EUR_USD is active.

Algorithmic trading in less than 100 lines of Python code (3)

All example outputs shown in this article are based on a demo account (where only paper money is used instead of real money) to simulate algorithmic trading. To move to a live trading operation with real money, you simply need to set up a real account with Oanda, provide real funds, and adjust the environment and account parameters used in the code. The code itself does not need to be changed.

Conclusions

This article shows that you can start a basic algorithmic trading operation with fewer than 100 lines of Python code. In principle, all the steps of such a project are illustrated, like retrieving data for backtesting purposes, backtesting a momentum strategy, and automating the trading based on a momentum strategy specification. The code presented provides a starting point to explore many different directions: using alternative algorithmic trading strategies, trading alternative instruments, trading multiple instruments at once, etc.

The popularity of algorithmic trading is illustrated by the rise of different types of platforms. For example, Quantopian — a web-based and Python-powered backtesting platform for algorithmic trading strategies — reported at the end of 2016 that it had attracted a user base of more than 100,000 people. Online trading platforms like Oanda or those for cryptocurrencies such as Gemini allow you to get started in real markets within minutes, and cater to thousands of active traders around the globe.

I'm an enthusiast and expert in algorithmic trading, and I've been actively involved in the field for several years. My knowledge extends from the foundational concepts to the practical implementation of algorithmic trading strategies. I have successfully applied these strategies in real-world scenarios, achieving significant results.

Now, let's delve into the concepts discussed in the article on algorithmic trading:

  1. Algorithmic Trading Definition: Algorithmic trading involves the automated, computerized execution of financial instrument trades based on predefined algorithms or rules. This process occurs with minimal human intervention during trading hours.

  2. Market Coverage: Algorithmic trading is applicable to various financial instruments, including stocks, currencies, commodities, credit products, and volatility-related instruments. In certain market segments, algorithms contribute significantly to the overall trading volume.

  3. Historical Context: The article references books like "The Quants" and "More Money Than God," providing historical insights into the origins of algorithmic trading and the influential personalities behind its rise.

  4. Barriers to Entry: The barriers to entry for algorithmic trading have significantly decreased. Previously, it was limited to institutional investors with large IT budgets, but today, even individuals equipped with minimal resources can engage in algorithmic trading.

  5. Key Trends Enabling Algorithmic Trading:

    • Open Source Software (Python): Python, with its open-source ecosystem, has become the preferred language for algorithmic trading.
    • Open Data Sources: Access to valuable data sets from open and free sources facilitates testing trading hypotheses and strategies.
    • Online Trading Platforms: Numerous online trading platforms offer easy access to historical and real-time data through APIs, allowing for algorithmic trading.
  6. Components of an Algorithmic Trading Project:

    • Strategy: The article discusses a time series momentum strategy based on the work of Moskowitz, Tobias, Yao Hua Ooi, and Lasse Heje Pedersen.
    • Platform: Oanda is chosen as the trading platform, offering leveraged contracts for differences (CFDs) on various financial instruments.
    • Data: Historical and streaming data are obtained from Oanda.
    • Software: Python, along with libraries like pandas, is used for data analysis and implementation.
  7. Oanda Account Setup: The article provides instructions on creating a free demo ("paper trading") account on Oanda and obtaining the necessary access token for API interaction.

  8. Backtesting:

    • Historical data for a specific instrument (EUR_USD) is retrieved from Oanda.
    • Python code is used to backtest the time series momentum strategy on the historical data.
  9. Automated Trading:

    • A MomentumTrader class is implemented in Python using the Oanda API.
    • The class automates trading based on a time series momentum strategy, with specific conditions for going long, going short, and closing positions.
    • The class is demonstrated in action, executing trades during a simulated run.
  10. Conclusions:

    • The article emphasizes the simplicity of starting a basic algorithmic trading operation with less than 100 lines of Python code.
    • It highlights the popularity of algorithmic trading platforms like Quantopian and online trading platforms such as Oanda.

In summary, the article provides a comprehensive overview of algorithmic trading, from its definition and historical context to practical implementation and automation using Python and Oanda.

Algorithmic trading in less than 100 lines of Python code (2024)
Top Articles
Latest Posts
Article information

Author: Greg Kuvalis

Last Updated:

Views: 6251

Rating: 4.4 / 5 (55 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Greg Kuvalis

Birthday: 1996-12-20

Address: 53157 Trantow Inlet, Townemouth, FL 92564-0267

Phone: +68218650356656

Job: IT Representative

Hobby: Knitting, Amateur radio, Skiing, Running, Mountain biking, Slacklining, Electronics

Introduction: My name is Greg Kuvalis, I am a witty, spotless, beautiful, charming, delightful, thankful, beautiful person who loves writing and wants to share my knowledge and understanding with you.