Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 26 additions & 23 deletions docs/_reference_docs/ASYNC_MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Async Migration Guide for project-x-py

This guide helps you migrate from the synchronous ProjectX SDK to the new async/await architecture.
This guide helps you migrate from the synchronous ProjectX SDK to the new async/await architecture.
**Note:** All public classes and factory functions are now async-ready by default—no Async* prefix is required.

## Table of Contents

Expand Down Expand Up @@ -69,7 +70,7 @@ await realtime_client.add_callback("position_update", on_position_update)
1. **All API methods are now async** - Must use `await`
2. **Context managers are async** - Use `async with`
3. **Callbacks can be async** - Better event handling
4. **Import changes** - New async classes available
4. **Imports updated** - All classes and factory functions are async-ready and use the canonical names (no Async* prefix).

## Migration Steps

Expand All @@ -79,8 +80,8 @@ await realtime_client.add_callback("position_update", on_position_update)
# Old imports
from project_x_py import ProjectX, create_trading_suite

# New imports for async
from project_x_py import AsyncProjectX, create_async_trading_suite
# New imports (all classes/factories are async-ready by default)
from project_x_py import ProjectX, create_trading_suite
```

### Step 2: Update Client Creation
Expand All @@ -91,7 +92,7 @@ client = ProjectX.from_env()
client.authenticate()

# New async client
async with AsyncProjectX.from_env() as client:
async with ProjectX.from_env() as client:
await client.authenticate()
```

Expand All @@ -116,11 +117,11 @@ data = await client.get_data("MGC", days=5)
order_manager = create_order_manager(client)
position_manager = create_position_manager(client)

# New async managers
order_manager = create_async_order_manager(client)
# New async managers (all managers are now async-ready by default)
order_manager = create_order_manager(client)
await order_manager.initialize()

position_manager = create_async_position_manager(client)
position_manager = create_position_manager(client)
await position_manager.initialize()
```

Expand All @@ -138,13 +139,13 @@ def main():
print(f"Connected as: {account.name}")
```

**Async:**
**Async (now using canonical names):**
```python
import asyncio
from project_x_py import AsyncProjectX
from project_x_py import ProjectX

async def main():
async with AsyncProjectX.from_env() as client:
async with ProjectX.from_env() as client:
await client.authenticate()
print(f"Connected as: {client.account_info.name}")

Expand All @@ -160,9 +161,9 @@ response = order_manager.place_market_order("MGC", 0, 1)
orders = order_manager.search_open_orders()
```

**Async:**
**Async (now using canonical names):**
```python
order_manager = create_async_order_manager(client)
order_manager = create_order_manager(client)
await order_manager.initialize()

response = await order_manager.place_market_order("MGC", 0, 1)
Expand All @@ -181,10 +182,10 @@ data_manager.initialize()
data_manager.start_realtime_feed()
```

**Async:**
**Async (now using canonical names):**
```python
realtime_client = create_async_realtime_client(jwt_token, account_id)
data_manager = create_async_data_manager("MGC", client, realtime_client)
realtime_client = create_realtime_client(jwt_token, account_id)
data_manager = create_data_manager("MGC", client, realtime_client)

await realtime_client.connect()
await data_manager.initialize()
Expand All @@ -204,9 +205,9 @@ suite["realtime_client"].connect()
suite["data_manager"].initialize()
```

**Async:**
**Async (now using canonical names):**
```python
suite = await create_async_trading_suite(
suite = await create_trading_suite(
"MGC", client, jwt_token, account_id,
timeframes=["5min", "15min"]
)
Expand All @@ -217,6 +218,8 @@ await suite["data_manager"].initialize()

## Common Patterns

All public classes and factory functions are async-ready—use canonical names (no Async* prefix).

### 1. Concurrent Operations

```python
Expand Down Expand Up @@ -299,7 +302,7 @@ monitor_task = asyncio.create_task(monitor_positions(position_manager))

1. **Always use async context managers:**
```python
async with AsyncProjectX.from_env() as client:
async with ProjectX.from_env() as client:
# Client is properly cleaned up
```

Expand Down Expand Up @@ -399,16 +402,16 @@ def trading_bot():
time.sleep(60)
```

**New Async Bot:**
**New Async Bot (now using canonical names):**
```python
import asyncio
from project_x_py import AsyncProjectX, create_async_trading_suite
from project_x_py import ProjectX, create_trading_suite

async def trading_bot():
async with AsyncProjectX.from_env() as client:
async with ProjectX.from_env() as client:
await client.authenticate()

suite = await create_async_trading_suite(
suite = await create_trading_suite(
"MGC", client, client.jwt_token,
client.account_info.id
)
Expand Down
36 changes: 19 additions & 17 deletions docs/_reference_docs/async_refactoring_issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ The current synchronous architecture has several limitations:
- Converted all managers to async: OrderManager, PositionManager, RealtimeDataManager, OrderBook
- Implemented proper async locking and thread safety
- Created comprehensive test suites for all managers (62 tests total)
- Ensured all managers can share AsyncProjectXRealtimeClient instance
- Ensured all managers can share ProjectXRealtimeClient instance

**Phase 4 (SignalR/WebSocket Integration) - COMPLETED on 2025-07-31**
- Created AsyncProjectXRealtimeClient with async wrapper around SignalR
- Created ProjectXRealtimeClient with async wrapper around SignalR
- Implemented async event handling and callback system
- Added JWT token refresh and reconnection support
- Created async factory functions for all components
Expand Down Expand Up @@ -153,14 +153,14 @@ The current synchronous architecture has several limitations:
- Thread-safe operations using asyncio.Lock
- Runs synchronous SignalR operations in executor for compatibility

**Async Factory Functions Created:**
- `create_async_client()` - Create AsyncProjectX client
- `create_async_realtime_client()` - Create async real-time WebSocket client
- `create_async_order_manager()` - Create async order manager
- `create_async_position_manager()` - Create async position manager
- `create_async_data_manager()` - Create async OHLCV data manager
- `create_async_orderbook()` - Create async market depth orderbook
- `create_async_trading_suite()` - Create complete async trading toolkit
**Async Factory Functions Created (now canonical, async-ready by default):**
- `create_client()` - Create ProjectX client
- `create_realtime_client()` - Create real-time WebSocket client
- `create_order_manager()` - Create order manager
- `create_position_manager()` - Create position manager
- `create_data_manager()` - Create OHLCV data manager
- `create_orderbook()` - Create market depth orderbook
- `create_trading_suite()` - Create complete async trading toolkit

**Integration Features:**
- All async managers share single AsyncProjectXRealtimeClient instance
Expand Down Expand Up @@ -205,16 +205,16 @@ This refactoring will introduce breaking changes:
3. Event handlers must be async functions
4. Example code and integrations need updates

## Migration Guide (Draft)
## Migration Guide

```python
# Old (Sync)
client = ProjectX(api_key, username)
client.authenticate()
positions = client.get_positions()

# New (Async)
async with AsyncProjectX(api_key, username) as client:
# New (Async-ready, canonical names)
async with ProjectX(api_key, username) as client:
await client.authenticate()
positions = await client.get_positions()
```
Expand Down Expand Up @@ -257,14 +257,14 @@ aioresponses = ">=0.7.6" # For mocking async HTTP

```python
import asyncio
from project_x_py import AsyncProjectX, create_async_trading_suite
from project_x_py import ProjectX, create_trading_suite

async def trading_bot():
async with AsyncProjectX(api_key, username) as client:
async with ProjectX(api_key, username) as client:
await client.authenticate()

# Create async trading suite
suite = await create_async_trading_suite(
# Create trading suite (now async-ready by default)
suite = await create_trading_suite(
instrument="MGC",
project_x=client,
jwt_token=client.session_token,
Expand Down Expand Up @@ -325,4 +325,6 @@ if __name__ == "__main__":

---

**Note:** All public classes and factory functions are now async-ready by default. The Async* prefix is no longer used—simply use the canonical names shown in the latest examples above.

**Note**: This refactoring aligns with the CLAUDE.md directive for "No Backward Compatibility" and "Clean Code Priority" during active development.
Loading