Skip to main content

Simple, elegant Python client for OANDA's REST API v20

Project description

FiveTwenty

Documentation Python License: MIT Code style: ruff

A comprehensive, production-ready Python client for the OANDA v20 REST API.

Features

  • Async-first with sync wrapper
  • Type-safe with mypy strict compliance and comprehensive TypedDict responses
  • 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 python-dotenv

Or with uv:

uv add fivetwenty python-dotenv

Configuration

Create a .env file with your OANDA credentials:

FIVETWENTY_OANDA_TOKEN=your-api-token
FIVETWENTY_OANDA_ACCOUNT=your-account-id
FIVETWENTY_OANDA_ENVIRONMENT=practice

Usage

import asyncio
import time
from decimal import Decimal

from dotenv import load_dotenv

from fivetwenty import AsyncClient
from fivetwenty.models import ClientPrice, InstrumentName

# Load environment variables from .env file
load_dotenv()


async def main() -> None:
    # Zero-config client - automatically reads from environment variables
    async with AsyncClient() as client:
        # Get accounts
        accounts = await client.accounts.get_accounts()
        account_id = accounts[0].id

        # Create market order (use Decimal for financial values)
        order = await client.orders.post_market_order(
            account_id=account_id,
            instrument=InstrumentName.EUR_USD,
            units=1000,
            stop_loss=Decimal("1.0900"),
            take_profit=Decimal("1.1100"),
        )
        print(f"Order created: {order['lastTransactionID']}")

        # Stream real-time prices for 30 seconds
        end_time = time.time() + 30

        async for price in client.pricing.get_pricing_stream(
            account_id, [InstrumentName.EUR_USD]
        ):
            if isinstance(price, ClientPrice):  # Filter out heartbeats
                spread = price.closeout_ask - price.closeout_bid
                print(f"{price.instrument}: {price.closeout_bid}/{price.closeout_ask} (spread: {spread})")

            if time.time() > end_time:
                break


if __name__ == "__main__":
    asyncio.run(main())

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.

Disclaimer

This library is provided for educational and demonstration purposes only.

Trading financial instruments involves substantial risk of loss. The examples and code provided in this library are for demonstration purposes only and should not be used for actual trading without thorough testing and understanding of the risks involved.

  • Past performance is not indicative of future results
  • You are solely responsible for any trading decisions and their consequences
  • The authors and contributors accept no liability for any financial losses incurred through use of this software
  • Always test thoroughly with paper trading accounts before risking real capital
  • Consult with qualified financial advisors before making investment decisions

USE AT YOUR OWN RISK.

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.3.2.tar.gz (139.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fivetwenty-0.3.2-py3-none-any.whl (169.8 kB view details)

Uploaded Python 3

File details

Details for the file fivetwenty-0.3.2.tar.gz.

File metadata

  • Download URL: fivetwenty-0.3.2.tar.gz
  • Upload date:
  • Size: 139.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.6

File hashes

Hashes for fivetwenty-0.3.2.tar.gz
Algorithm Hash digest
SHA256 072fa549579a14d3c3a03f04fa4edaa38dc38b3944f086e775004b3aaaf24ea3
MD5 45d08e84066e4bc3d02676ee3832e64c
BLAKE2b-256 08a9c258be7b42057a6c6113ab683a4418bce967e7b7cdf679ba39f467e68347

See more details on using hashes here.

File details

Details for the file fivetwenty-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: fivetwenty-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 169.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.6

File hashes

Hashes for fivetwenty-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 39e21bb7de6bee499233e3efd18547343b7614d9eb01428ed1e5a196ea13e3b9
MD5 b6302dbd635f10012d4c5db56fb0a00c
BLAKE2b-256 9332e0fc3d604104b68ef5a92b320870f2e27bc73af77d3183a4efe55c2eb1c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page