FiveTwenty¶
FiveTwenty is a Python client for OANDA's v20 REST API. Read market data, manage orders and trades, and follow account activity through async or synchronous code.
The library turns API responses into typed Python models, using Decimal for
financial values and datetime for timestamps. It also manages HTTP connections,
formats requests and provides structured exceptions when something goes wrong.
Find what you need¶
| You want to… | Start here |
|---|---|
| Set up your first connection | Installation, then authentication |
| Create and close a practice trade | Your first trade |
| Solve a specific integration problem | Guides |
| Look up a method, parameter or field | API reference |
| Run a script or notebook | Examples |
| Contribute to the library | Contributing |
Start with a read-only request¶
You need Python 3.10 or later and an OANDA v20 practice account. In a uv project,
install FiveTwenty and the optional python-dotenv helper:
With pip, use python -m pip install fivetwenty python-dotenv instead.
Create a .env file in your project directory. Replace the placeholders with your
practice token and account ID, and add .env to .gitignore:
FIVETWENTY_OANDA_TOKEN=your-practice-token
FIVETWENTY_OANDA_ACCOUNT=your-account-id
FIVETWENTY_OANDA_ENVIRONMENT=practice
Save the following as quickstart.py alongside .env. The script uses
AsyncClient to read your balance and a price snapshot for EUR/USD. It checks that
the client is configured for practice and does not place an order.
import asyncio
from dotenv import load_dotenv
from fivetwenty import AsyncClient, Environment
load_dotenv()
async def main() -> None:
async with AsyncClient() as client:
if client.config.environment != Environment.PRACTICE:
message = "Use a practice account for this example"
raise ValueError(message)
response = await client.accounts.get_account_summary(client.account_id)
account = response["account"]
print(f"Balance: {account.balance} {account.currency}")
response_prices = await client.pricing.get_pricing(
client.account_id, instruments=["EUR_USD"]
)
for price in response_prices["prices"]:
print(f"{price.instrument}: {price.closeout_bid} / {price.closeout_ask}")
if __name__ == "__main__":
asyncio.run(main())
Run uv run quickstart.py, or python quickstart.py if you installed with pip.
The load_dotenv() call loads the file into your process environment; FiveTwenty
reads those environment variables to configure the client.
Understand the response¶
response is a dictionary. Its "account" entry contains an AccountSummary model,
so account.balance gives you a Decimal and account.currency gives you the
account's currency. The dictionary also retains metadata such as
response["lastTransactionID"], which you can use to track account changes.
The pricing response follows the same pattern: response_prices["prices"]
contains a list of price models. See models and response shapes
for more about working with model attributes and API field names.
For synchronous code, use Client. The async and sync guide
shows both clients and explains how to close connections and streams.
API scope and compatibility¶
FiveTwenty covers accounts, instruments, orders, trades, positions, pricing and transactions. The instruments and order features you can use depend on your OANDA account. OANDA validates each request against the account's permissions and settings.
The SDK retries eligible read requests after selected failures and sends write requests once. If a write times out, check account or transaction state before submitting it again. The client reference explains retry settings, timeouts and datetime formats; the connection guide covers recovery.
While FiveTwenty is below version 1.0, minor releases may include breaking changes. Read the changelog for migration notes before upgrading.