Algo Trading with REST API and Python | Using the fxcmpy Python wrapper to connect to FXCM’s REST API
Connecting to and using FXCM’s REST API to build your trading algorithms has never been easier with the introduction of the fxcmpy Python wrapper. Establishing a connection, pulling prices, streaming data, and placing orders is a quick and simple process that even novice programmers can utilize.
In today’s article we will be covering a step-by-step walk through of installing and using the main functions of the fxcmpy Python wrapper. In future tutorials, we will build off of this demonstration to create trading strategies that we can backtest and run in real-time, so stay tuned for more.
Installing the fxcmpy Python Wrapper
Installing the fxcmpy Python wrapper is quick, easy, and straightforward. If you’ve ever installed a Python package using the ‘pip install’ command, you’re already familiar with the steps. Note that fxcmpy requires that you have already installed Python on your computer and is only compatible with Python 3.4 and later. If you need instructions on how to install Python, please visit our Preparing Your Computer article.
The easiest way to install the fxcmpy Python Wrapper is using the ‘pip install’ command within Python. After installing Python, simply open a command line and enter:
pip install fxcmpy
All dependencies of the wrapper will automatically be installed during this process. Once complete, you will be ready to use the fxcmpy wrapper.
Note: It is suggested to regularly check for new versions of the fxcmpy wrapper as we continually aim to improve this product. To update, simply open a command prompt at any time and enter the following command:
pip install fxcmpy –upgrade
Manual Package Installation
To install the package locally, you can clone the Git repository and install by using the following commands from the command prompt:
git clone https://github.com/fxcm/fxcmpy cd fxcmpy python setup.py install
Preparing to Use the fxcmpy Wrapper
Getting an API Token
To connect to the API, you will need an API Token that you can create or revoke by logging into the FXCM Trading Station web platform with your Live or Demo account. For steps on creating your token, please see our Getting Started Guide.
Preparing Your Config File
In order to connect to the FXCM REST API via the fxcmpy Python wrapper, we will need to define a few settings about the connection and our credentials for logging in. It is highly recommended to store the API token in a configuration file which will allow us to keep your information separate from our algorithm’s main code for security purposes.
To create a configuration file, we can utilize a simple text editor (such as notepad on Windows) and enter the following information:
[FXCM] log_level = error log_file = PATH_TO_AND_NAME_OF_LOG_FILE access_token = YOUR_FXCM_API_TOKEN
For this article, we will save this file as fxcm.cfg and will save it in the same directory as our main program so that we only need to pass the fxcm.cfg file name as a parameter when connecting to REST API.
Using the fxcmpy Python Wrapper
Creating a connection is very quick and easy with the fxcmpy Python wrapper. In one line we will establish our connection and be ready to send requests to place trades, get historical data, stream live data, and more. To do so, we’ll import the fxcmpy wrapper, define our connection object, and pass in our configuration file and other parameters:
import fxcmpy con = fxcmpy.fxcmpy(config_file='fxcm.cfg', server='demo')
Note: If you want to connect using your live account, simply set the server parameter equal to ‘real’.
This process can take approximately 10 seconds to complete as the server authenticates your credentials.
Getting Instrument Names
In order to get historical pricing, it’s important that you’re able to see which instruments are available and which instruments you are currently subscribed to on your account. To view all instruments that you can subscribe to on your account, use the following method:
To view the instruments that you are currently subscribed to on your account, use the following method:
Note: You can only pull data/trade the instruments returned by the get_instruments_for_candles() method. If you want to trade an instrument that is not listed by this method, you can log into your account via the Trading Station Desktop or Trading Station Web platforms and subscribe to the instrument using the GUI.
Pulling Historical Prices
Now that we know which instruments we can use; the next step is to get historical data. There are a few different ways to pull historical data. Historical data, regardless of the method used to retrieve it, will be returned as a Pandas DataFrame object.
To get historical prices we will use the con.get_candles() method with different parameters. At minimum, we must pass in the instrument name and period.
Note: Available periods for pulling historical data are: ‘m1’, ‘m5’, ‘m15’, ‘m30’, ‘H1’, ‘H2’, ‘H3’, ‘H4’, ‘H6’, ‘H8′,’D1’, ‘W1’, or ‘M1’
Getting historical prices by specifying only the time period
data = con.get_candles('GBP/JPY', period='D1')
Note: Specifying the period with no other parameters will return only the 10 most recent periods.
Getting historical prices by specifying the number of results
data = con.get_candles('EUR/USD', period = 'm1', number = 5)
Getting historical prices by specifying the start and end date
In order to specify dates, we will need to import the date datetime library and define our start and stop times:
import datetime as dt start = dt.datetime(2018, 1, 1) stop = dt.datetime(2018, 1, 30) data = con.get_candles('EUR/USD', period = 'D1', start = start, stop = stop)
Streaming Real-time Prices
Streaming real-time prices with the fxcmpy wrapper is a very easy and straightforward process that can be accomplished with a few simple methods. First, we must subscribe to an instrument using the subscribe_market_data() method by passing in the instrument that we would like to subscribe to.
Once the subscription method has executed, the fxcmpy wrapper collects the streaming data in pandas DataFrame object, which can be assigned to a variable using the get_prices() method.
data = con.get_prices('EUR/USD')
Finally, once we have finished we can unsubscribe from the instrument using the unsubscribe_market_data() command.
Executing orders using the fxcmpy wrapper is, just like all other functions, quite easy to do while remaining very flexible in the execution options available. This article won’t be able to cover every single parameter; however, you can view the full documentation of the fxcmpy wrapper and its functionality here.
Checking Open Positions
Before placing new orders, it’s always a good idea to get information on existing orders first. To do so, we can use the following command:
Creating Basic Market Orders
In order to create a basic market order, you must provide the instrument and the size of the order (in micro lots) as parameters to either the create_market_sell_order() or create_market_buy_order() methods.
con.create_market_buy_order('USD/JPY', (10) con.create_market_sell_order('EUR/USD', (100)
Creating More Complex Market Orders
The fxcmpy wrapper also allows for the creation of more complex general market orders with the open_trade() method. A detailed description of the meaning of each parameter can be found in the FXCM REST API documentation.
Here, we will create a Good-Til-Canceled market order to buy 10k worth of GBP/JPY with a limit at the market price of 150.00:
con.open_trade(symbol = 'GBP/JPY', is_buy = True, rate = 105, is_in_pips = False, amount = 10, time_in_force = 'GTC', order_type = 'AtMarket', limit = 150)
Creating and Modifying Entry Orders
Creating entry orders is similar to creating a market order. Instead of using the open_trade() method, we will instead use the create_entry_order() method. Similar to before, we will create a resting order to buy 10k worth of GBP/JPY at a rate of 105 with a limit set at the market price of 150.00.
con.create_entry_order(symbol = 'GBP/JPY', is_buy = True, amount = 10, limit = 150, is_in_pips = False, time_in_force = 'GTC', rate = 105)
To change an order you will need to get the order ID using the get_order_ids() method and pass this as a parameter, along with changes, into the change_order() or change_order_stop_limit() methods. Below, we will get the order ID of our last order and change the size of the order and limit:
id = con.get_order_ids()[-1] con.change_order_stop_limit(order_id = id, limit = 140) con.change_order(order_id = id, amount = 100, rate = 110)
To check on the changes we can use the get_orders() function:
Finally, to delete an entry order we will use the delete_order() method and pass in the corresponding Order ID:
Closing Executed Orders
Now that we have create and modified orders, the only thing left to do is to close out our existing orders. There are a number of ways to manage your open orders, starting with closing a single position. In order to close a single position, we will pass in the position ID into the get_open_position() method. This allows us to store the position as an object that we can then close.
pos = con.get_open_position(id) pos.close()
Next, we can close all positions for a specific instrument. All that’s needed is to pass in the instrument name as an argument to the close_all_for_symbol() method.
Finally, we can simply close all positions at the same time by using the close_all() method.
This article is a good introduction to the basic functionality of the fxcmpy Python wrapper. This wrapper makes accessing and using the FXCM REST API a simple and easy process; however, we weren’t able to cover all of the nuances in this article.
To learn more about the fxcmpy Python wrapper we would encourage you to read the full documentation located here. Additionally, check often for updated content and new guides for building and backtesting algorithmic trading strategies.
Risk Warning: The FXCM Group does not guarantee accuracy and will not accept liability for any loss or damage which arise directly or indirectly from use of or reliance on information contained within the webinars. The FXCM Group may provide general commentary which is not intended as investment advice and must not be construed as such. FX/CFD trading carries a risk of losses in excess of your deposited funds and may not be suitable for all investors. Please ensure that you fully understand the risks involved.