Skip to content

Commit a55c983

Browse files
authored
Merge pull request #28 from TexasCoding/work_on_factory_functions
feat: enhance factory functions with auto-initialization (v2.0.8)
2 parents 5cc8e92 + 9c3e5ba commit a55c983

File tree

11 files changed

+710
-24
lines changed

11 files changed

+710
-24
lines changed

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Old implementations are removed when improved
1414
- Clean, modern code architecture is prioritized
1515

16+
## [2.0.8] - 2025-08-03
17+
18+
### Added
19+
- **🚀 Enhanced Factory Functions**: Dramatically simplified trading suite setup
20+
- `create_initialized_trading_suite()`: One-line setup with everything connected and ready
21+
- Enhanced `create_trading_suite()` with auto-initialization options:
22+
- `auto_connect`: Automatically connect realtime client and subscribe to user updates
23+
- `auto_subscribe`: Automatically subscribe to market data and start feeds
24+
- `initial_days`: Configurable historical data loading (default: 5)
25+
- Reduces boilerplate code by ~95% for most use cases
26+
- Still allows full manual control when needed
27+
28+
### Examples
29+
- **12_simplified_strategy.py**: Demonstrates the new simplified setup approach
30+
- **13_factory_comparison.py**: Shows the difference between old manual setup and new auto-initialization
31+
32+
### Improved
33+
- **📖 Documentation**: Updated README with comprehensive factory function documentation
34+
- **🎯 Developer Experience**: Trading strategies can now focus on logic instead of setup boilerplate
35+
- **🔄 Flexibility**: Three levels of initialization control:
36+
1. `create_initialized_trading_suite()` - Everything automatic
37+
2. `create_trading_suite(..., auto_connect=True, auto_subscribe=True)` - Configurable automation
38+
3. `create_trading_suite(..., auto_connect=False, auto_subscribe=False)` - Full manual control
39+
40+
### Technical Details
41+
- Factory functions now handle all initialization steps:
42+
- WebSocket connection and user update subscription
43+
- Historical data loading
44+
- Instrument search and contract resolution
45+
- Market data subscription
46+
- Real-time feed initialization
47+
- OrderBook initialization (if enabled)
48+
- All initialization is properly sequenced to avoid race conditions
49+
- Error handling ensures clear feedback if initialization fails
50+
1651
## [2.0.7] - 2025-08-03
1752

1853
### Added

README.md

Lines changed: 146 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,37 +128,117 @@ if __name__ == "__main__":
128128
asyncio.run(main())
129129
```
130130

131-
### Real-time Trading Suite
131+
### Trading Suite (NEW in v2.0.8)
132+
133+
The easiest way to get started with a complete trading setup:
132134

133135
```python
134136
import asyncio
135-
from project_x_py import ProjectX, create_trading_suite
136-
137-
async def on_tick(tick_data):
138-
print(f"Price: ${tick_data['price']}")
137+
from project_x_py import ProjectX, create_initialized_trading_suite
139138

140139
async def main():
141140
async with ProjectX.from_env() as client:
142141
await client.authenticate()
143142

144-
# Create complete trading suite
145-
suite = await create_trading_suite(
143+
# One line creates and initializes everything!
144+
suite = await create_initialized_trading_suite(
146145
instrument="MNQ",
147146
project_x=client,
148-
timeframes=["1min", "5min", "15min"]
147+
timeframes=["5min", "15min", "1hr"],
148+
initial_days=5
149149
)
150150

151-
# Connect real-time services
152-
await suite["realtime_client"].connect()
153-
await suite["data_manager"].initialize(initial_days=5)
151+
# Everything is ready to use:
152+
# ✅ Realtime client connected
153+
# ✅ Historical data loaded
154+
# ✅ Market data streaming
155+
# ✅ All components initialized
154156

155-
# Subscribe to real-time data
157+
# Access components
158+
data = await suite["data_manager"].get_data("5min")
159+
orderbook = suite["orderbook"]
160+
order_manager = suite["order_manager"]
161+
position_manager = suite["position_manager"]
162+
163+
# Your trading logic here...
164+
165+
if __name__ == "__main__":
166+
asyncio.run(main())
167+
```
168+
169+
### Factory Functions (v2.0.8+)
170+
171+
The SDK provides powerful factory functions to simplify setup:
172+
173+
#### create_initialized_trading_suite
174+
The simplest way to get a fully initialized trading environment:
175+
176+
```python
177+
suite = await create_initialized_trading_suite(
178+
instrument="MNQ",
179+
project_x=client,
180+
timeframes=["5min", "15min", "1hr"], # Optional, defaults to ["5min"]
181+
enable_orderbook=True, # Optional, defaults to True
182+
initial_days=5 # Optional, defaults to 5
183+
)
184+
# Everything is connected and ready!
185+
```
186+
187+
#### create_trading_suite
188+
For more control over initialization:
189+
190+
```python
191+
suite = await create_trading_suite(
192+
instrument="MNQ",
193+
project_x=client,
194+
timeframes=["5min", "15min"],
195+
auto_connect=True, # Auto-connect realtime client (default: True)
196+
auto_subscribe=True, # Auto-subscribe to market data (default: True)
197+
initial_days=5 # Historical data to load
198+
)
199+
```
200+
201+
#### Manual Setup (Full Control)
202+
If you need complete control:
203+
204+
```python
205+
suite = await create_trading_suite(
206+
instrument="MNQ",
207+
project_x=client,
208+
auto_connect=False,
209+
auto_subscribe=False
210+
)
211+
# Now manually connect and subscribe as needed
212+
await suite["realtime_client"].connect()
213+
await suite["data_manager"].initialize()
214+
# ... etc
215+
```
216+
217+
### Real-time Trading Example
218+
219+
```python
220+
import asyncio
221+
from project_x_py import ProjectX, create_initialized_trading_suite
222+
223+
async def on_tick(tick_data):
224+
print(f"Price: ${tick_data['price']}")
225+
226+
async def main():
227+
async with ProjectX.from_env() as client:
228+
await client.authenticate()
229+
230+
# Create fully initialized trading suite
231+
suite = await create_initialized_trading_suite("MNQ", client)
232+
233+
# Add callbacks
156234
suite["data_manager"].add_tick_callback(on_tick)
157-
await suite["data_manager"].start_realtime_feed()
235+
236+
# Get current price
237+
current_price = await suite["data_manager"].get_current_price()
158238

159239
# Place a bracket order
160240
response = await suite["order_manager"].place_bracket_order(
161-
contract_id=instrument.id,
241+
contract_id=suite["instrument_info"].id,
162242
side=0, # Buy
163243
size=1,
164244
entry_price=current_price,
@@ -284,6 +364,8 @@ The `examples/` directory contains comprehensive async examples:
284364
7. **07_technical_indicators.py** - Using indicators with async data
285365
8. **08_order_and_position_tracking.py** - Integrated async monitoring
286366
9. **09_get_check_available_instruments.py** - Interactive async instrument search
367+
10. **12_simplified_strategy.py** - NEW: Simplified strategy using auto-initialization
368+
11. **13_factory_comparison.py** - NEW: Comparison of factory function approaches
287369

288370
## 🔧 Configuration
289371

@@ -366,6 +448,56 @@ async def place_order(self, ...):
366448
# Method implementation
367449
```
368450

451+
## 🔧 Troubleshooting
452+
453+
### Common Issues with Factory Functions
454+
455+
#### JWT Token Not Available
456+
```python
457+
# Error: "JWT token is required but not available from client"
458+
# Solution: Ensure client is authenticated before creating suite
459+
async with ProjectX.from_env() as client:
460+
await client.authenticate() # Don't forget this!
461+
suite = await create_initialized_trading_suite("MNQ", client)
462+
```
463+
464+
#### Instrument Not Found
465+
```python
466+
# Error: "Instrument MNQ not found"
467+
# Solution: Verify instrument symbol is correct
468+
# Common symbols: "MNQ", "MES", "MGC", "ES", "NQ"
469+
```
470+
471+
#### Connection Timeouts
472+
```python
473+
# If initialization times out, try manual setup with error handling:
474+
try:
475+
suite = await create_trading_suite(
476+
instrument="MNQ",
477+
project_x=client,
478+
auto_connect=False
479+
)
480+
await suite["realtime_client"].connect()
481+
except Exception as e:
482+
print(f"Connection failed: {e}")
483+
```
484+
485+
#### Memory Issues with Long-Running Strategies
486+
```python
487+
# The suite automatically manages memory, but for long-running strategies:
488+
# 1. Use reasonable initial_days (3-7 is usually sufficient)
489+
# 2. The data manager automatically maintains sliding windows
490+
# 3. OrderBook has built-in memory limits
491+
```
492+
493+
#### Rate Limiting
494+
```python
495+
# The SDK handles rate limiting automatically, but if you encounter issues:
496+
# 1. Reduce concurrent API calls
497+
# 2. Add delays between operations
498+
# 3. Use batch operations where available
499+
```
500+
369501
## 🤝 Contributing
370502

371503
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
project = "project-x-py"
2424
copyright = "2025, Jeff West"
2525
author = "Jeff West"
26-
release = "2.0.7"
27-
version = "2.0.7"
26+
release = "2.0.8"
27+
version = "2.0.8"
2828

2929
# -- General configuration ---------------------------------------------------
3030

examples/06_multi_timeframe_strategy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ def signal_handler(signum, frame):
440440
instruments = await client.search_instruments("MNQ")
441441
if instruments:
442442
await suite["realtime_client"].subscribe_market_data(
443-
[instruments[0].activeContract]
443+
[instruments[0].id]
444444
)
445445
await suite["data_manager"].start_realtime_feed()
446446

0 commit comments

Comments
 (0)