Skip to content

Commit 43c9b54

Browse files
authored
Merge pull request #14 from TexasCoding:code_cleanup
Code_cleanup
2 parents 4bd030b + 9265f82 commit 43c9b54

31 files changed

+278
-370
lines changed

examples/01_basic_client_connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
This is the foundation for all other async examples.
77
88
Usage:
9-
Run with: uv run examples/async_01_basic_client_connection.py
9+
Run with: uv run examples/01_basic_client_connection.py
1010
Or use test.sh which sets environment variables: ./test.sh
1111
1212
Author: TexasCoding

examples/02_order_management.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
1818
Usage:
1919
Run with: ./test.sh (sets environment variables)
20-
Or: uv run examples/async_02_order_management.py
20+
Or: uv run examples/02_order_management.py
2121
2222
Author: TexasCoding
2323
Date: July 2025
@@ -32,6 +32,7 @@
3232
create_realtime_client,
3333
setup_logging,
3434
)
35+
from project_x_py.models import Order
3536

3637

3738
async def wait_for_user_confirmation(message: str) -> bool:
@@ -80,7 +81,11 @@ async def show_order_status(order_manager, order_id: int, description: str):
8081
else:
8182
# Fall back to API check for status
8283
print(f" Order {order_id} not in real-time cache, checking API...")
83-
api_order = await order_manager.get_order_by_id(order_id)
84+
api_order: Order | None = await order_manager.get_order_by_id(order_id)
85+
if not isinstance(api_order, Order):
86+
print(f" Order {order_id} not found in API either")
87+
return
88+
8489
if api_order:
8590
status_map = {1: "Open", 2: "Filled", 3: "Cancelled", 4: "Partially Filled"}
8691
status = status_map.get(api_order.status, f"Unknown ({api_order.status})")

examples/03_position_management.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
Usage:
1515
Run with: ./test.sh (sets environment variables)
16-
Or: uv run examples/async_03_position_management.py
16+
Or: uv run examples/03_position_management.py
1717
1818
Author: TexasCoding
1919
Date: July 2025
@@ -30,13 +30,14 @@
3030
create_realtime_client,
3131
setup_logging,
3232
)
33-
from project_x_py.async_realtime_data_manager import AsyncRealtimeDataManager
33+
from project_x_py.position_manager import PositionManager
34+
from project_x_py.realtime_data_manager import RealtimeDataManager
3435

3536

3637
async def get_current_market_price(
3738
client: ProjectX,
3839
symbol="MNQ",
39-
realtime_data_manager: AsyncRealtimeDataManager | None = None,
40+
realtime_data_manager: RealtimeDataManager | None = None,
4041
):
4142
"""Get current market price with async fallback for closed markets."""
4243
# Try to get real-time price first if available
@@ -74,7 +75,7 @@ async def try_get_data(days, interval):
7475
return None
7576

7677

77-
async def display_positions(position_manager):
78+
async def display_positions(position_manager: PositionManager):
7879
"""Display current positions with detailed information."""
7980
print("\n📊 Current Positions:")
8081
print("-" * 80)
@@ -88,29 +89,24 @@ async def display_positions(position_manager):
8889
# Get portfolio P&L concurrently with position display
8990
pnl_task = asyncio.create_task(position_manager.get_portfolio_pnl())
9091

92+
portfolio_pnl = await pnl_task
9193
# Display each position
92-
for symbol, position in positions.items():
93-
print(f"\n{symbol}:")
94-
print(f" Quantity: {position.quantity}")
94+
for position in positions:
95+
print(f"\n{position.contractId}:")
96+
print(f" Quantity: {position.size}")
9597
print(f" Average Price: ${position.averagePrice:.2f}")
96-
print(f" Position Value: ${position.positionValue:.2f}")
97-
print(f" Unrealized P&L: ${position.unrealizedPnl:.2f}")
98-
99-
# Show percentage change
100-
if position.averagePrice > 0:
101-
pnl_pct = (
102-
position.unrealizedPnl / (position.quantity * position.averagePrice)
103-
) * 100
104-
print(f" P&L %: {pnl_pct:+.2f}%")
98+
print(f" Position Value: ${position.averagePrice:.2f}")
99+
print(f" Unrealized P&L: ${portfolio_pnl.get('unrealized_pnl', 0):.2f}")
105100

106101
# Show portfolio totals
107-
portfolio_pnl = await pnl_task
108102
print("\n" + "=" * 40)
109-
print(f"Portfolio Total P&L: ${portfolio_pnl:.2f}")
103+
print(f"Portfolio Total P&L: ${portfolio_pnl.get('net_pnl', 0):.2f}")
110104
print("=" * 40)
111105

112106

113-
async def monitor_positions_realtime(position_manager, duration_seconds=30):
107+
async def monitor_positions_realtime(
108+
position_manager: PositionManager, duration_seconds: int = 30
109+
):
114110
"""Monitor positions with real-time updates."""
115111
print(f"\n🔄 Monitoring positions for {duration_seconds} seconds...")
116112

examples/04_realtime_data.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
1515
Usage:
1616
Run with: ./test.sh (sets environment variables)
17-
Or: uv run examples/async_04_realtime_data.py
17+
Or: uv run examples/04_realtime_data.py
1818
1919
Author: TexasCoding
2020
Date: July 2025
@@ -35,10 +35,10 @@
3535
)
3636

3737
if TYPE_CHECKING:
38-
from project_x_py.async_realtime_data_manager import AsyncRealtimeDataManager
38+
from project_x_py.realtime_data_manager import RealtimeDataManager
3939

4040

41-
async def display_current_prices(data_manager: AsyncRealtimeDataManager):
41+
async def display_current_prices(data_manager: RealtimeDataManager):
4242
"""Display current prices across all timeframes asynchronously."""
4343
print("\n📊 Current Prices:")
4444

examples/05_orderbook_analysis.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
- Market imbalance monitoring
1212
- Best bid/ask tracking
1313
14-
Uses MNQ for Level 2 orderbook data with AsyncOrderBook.
14+
Uses MNQ for Level 2 orderbook data with OrderBook.
1515
1616
Usage:
1717
Run with: ./test.sh (sets environment variables)
18-
Or: uv run examples/async_05_orderbook_analysis.py
18+
Or: uv run examples/05_orderbook_analysis.py
1919
2020
Note: This example includes several wait periods:
2121
- 5 seconds for initial data population
@@ -38,6 +38,7 @@
3838
create_realtime_client,
3939
setup_logging,
4040
)
41+
from project_x_py.orderbook import OrderBook
4142

4243

4344
async def display_best_prices(orderbook):
@@ -259,9 +260,9 @@ async def monitor_orderbook_feed(orderbook, duration_seconds=60):
259260
print(f" Update Cycles: {update_count}", flush=True)
260261

261262

262-
async def demonstrate_all_orderbook_methods(orderbook):
263-
"""Comprehensive demonstration of all AsyncOrderBook methods."""
264-
print("\n🔍 Testing all available AsyncOrderBook methods...", flush=True)
263+
async def demonstrate_all_orderbook_methods(orderbook: OrderBook):
264+
"""Comprehensive demonstration of all OrderBook methods."""
265+
print("\n🔍 Testing all available OrderBook methods...", flush=True)
265266
print(
266267
"📝 Note: Some methods may show zero values without live market data connection"
267268
)

examples/06_multi_timeframe_strategy.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
Usage:
1717
Run with: ./test.sh (sets environment variables)
18-
Or: uv run examples/async_06_multi_timeframe_strategy.py
18+
Or: uv run examples/06_multi_timeframe_strategy.py
1919
2020
Author: TexasCoding
2121
Date: July 2025
@@ -31,9 +31,10 @@
3131
create_trading_suite,
3232
)
3333
from project_x_py.indicators import RSI, SMA
34+
from project_x_py.models import BracketOrderResponse, Position
3435

3536

36-
class AsyncMultiTimeframeStrategy:
37+
class MultiTimeframeStrategy:
3738
"""
3839
Async multi-timeframe trend following strategy.
3940
@@ -47,11 +48,13 @@ class AsyncMultiTimeframeStrategy:
4748

4849
def __init__(
4950
self,
51+
client: ProjectX,
5052
trading_suite: dict,
5153
symbol: str = "MNQ",
5254
max_position_size: int = 2,
5355
risk_percentage: float = 0.02,
5456
):
57+
self.client = client
5558
self.suite = trading_suite
5659
self.symbol = symbol
5760
self.max_position_size = max_position_size
@@ -245,19 +248,20 @@ async def generate_trading_signal(self):
245248
async def execute_signal(self, signal_data: dict):
246249
"""Execute trading signal with proper risk management."""
247250
# Check current position
248-
positions = await self.position_manager.get_all_positions()
249-
current_position = positions.get(self.symbol)
251+
positions: list[Position] = await self.position_manager.get_all_positions()
252+
current_position = next(
253+
(pos for pos in positions if pos.contractId == self.symbol), None
254+
)
250255

251256
# Position size limits
252-
if (
253-
current_position
254-
and abs(current_position.quantity) >= self.max_position_size
255-
):
257+
if current_position and abs(current_position.size) >= self.max_position_size:
256258
self.logger.info("Max position size reached, skipping signal")
257259
return
258260

259261
# Get account info for position sizing
260-
account_balance = float(self.order_manager.project_x.account_info.balance)
262+
account_balance = (
263+
float(self.client.account_info.balance) if self.client.account_info else 0
264+
)
261265

262266
# Calculate position size based on risk
263267
entry_price = signal_data["price"]
@@ -285,11 +289,11 @@ async def execute_signal(self, signal_data: dict):
285289
return
286290

287291
# Get active contract
288-
instruments = await self.order_manager.project_x.search_instruments(self.symbol)
292+
instruments = await self.client.search_instruments(self.symbol)
289293
if not instruments:
290294
return
291295

292-
contract_id = instruments[0].activeContract
296+
contract_id = instruments[0].id
293297

294298
# Place bracket order
295299
self.logger.info(
@@ -313,8 +317,14 @@ async def execute_signal(self, signal_data: dict):
313317
take_profit_price=take_profit,
314318
)
315319

320+
if not isinstance(response, BracketOrderResponse):
321+
self.logger.error(f"❌ Unexpected order type: {type(response)}")
322+
return
323+
316324
if response and response.success:
317-
self.logger.info(f"✅ Order placed successfully: {response.orderId}")
325+
self.logger.info(
326+
f"✅ Order placed successfully: {response.entry_order_id}"
327+
)
318328
else:
319329
self.logger.error("❌ Order placement failed")
320330

@@ -433,7 +443,8 @@ def signal_handler(signum, frame):
433443
await suite["data_manager"].start_realtime_feed()
434444

435445
# Create and configure strategy
436-
strategy = AsyncMultiTimeframeStrategy(
446+
strategy = MultiTimeframeStrategy(
447+
client=client,
437448
trading_suite=suite,
438449
symbol="MNQ",
439450
max_position_size=2,

examples/07_technical_indicators.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22
"""
3-
Async Technical Indicators Analysis Example
3+
Technical Indicators Analysis Example
44
55
Demonstrates concurrent technical analysis using async patterns:
66
- Concurrent calculation of multiple indicators
@@ -12,7 +12,7 @@
1212
1313
Usage:
1414
Run with: ./test.sh (sets environment variables)
15-
Or: uv run examples/async_07_technical_indicators.py
15+
Or: uv run examples/07_technical_indicators.py
1616
1717
Author: TexasCoding
1818
Date: July 2025
@@ -179,7 +179,7 @@ async def on_data_update(timeframe):
179179
update_count += 1
180180

181181
# Get latest data
182-
data = await data_manager.get_data(timeframe)
182+
data: pl.DataFrame | None = await data_manager.get_data(timeframe)
183183
if data is None:
184184
return
185185

@@ -189,8 +189,7 @@ async def on_data_update(timeframe):
189189
return
190190

191191
# Calculate key indicators
192-
data = data.pipe(RSI, period=14)
193-
data = data.pipe(SMA, period=20)
192+
data = data.pipe(RSI, period=14).pipe(SMA, period=20)
194193

195194
last_row = data.tail(1)
196195
timestamp = datetime.now().strftime("%H:%M:%S")

0 commit comments

Comments
 (0)