How to connect to OandaAPI

by Num3Ilia 21 Apr 2024

Overview

Connecting to OandaAPI with request library utilizing their documentation and pulling available instruments which are available to be traded for your account.

In order to achieve our goal, we need first to get our hand on:

  • Oanda Account Number (demo or paper account)
  • Oanda Access Tocken which will be generated from the account management portal

All details for above work can be found at this documentation link, called Introduction.

Below examples is what you are looking for (please don’t use them as they are fake):

OANDA_ACCOUNT_ID = "101-003-2234342345-001"

OANDA_ACCESS_TOKEN = "2a12s5d1a5f3297b7ae1324327f05ea38-d0dg57ffa389498165dhh1cc39f59382"

First of all, in the project root create a file names .env, once you created please paste the above information in it. We we'll be using a python module to pull out those variables and we we'll always be careful not to use that directly in our code.

Get Started

First aim for this would be to play with the API located here Oanda Account Endpoints.

import requests
from dotenv import load_dotenv
import os

# load variables from file
load_dotenv()

account_id = os.getenv('OANDA_ACCOUNT_ID')
access_token = os.getenv('OANDA_ACCESS_TOKEN')

# API URL for retrieving data (example:getaccounts)
url = f"https://api-fxpractice.oanda.com/v3/accounts"

# Setup headers to include your access token for authentication
headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {access_token}'
}

# Makea GET request to API
response = requests.get(url, headers=headers)

# Print the status code and data
print("StatusCode:", response.status_code)
print("JSONResponse:", response.json())


Output:
-> StatusCode: 200
-> JSONResponse: {'accounts': [{'id': '101-004-10931195-001', 'tags': []}]}


Code Brake down:

1. Import required modules to enhance our code
2. We pull out the variables which are not going to be shared with everybody and bring them in our environment variables
3. We construct the accounts URL to be able to pull the details which are written in Oanda documentation
4. Create the headers which will be static for all our requests to Oanda
5. Make the GET request to Oanda API
6. Print status of the request (code and output)

So, as you can see, we managed to connect to Oanda and test connection, now we can go deeper in documentation.

Expand our initial code

Lets extract the status of the account.

The only modifications which we have to perform for the call, is to change the URL call and add your Oanda account_id

# API URL for retrieving data (example:getaccounts)
url=f"https://api-fxpractice.oanda.com/v3/accounts/{account_id}/"

I'm not going to print out the output as its quite long, but if you go to Oanda Account Endpoints  section GET v3/accounts/{account_id}/. -> curl: Get details for Account you will be able to see the output and compare to yours.

Going further into Oanda documentation, lets pull the instruments to which your account have access too:

import requests
from dotenv import load_dotenv
import os

# Load variables from file
load_dotenv()

account_id=os.getenv('OANDA_ACCOUNT_ID')
access_token=os.getenv('OANDA_ACCESS_TOKEN')


# API URL for retrieving data (example:getaccounts)
url=f"https://api-fxpractice.oanda.com/v3/accounts/{account_id}/instruments"

# Setup headers to include your access token for authentication
headers={
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {access_token}'
}

# Makea GET request to API
response = requests.get(url,headers=headers)

# Print the status code and data
print("StatusCode:", response.status_code)
print("JSONResponse:", response.json())

# Creating the list of instruments and filling it with content from Oanda
instrs = []
for i in range(len(response.json()['instruments'])):
    instrs.append(response.json()['instruments'][i]['name'])

Code Brake down:
1. Import required modules to enhance our code
2. We pull out the variables which are not going to be shared with everybody and bring them in our environment variables
3. We construct the accounts URL to be able to pull the details which are written in Oanda documentation
4. Create the headers which will be static for all our requests to Oanda
5. Make the GET request to Oanda API
6. Print status of the request (code and output)
7. Create a list with all instruments using a for loop

Now, this code can receive some love in making it a little bit more efficient but clearly more pythonic.

# Get the list of instruments that can be traded in Oanda with list comprehension
inst = [response.json()['instruments'][i]['name'] for i in range(len(response.json()['instruments']))]

As you can this, we are using  Python list comprehension to achieve the same result but in a more beaufiful manner. But this is not the end of what we can do, lets try a more python version to enhance our code.

# A more pythonic approach is to use the get() function which looks like this
instruments = [inst['name'] for inst in response.json().get('instruments', [])]

This would be our last improvement for this code. Using list comprehension and utilizing the get method.

Note:  The get() method on dictionary is a way to fetch a value from a dictionary safely. It allows you to specify a default value to return if the specified key is not found. In our case data.get('instruments', []) tells Python to return the value associated with the key 'instruments' in the dictionary 'data'. If the key 'instruments' does not exists, it returns and empty list '[]' instead thus avoiding a 'KeyError' code pottentially causing the program to crash or require additional error handling logic. Method get() with an empty list makes the subsequent  list comprehension safe to execute even if the data is incomplete or malformed.

There is also a way to pull details for a particular instrument or multile instruments if you separate by comma, but I will not go into deep details here. You just have to change the URL which you call the instruments, like this:

# retrieve only one instrument
import requests
from dotenv import load_dotenv
import os

# load variables from file
load_dotenv()

account_id=os.getenv('OANDA_ACCOUNT_ID')
access_token=os.getenv('OANDA_ACCESS_TOKEN')


# API URL for retrieving data (example:getaccounts)
url=f"https://api-fxpractice.oanda.com/v3/accounts/{account_id}/instruments?instruments=EUR_USD"

# Setup headers to include your access token for authentication
headers={
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {access_token}'
}

# Makea GET request to API
response = requests.get(url,headers=headers)

# Print the status code and data
print("StatusCode:", response.status_code)
print("JSONResponse:", response.json())

And if you look to get multiple instruments, you just have to increase the URL with a comma and add what are you looking for like this:

# API URL for retrieving data (example:getaccounts)
url=f"https://api-fxpractice.oanda.com/v3/accounts/{account_id}/instruments?instruments=EUR_USD,GBP_JPY"

To close out this HowTo post, I will add the final result which we'll be using in the future on our others HowTo articles:

import requests
from dotenv import load_dotenv
import os

# load variables from file
load_dotenv()

account_id=os.getenv('OANDA_ACCOUNT_ID')
access_token=os.getenv('OANDA_ACCESS_TOKEN')


# API URL for retrieving data (example:getaccounts)
url=f"https://api-fxpractice.oanda.com/v3/accounts/{account_id}/instruments"

# Setup headers to include your access token for authentication
headers={
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {access_token}'
}

# Makea GET request to API
response = requests.get(url,headers=headers)

# handling API response
if response.status_code == 200:
    print("Successfully connected to Oanda")

    data = response.json()
    # List comprehencion containing the instruments avoiding a KeyError we add [] in get
    # If the key 'instruments' does not exist, it returns an empty list [] instead.
    instr = [instr['name'] for instr in data.get('instruments',[])]
    
    print("Instruments available for trading, multiple per line")
    for i in range(0, len(instr), 12):
        # Slice 6 instruments per line to be printed
        six_items = instr[i:i+12]
        # Print items joined by comma
        print(", ".join(six_items))

else:
    print("Failed to connect to Oanda")
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.text}")
    # maybe you'll need for more context also the json
    print("JSONResponse:", response.json())

Code Brake down:
1. 1 to 5 are the same as the above examples
2. IF response is 200 means OK then we process the instruments into a list
3. Print multiple instruments per same line
4. In case something is wrong, we just print the output to be able to debug it

Wrap UP

We manage to use Python to connect to Oanda via their API service.
We manage to pull account details and get available instruments.
We managed to optime our code and make it look a little better.

References

Oanda API documentation: LINK

GitHub 

testOandaAPI.py

 

Happy PiPing folks!