Simple, elegant Python client for OANDA's REST API v20
Project description
FiveTwenty
A comprehensive, production-ready Python client for the OANDA v20 REST API.
Features
- Async-first with sync wrapper
- Minimal dependencies (only httpx + pydantic)
- Robust client with retries, rate limiting, and comprehensive error handling
- Complete API coverage with 100% endpoint implementation (all 7 endpoint groups)
Quick Start
Installation
pip install fivetwenty
Or with uv:
uv add fivetwenty
Async Usage (Recommended)
import asyncio
from decimal import Decimal
from fivetwenty import AsyncClient, Environment
async def main():
async with AsyncClient(
token="your-token-here",
environment=Environment.PRACTICE
) as client:
# Get accounts
accounts = await client.accounts.list()
account_id = accounts[0].id
# Create a market order
order = await client.orders.post_market_order(
account_id=account_id,
instrument="EUR_USD",
units=1000,
stop_loss=Decimal("1.0900"),
take_profit=Decimal("1.1100"),
)
print(f"Order created: {order.last_transaction_id}")
# Stream prices for 30 seconds
import time
end_time = time.time() + 30
async for price in client.pricing.stream(account_id, ["EUR_USD"]):
if hasattr(price, 'instrument'): # It's a price update
spread = price.spread
print(f"{price.instrument}: {price.closeout_bid}/{price.closeout_ask} (spread: {spread})")
if time.time() > end_time:
break
if __name__ == "__main__":
asyncio.run(main())
Sync Usage
from decimal import Decimal
from fivetwenty import Client, Environment
with Client(token="your-token-here", environment=Environment.PRACTICE) as client:
# Get accounts
accounts = client.accounts.list()
account_id = accounts[0].id
# Create a market order
order = client.orders.post_market_order(
account_id=account_id,
instrument="EUR_USD",
units=1000,
stop_loss=Decimal("1.0900")
)
# Stream prices (blocking iterator)
count = 0
for price in client.pricing.stream_iter(account_id, ["EUR_USD"]):
if hasattr(price, 'instrument'):
print(f"{price.instrument}: {price.closeout_bid}/{price.closeout_ask}")
count += 1
if count > 10:
break # Stop after 10 updates
Configuration
Environment Variables
FIVETWENTY_OANDA_TOKEN: Your API tokenFIVETWENTY_USER_AGENT_EXTRA: Additional user agent info
Advanced Configuration
from fivetwenty import AsyncClient, Environment
import httpx
client = AsyncClient(
token="your-token",
environment=Environment.LIVE, # Use live trading
timeout=60.0, # 60 second timeout
max_retries=5, # Retry failed requests
# Custom HTTP client with proxy
transport=httpx.AsyncClient(
proxies="http://proxy.example.com:8080",
verify="/path/to/ca-bundle.crt"
),
# Custom logging
logger=your_logger,
)
Error Handling
from fivetwenty import VeeTwentyError, StreamStall
try:
order = await client.orders.post_market_order(...)
except VeeTwentyError as e:
print(f"API Error: {e}")
print(f"Status: {e.status}")
print(f"Code: {e.code}")
print(f"Request ID: {e.request_id}")
if e.retryable:
# Can retry this operation
pass
try:
async for price in client.pricing.stream(...):
process(price)
except StreamStall:
# Reconnect and try again
pass
Requirements
- Python 3.10+
- httpx >= 0.25.0
- pydantic >= 2.5.0
API Coverage
OANDA v20 API Implementation
- Account Management: Complete account operations, configuration updates, and change polling
- Order Operations: Full order lifecycle - create, list, get, cancel, replace, and client extensions
- Trade Management: Complete trade operations - list, get, close, modify, and dependent orders
- Position Management: Full position operations - list, get, close by instrument
- Pricing & Streaming: Real-time pricing, reliable streaming, and historical candles
- Transaction History: Complete audit trail, streaming, and incremental updates
License
MIT License - see LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
fivetwenty-0.2.0.tar.gz
(87.7 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
fivetwenty-0.2.0-py3-none-any.whl
(108.2 kB
view details)
File details
Details for the file fivetwenty-0.2.0.tar.gz.
File metadata
- Download URL: fivetwenty-0.2.0.tar.gz
- Upload date:
- Size: 87.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37302d75868d22d40b4f2804424cb4434942dafeaa66a9e0acaa6fce500a8c27
|
|
| MD5 |
35b41f5a9744985189ad2719bbf2b15b
|
|
| BLAKE2b-256 |
8c8366fa34eb14cb7415d219a8684fd28faf4ba295a479b2a04d0aeb927678aa
|
File details
Details for the file fivetwenty-0.2.0-py3-none-any.whl.
File metadata
- Download URL: fivetwenty-0.2.0-py3-none-any.whl
- Upload date:
- Size: 108.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88b9214aafa5d74c6a99ea6f8923e1ae5c410cb318b04970d7365e649fb818df
|
|
| MD5 |
1fc24eab60e4733a5dbb0dc034188627
|
|
| BLAKE2b-256 |
ce076567f9598ee7f5e56f31c131f390578d1d9269dffd08892d0b6bc97cb3e6
|