The Python Quants

FXCM Algorithmic Trading Initiative

RESTful API & Automated Trading

Dr. Yves J. Hilpisch

The Python Quants GmbH

Risk Disclaimer

Trading forex/CFDs on margin carries a high level of risk and may not be suitable for all investors as you could sustain losses in excess of deposits. Leverage can work against you. Due to the certain restrictions imposed by the local law and regulation, German resident retail client(s) could sustain a total loss of deposited funds but are not subject to subsequent payment obligations beyond the deposited funds. Be aware and fully understand all risks associated with the market and trading. Prior to trading any products, carefully consider your financial situation and experience level. Any opinions, news, research, analyses, prices, or other information is provided as general market commentary, and does not constitute investment advice. FXCM & TPQ will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on such information.

Speaker Disclaimer

The speaker is neither an employee, agent nor representative of FXCM and is therefore acting independently. The opinions given are their own, constitute general market commentary, and do not constitute the opinion or advice of FXCM or any form of personal or investment advice. FXCM assumes no responsibility for any loss or damage, including but not limited to, any loss or gain arising out of the direct or indirect use of this or any other content. Trading forex/CFDs on margin carries a high level of risk and may not be suitable for all investors as you could sustain losses in excess of deposits.

Imports

In [1]:
import numpy as np
import pandas as pd
import datetime as dt
import cufflinks as cf
import warnings; warnings.simplefilter('ignore')
from statsmodels.tsa.stattools import adfuller
cf.set_config_file(offline=True)

Connecting to the FXCM RESTful API

You can install fxcmpy via

pip install fxcmpy

The documentation is currently found under http://fxcmpy.tpq.io

In [2]:
import fxcmpy
In [3]:
api = fxcmpy.fxcmpy(config_file='fxcm.cfg')
In [4]:
instruments = api.get_instruments()
print(instruments)
['EUR/USD', 'USD/JPY', 'GBP/USD', 'USD/CHF', 'EUR/CHF', 'AUD/USD', 'USD/CAD', 'NZD/USD', 'EUR/GBP', 'EUR/JPY', 'GBP/JPY', 'CHF/JPY', 'GBP/CHF', 'EUR/AUD', 'EUR/CAD', 'AUD/CAD', 'AUD/JPY', 'CAD/JPY', 'NZD/JPY', 'GBP/CAD', 'GBP/NZD', 'GBP/AUD', 'AUD/NZD', 'USD/SEK', 'EUR/SEK', 'EUR/NOK', 'USD/NOK', 'USD/MXN', 'AUD/CHF', 'EUR/NZD', 'USD/ZAR', 'USD/HKD', 'ZAR/JPY', 'USD/TRY', 'EUR/TRY', 'NZD/CHF', 'CAD/CHF', 'NZD/CAD', 'TRY/JPY', 'USD/CNH', 'AUS200', 'ESP35', 'FRA40', 'GER30', 'HKG33', 'JPN225', 'NAS100', 'SPX500', 'UK100', 'US30', 'Copper', 'CHN50', 'EUSTX50', 'USDOLLAR', 'USOil', 'UKOil', 'SOYF', 'NGAS', 'Bund', 'XAU/USD', 'XAG/USD']

Historical Data

Retrieving Historical Data

In [5]:
candles = api.get_candles('USD/JPY', period='D1', number=10)
In [6]:
# 10 most recent days | daily
candles
Out[6]:
bidopen bidclose bidhigh bidlow askopen askclose askhigh asklow tickqty
date
2018-03-05 22:00:00 105.494 106.202 106.238 105.351 105.547 106.220 106.239 105.352 278878
2018-03-06 22:00:00 106.202 106.130 106.463 105.852 106.220 106.146 106.465 105.855 535538
2018-03-07 22:00:00 106.130 106.060 106.229 105.456 106.146 106.091 106.222 105.458 310564
2018-03-08 22:00:00 106.060 106.193 106.315 105.892 106.091 106.247 106.316 105.894 235470
2018-03-09 22:00:00 106.193 106.814 107.050 106.150 106.247 106.822 107.055 106.176 263242
2018-03-11 21:00:00 106.616 106.632 106.680 106.568 106.676 106.680 106.706 106.580 167
2018-03-12 21:00:00 106.632 106.410 106.972 106.310 106.680 106.435 106.974 106.315 177547
2018-03-13 21:00:00 106.410 106.566 107.293 106.254 106.435 106.583 107.298 106.255 335733
2018-03-14 21:00:00 106.566 106.314 106.749 106.064 106.583 106.326 106.750 106.066 296421
2018-03-15 21:00:00 106.314 106.323 106.415 105.785 106.326 106.358 106.417 105.786 290884
In [7]:
start = dt.datetime(2017, 1, 1)
end = dt.datetime(2018, 1, 1)
In [8]:
candles = api.get_candles('USD/JPY', period='D1',
                         start=start, stop=end)
In [9]:
candles['askclose'].iplot()

The parameter period must be one of m1, m5, m15, m30, H1, H2, H3, H4, H6, H8, D1, W1 or M1.

In [10]:
# 50 most recent 1 minute bars
candles = api.get_candles('EUR/USD', period='m1', number=150)
candles.tail(10)
Out[10]:
bidopen bidclose bidhigh bidlow askopen askclose askhigh asklow tickqty
date
2018-03-16 08:59:00 1.23193 1.23182 1.23195 1.23173 1.23196 1.23182 1.23197 1.23173 265
2018-03-16 09:00:00 1.23182 1.23197 1.23199 1.23178 1.23181 1.23198 1.23200 1.23177 262
2018-03-16 09:01:00 1.23197 1.23187 1.23199 1.23175 1.23198 1.23190 1.23200 1.23177 309
2018-03-16 09:02:00 1.23187 1.23189 1.23209 1.23182 1.23190 1.23192 1.23211 1.23182 275
2018-03-16 09:03:00 1.23190 1.23211 1.23211 1.23190 1.23193 1.23213 1.23213 1.23193 192
2018-03-16 09:04:00 1.23211 1.23235 1.23243 1.23211 1.23213 1.23235 1.23242 1.23213 295
2018-03-16 09:05:00 1.23235 1.23221 1.23240 1.23221 1.23235 1.23223 1.23239 1.23222 116
2018-03-16 09:06:00 1.23221 1.23251 1.23252 1.23214 1.23223 1.23252 1.23254 1.23217 203
2018-03-16 09:07:00 1.23250 1.23236 1.23254 1.23229 1.23251 1.23236 1.23255 1.23229 231
2018-03-16 09:08:00 1.23237 1.23250 1.23251 1.23237 1.23237 1.23253 1.23253 1.23236 155

Visualization of the Data

In [11]:
data = candles[['askopen', 'askhigh', 'asklow', 'askclose']]
data.columns = ['open', 'high', 'low', 'close']
data.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 150 entries, 2018-03-16 06:39:00 to 2018-03-16 09:08:00
Data columns (total 4 columns):
open     150 non-null float64
high     150 non-null float64
low      150 non-null float64
close    150 non-null float64
dtypes: float64(4)
memory usage: 5.9 KB
In [12]:
qf = cf.QuantFig(data, title='EUR/USD', legend='top',
                 name='EUR/USD', datalegend=False)
In [13]:
qf.iplot()