Forex com 8

A Quick and Dirty Guide to Placing Trades on Forex.com via Python.


For anyone who has previously attempted to use Python to integrate with Forex.com’s API for algorithmic training and failed, I feel for you. Due to “alright” API documentation on Forex.com’s end, and a lack of documentation on the Lightstreamer side of things, it was no easy feat to get something working. With that being said, after going on a short hiatus of not working on this and then revisiting it with fresh eyes, I can finally utilize Forex.com’s API and place trades via Python.


What is Forex.com.


Forex.com is a foreign exchange broker. In layman’s terms, they’re a service that allows you to exchange currency for other currencies (like converting US dollars to Euros) on the foreign exchange market. The foreign exchange market is the largest financial market in the world, with a daily volume of over 6 trillion dollars. For reference, the U.S. stock market sees about 90 billion dollars of daily volume. Due to this high level, there’s a lot of liquidity in the forex market, making it a great candidate for algorithmic trading.


Getting Started.


Before anything else, an account with Forex.com is needed, and thankfully they offer demo accounts, so you don’t have to risk your actual money when you’re getting your code setup and working.


As far as I know, the only way to gain API access for the created account is by contacting their support team and requesting API access. This process may have been improved since my experience, but I’m sure this approach will still work even if there’s an automated process now.


This is also the only way I’m aware of to gain access to the API documentation, as I haven’t been able to search for it using a search engine. Due to this, I will not be able to show screenshots or snippets from the documentation itself, but I will show my implementation.


Getting a Session ID.


A session ID is needed for every request made to the API, so we need to get one before doing anything else. To do this, we’ll need to make a POST request to the TradingAPI’s session endpoint. The body of the POST will need to include our username, password, and app key. The username and password are the exact same as you would use to access the Forex.com WebTrader, and the app key is a value that gets provided to you when you set up API access to your live or demo account. Here’s an example get session() method.


def get session(): body = response = requests.post('https://ciapi.cityindex.com/TradingAPI/session', json=body) if response.status code == 200: return response.json()['Session'] else: return None.


Getting Your Trading Account ID.


Now that we have our session ID, we can now retrieve our Trading Account ID from the API. To do so, we need to make a request to the /useraccount/ClientAndTradingAccount endpoint. This call and all other requests require us to include authentication headers, which consist of your username and the session ID from the step above. Here’s an example get trading account id() method.


def get trading account id(): response = requests.get( 'https://ciapi.cityindex.com/TradingAPI/useraccount/ClientAndTradingAccount', headers= if response.status code == 200: return response.json()['TradingAccounts'][0]['TradingAccountId'] else: return None.


Getting One or More Market ID's.


Now we need to get some market IDs for the different markets we might want to trade in. For this example, I’ll only be looking to place trades in the EUR/USD market. This is probably one of the simplest requests we’ll make. The endpoint we need to hit is the /market/fullsearchwithtags endpoint, which takes in a query parameter that lets us pass in the market names we want information about. Here’s an example get market info() method.


def get market info(): response = requests.get( 'https://ciapi.cityindex.com/TradingAPI/market/fullsearchwithtags?query=EUR%2FUSD', headers= ) if response.status code == 200: return response.json()['MarketInformation'][0]['MarketId'] else: return None.


Getting Current Price Data.


Here’s where the meat and potatoes of this process come in. All previous and future steps involve us making requests to a HTTP service, but we need to interface with a streaming API to get current price data. In this case, Forex.com is using a library called Lightstreamer (https://lightstreamer.com) to stream data to clients. Unfortunately, there is no python client library straight from Lightstreamer. Fortunately, someone has made their own version for us to use. To use it, just run:


pip install lightstreamer-client.


Now that we have our Lightstreamer Client library, we need to build the connection and subscribe to the correct data stream. First things first, we need to create a LightstreamerClient object. This takes in our username, session ID, API Url, and something named an adapter set . In this instance, the adapter set is STREAMINGALL .


lightstreamer client = LightstreamerClient( , , "https://push.cityindex.com/", "STREAMINGALL" )


Next up is creating our LightstreamerSubscription object. This is what determines what information we get back in the stream response. This object takes 4 parameters: mode, adapter, items, and fields. Below is a quick description of each.


Mode : This is considered a “subscription mode” within the Lightstreamer documentation. We will use MERGE as our mode for this example. Adapter : The adapter we want to connect to, and is set up on Forex.com’s side. For getting price data, we will use the PRICES adapter. Items : An array of items we want information about. For each price item, they’re in the format of PRICE.. Fields : The fields on the response object that we want included in the response. The “required” fields that we’ll need for placing trades are Bid, Offer, and AuditId.


Here’s an example of all these fields broken out using methods we previously created.


subscription = LightstreamerSubscription( mode="MERGE", adapter="PRICES", items=[f"PRICE."], fields=["Bid", "Offer", "AuditId"] )


Now that we have a subscription object, we need to provide a method to add as an event listener. In this case, we’ll make a method called on item update(update item) which takes in an object that has all the fields we requested as part of the subscription object setup. Below is a sample event listener method that simply prints out the fields we wanted. For your own usage, you would want to save these in some way to be used later on. We’ll also include the call that adds the method as an event listener.


def on item update(update item): print(update item['values']['AuditId']) print(update item['values']['Offer']) print(update item['values']['Bid']) subscription.addlistener(on item update)


All that’s left now is connecting to the server side of Lightstreamer, and connecting the subscription to that connection. After making these two calls, we’ll start getting updates every time the streaming API pushes our new values. Here’s how to do that.


lightstreamer client.connect() sub key = lightstreamer client.subscribe(subscription)


As you can see, when subscribing, we get a key value. This can be used at a later time to kill the connection like so.


lightstreamer client.unsubscribe(sub key) lightstreamer client.disconnect()


Placing the Trade.


We finally have all the information we need to place a trade. To do so, we need to construct a JSON object that contains information about the trade we want to place. For this object, we’ll need data from a few different things. First, we need the Audit ID and either the Bid or Offer price from the streaming API (the price used is based on if this is a buy or sell operation). We will also need the market ID of what market we want to trade in, as well as your Trading Account ID from earlier. In this example, I’m requesting a static quantity of 10,000, but this could also be easily made into a variable that can be modified for each request. The same goes for the PriceTolerance value, which determines how much slippage in price you’re willing to allow. Here’s the full example place trade() method.


def place order(): body = response = requests.post( 'https://ciapi.cityindex.com/TradingAPI/order/newtradeorder', json=body, headers= ) if response.status code == 200: print(response.json()) else: print('An error occurred. Please try again', response.json())