Broker-agnostic trading library for Python
Project description
Trading Lib
A broker-agnostic Python trading library that abstracts broker APIs for platform-independent algorithmic trading strategies.
Features
- Broker Agnostic: Write strategies once, run on any supported broker
- Async-First: Built with
asynciofor non-blocking I/O operations - Type-Safe: Full type hints with Pydantic models for runtime validation
- Extensible: Easy to add new broker implementations via Protocol interfaces
- Production Ready: Rate limiting, error handling, and connection management built-in
Supported Brokers
| Broker | Status | Notes |
|---|---|---|
| MetaTrader 5 | โ Implemented | Full API coverage |
| Interactive Brokers | ๐ Planned | Coming soon |
| Binance | ๐ Planned | Coming soon |
Installation
# Using pip
pip install tradingkit-mt5
# Using uv
uv add tradingkit-mt5
# From source
git clone https://github.com/LucianP984/py-trading-lib.git
cd py-trading-lib
pip install -e .
Requirements
- Python 3.10+
- MetaTrader 5 terminal installed (Windows only for MT5)
- Pydantic 2.0+
Quick Start
import asyncio
from decimal import Decimal
from trading_lib import create_broker, BrokerType, OrderRequest, TradeAction, OrderType
async def main():
# Create broker instance
broker = create_broker(BrokerType.MT5)
# Connect to MT5 terminal
await broker.connect(
login=12345678,
password="your_password",
server="YourBroker-Demo"
)
# Get account info
account = await broker.get_account_info()
print(f"Balance: {account.balance} {account.currency}")
print(f"Equity: {account.equity}")
print(f"Free Margin: {account.margin_free}")
# Get symbol info
symbol = await broker.get_symbol_info("EURUSD")
print(f"EURUSD Spread: {symbol.spread} points")
# Get latest tick
tick = await broker.get_symbol_tick("EURUSD")
print(f"Bid: {tick.bid}, Ask: {tick.ask}")
# Get historical bars
from trading_lib import Timeframe
bars = await broker.get_bars("EURUSD", Timeframe.H1, start=0, count=100)
print(f"Retrieved {len(bars)} bars")
# Place a market order
request = OrderRequest(
action=TradeAction.DEAL,
symbol="EURUSD",
volume=Decimal("0.1"),
type=OrderType.BUY,
deviation=10,
magic=12345,
comment="Trading Lib"
)
# Check order before sending
check = await broker.check_order(request)
if check.valid:
result = await broker.send_order(request)
if result.success:
print(f"Order placed! Ticket: {result.order}")
# Get open positions
positions = await broker.get_positions()
for pos in positions:
print(f"Position {pos.ticket}: {pos.symbol} {pos.volume} lots, P/L: {pos.profit}")
# Disconnect
await broker.disconnect()
asyncio.run(main())
Architecture
The library uses Protocol-based abstractions for broker-agnostic design:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Trading Strategy โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ BrokerProtocol โ
โ (ConnectionProtocol, AccountProtocol, OrderProtocol, ...) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ MT5Clientโ โ IBClient โ โ Binance โ
โ โ โ (planned)โ โ (planned)โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
API Reference
Factory
from trading_lib import create_broker, BrokerType
# Create MT5 broker
broker = create_broker(BrokerType.MT5)
# With custom path
broker = create_broker(BrokerType.MT5, path="C:/Program Files/MT5/terminal64.exe")
Connection
# Connect with login
await broker.connect(login=12345, password="pass", server="Demo-Server")
# Check connection
is_connected = await broker.is_connected()
# Disconnect
await broker.disconnect()
# Context manager
async with create_broker(BrokerType.MT5) as broker:
await broker.connect(...)
# Auto-disconnects on exit
Account Information
account = await broker.get_account_info()
# AccountInfo(login, balance, equity, margin, margin_free, leverage, ...)
terminal = await broker.get_terminal_info()
# TerminalInfo(name, company, connected, trade_allowed, ...)
Symbols
# Get all symbols
symbols = await broker.get_symbols()
# Filter by group
forex_symbols = await broker.get_symbols(group="*USD*")
# Get specific symbol info
eurusd = await broker.get_symbol_info("EURUSD")
# Get latest tick
tick = await broker.get_symbol_tick("EURUSD")
# Select symbol in Market Watch
await broker.select_symbol("EURUSD", enable=True)
Market Data
from trading_lib import Timeframe
# Get bars by position (0 = current bar)
bars = await broker.get_bars("EURUSD", Timeframe.H1, start=0, count=100)
# Get bars by date range
from datetime import datetime
bars = await broker.get_bars(
"EURUSD",
Timeframe.M15,
start=datetime(2024, 1, 1),
end=datetime(2024, 1, 31)
)
# Get ticks
ticks = await broker.get_ticks("EURUSD", start=datetime.now(), count=1000)
Orders
from trading_lib import OrderRequest, TradeAction, OrderType, OrderFilling
# Market order
request = OrderRequest(
action=TradeAction.DEAL,
symbol="EURUSD",
volume=Decimal("0.1"),
type=OrderType.BUY,
deviation=10,
)
# Pending order
request = OrderRequest(
action=TradeAction.PENDING,
symbol="EURUSD",
volume=Decimal("0.1"),
type=OrderType.BUY_LIMIT,
price=Decimal("1.0800"),
sl=Decimal("1.0750"),
tp=Decimal("1.0900"),
)
# Check and send
check = await broker.check_order(request)
if check.valid:
result = await broker.send_order(request)
# Get active orders
orders = await broker.get_orders()
orders = await broker.get_orders(symbol="EURUSD")
Positions
# Get all positions
positions = await broker.get_positions()
# Filter by symbol
eurusd_positions = await broker.get_positions(symbol="EURUSD")
# Filter by ticket
position = await broker.get_positions(ticket=123456)
Trade History
from datetime import datetime, timedelta
start = datetime.now() - timedelta(days=30)
end = datetime.now()
# Get historical orders
orders = await broker.get_history_orders(start=start, end=end)
# Get deals
deals = await broker.get_history_deals(start=start, end=end)
Market Depth
# Subscribe to market depth
await broker.subscribe_book("EURUSD")
# Get current book
book = await broker.get_book("EURUSD")
for entry in book:
print(f"{entry.type}: {entry.price} x {entry.volume}")
# Unsubscribe
await broker.unsubscribe_book("EURUSD")
Error Handling
from trading_lib import (
TradingError,
ConnectionError,
AuthenticationError,
OrderRejectedError,
InsufficientMarginError,
)
try:
await broker.connect(login=12345, password="wrong")
except AuthenticationError as e:
print(f"Login failed: {e.message} (code: {e.code})")
try:
result = await broker.send_order(request)
except OrderRejectedError as e:
print(f"Order rejected: {e.message}")
print(f"Original request: {e.request}")
except InsufficientMarginError:
print("Not enough margin")
Adding Custom Brokers
Implement the BrokerProtocol to add new broker support:
from trading_lib import BrokerProtocol, register_broker, BrokerType
class MyBrokerClient(BrokerProtocol):
@property
def broker_name(self) -> str:
return "MyBroker"
async def connect(self, ...) -> bool:
# Implementation
...
async def get_account_info(self) -> AccountInfo:
# Implementation
...
# Implement all protocol methods...
# Register with factory
register_broker(BrokerType.MY_BROKER, MyBrokerClient)
Development
# Clone repository
git clone https://github.com/LucianP984/py-trading-lib.git
cd py-trading-lib
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Type checking
mypy trading_lib
# Linting
ruff check trading_lib
License
MIT License - see LICENSE for details.
Disclaimer
This software is for educational and research purposes only. Trading financial instruments carries significant risk. Always test thoroughly with demo accounts before using real money. The authors are not responsible for any financial losses incurred through the use of this software.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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
File details
Details for the file tradingkit_mt5-0.1.0.tar.gz.
File metadata
- Download URL: tradingkit_mt5-0.1.0.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea4c15330a767c200851bb798391d40791c4082722835688c44d6ef4700115d0
|
|
| MD5 |
61acb4b95e28030bf5f5b7f4c135e9bc
|
|
| BLAKE2b-256 |
6b37345676fa60ffbbce596be66b9e6cb79f49ef0c91ae1301018de7fd6a1ff6
|
Provenance
The following attestation bundles were made for tradingkit_mt5-0.1.0.tar.gz:
Publisher:
publish.yml on LucianP984/py-trading-lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tradingkit_mt5-0.1.0.tar.gz -
Subject digest:
ea4c15330a767c200851bb798391d40791c4082722835688c44d6ef4700115d0 - Sigstore transparency entry: 928411737
- Sigstore integration time:
-
Permalink:
LucianP984/py-trading-lib@784a7be5c189c74b6bdcd8b375eca8f8e57e28c7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/LucianP984
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@784a7be5c189c74b6bdcd8b375eca8f8e57e28c7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tradingkit_mt5-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tradingkit_mt5-0.1.0-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d354875eaa82b7282543796c609db4674ce7f4cca90a3f71adb653a48bcb2f36
|
|
| MD5 |
7c346255e261e0e73b3934c704207e76
|
|
| BLAKE2b-256 |
cab1782dc37646d28f370717c079847bfb12eccf548ed4e748ef62e816b67fab
|
Provenance
The following attestation bundles were made for tradingkit_mt5-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on LucianP984/py-trading-lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tradingkit_mt5-0.1.0-py3-none-any.whl -
Subject digest:
d354875eaa82b7282543796c609db4674ce7f4cca90a3f71adb653a48bcb2f36 - Sigstore transparency entry: 928411738
- Sigstore integration time:
-
Permalink:
LucianP984/py-trading-lib@784a7be5c189c74b6bdcd8b375eca8f8e57e28c7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/LucianP984
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@784a7be5c189c74b6bdcd8b375eca8f8e57e28c7 -
Trigger Event:
release
-
Statement type: