Skip to content

Commit 60b0dee

Browse files
committed
update documentation
1 parent b35c278 commit 60b0dee

6 files changed

Lines changed: 332 additions & 89 deletions

File tree

docs/guide/orders.md

Lines changed: 110 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,24 @@ The OrderManager provides complete lifecycle management for all order types incl
2222
```python
2323
import asyncio
2424
from decimal import Decimal
25+
2526
from project_x_py import TradingSuite
2627

28+
2729
async def main():
2830
# Initialize with order management capabilities
2931
suite = await TradingSuite.create("MNQ")
3032

33+
mnq_context = suite["MNQ"]
3134
# Order manager is automatically available
32-
order_manager = suite.orders
35+
order_manager = mnq_context.orders
3336

3437
# Get instrument information for proper pricing
35-
instrument = await suite.client.get_instrument("MNQ")
38+
instrument = mnq_context.instrument_info
3639
print(f"Tick size: ${instrument.tickSize}")
40+
41+
42+
asyncio.run(main())
3743
```
3844

3945
### Safety First
@@ -52,183 +58,187 @@ async def main():
5258
Market orders execute immediately at the current market price with guaranteed fills but no price control.
5359

5460
```python
61+
import asyncio
62+
63+
from project_x_py import TradingSuite
64+
65+
5566
async def place_market_order():
5667
suite = await TradingSuite.create("MNQ")
5768

5869
try:
5970
# Place buy market order
60-
response = await suite.orders.place_market_order(
61-
contract_id="MNQ", # Or use suite.instrument_info.id
62-
side=0, # 0 = Buy, 1 = Sell
63-
size=1 # Number of contracts
71+
response = await suite["MNQ"].orders.place_market_order(
72+
contract_id=suite["MNQ"].instrument_info.id, # Or use suite.instrument_info.id
73+
side=0, # 0 = Buy, 1 = Sell
74+
size=1, # Number of contracts
6475
)
6576

66-
print(f"Market order placed: {response.order_id}")
67-
print(f"Status: {response.status}")
77+
print(f"Market order placed: {response.orderId}")
78+
print(f"Status: {response.success}")
6879

6980
# Wait for fill confirmation
7081
await asyncio.sleep(2)
71-
order_status = await suite.orders.get_order_status(response.order_id)
82+
order_status = await suite["MNQ"].orders.get_order_statistics_async()
7283
print(f"Final status: {order_status}")
7384

7485
except Exception as e:
7586
print(f"Order failed: {e}")
7687
finally:
7788
await suite.disconnect()
89+
90+
91+
asyncio.run(place_market_order())
7892
```
7993

8094
### Limit Orders
8195

8296
Limit orders execute only at specified price or better, providing price control but no fill guarantee.
8397

8498
```python
99+
import asyncio
100+
from decimal import Decimal
101+
102+
from project_x_py import TradingSuite
103+
104+
85105
async def place_limit_order():
86106
suite = await TradingSuite.create("MNQ")
87107

88108
# Get current market price for context
89-
current_price = await suite.data.get_current_price()
109+
current_price = await suite["MNQ"].data.get_current_price()
90110

91111
# Place buy limit order below market
92-
limit_price = Decimal(str(current_price)) - Decimal("25") # $25 below market
112+
limit_price = Decimal(str(current_price)) - Decimal("2.00") # $2.00 below market
93113

94-
response = await suite.orders.place_limit_order(
95-
contract_id="MNQ",
96-
side=0, # Buy
114+
response = await suite["MNQ"].orders.place_limit_order(
115+
contract_id=suite["MNQ"].instrument_info.id,
116+
side=0, # Buy
97117
size=1,
98-
limit_price=limit_price,
99-
time_in_force="DAY" # DAY, GTC, IOC, FOK
118+
limit_price=float(limit_price),
100119
)
101120

102121
print(f"Limit order placed at ${limit_price}")
103-
print(f"Order ID: {response.order_id}")
122+
print(f"Order ID: {response.orderId}")
104123

105124
# Monitor order status
106125
while True:
107-
status = await suite.orders.get_order_status(response.order_id)
108-
print(f"Status: {status}")
109-
110-
if status in ["FILLED", "CANCELLED", "REJECTED"]:
126+
status = await suite["MNQ"].orders.get_order_by_id(response.orderId)
127+
if status is None:
128+
continue
129+
130+
if status.status in [2, 3, 4]:
131+
print(
132+
f"Status: {'FILLED' if status.status == 2 else 'CANCELLED' if status.status == 3 else 'EXPIRED' if status.status == 4 else 'PENDING'}"
133+
)
111134
break
112135

113136
await asyncio.sleep(5) # Check every 5 seconds
137+
138+
139+
asyncio.run(place_limit_order())
114140
```
115141

116142
### Stop Orders
117143

118144
Stop orders become market orders when the stop price is reached, useful for exits and breakout entries.
119145

120146
```python
147+
import asyncio
148+
from decimal import Decimal
149+
150+
from project_x_py import TradingSuite
151+
152+
121153
async def place_stop_order():
122154
suite = await TradingSuite.create("MNQ")
123155

124-
current_price = await suite.data.get_current_price()
156+
current_price = await suite["MNQ"].data.get_current_price()
125157

126158
# Stop loss order (sell stop below current price)
127-
stop_price = Decimal(str(current_price)) - Decimal("50") # $50 below market
159+
stop_price = Decimal(str(current_price)) - Decimal("2.00") # $2.00 below market
128160

129-
response = await suite.orders.place_stop_order(
130-
contract_id="MNQ",
131-
side=1, # Sell (for stop loss)
161+
response = await suite["MNQ"].orders.place_stop_order(
162+
contract_id=suite["MNQ"].instrument_info.id,
163+
side=1, # Sell (for stop loss)
132164
size=1,
133-
stop_price=stop_price,
134-
time_in_force="GTC" # Good Till Cancelled
165+
stop_price=float(stop_price),
135166
)
136167

137168
print(f"Stop order placed at ${stop_price}")
138169

139170
# Or stop entry order (buy stop above current price for breakouts)
140-
breakout_price = Decimal(str(current_price)) + Decimal("30")
171+
breakout_price = Decimal(str(current_price)) + Decimal("2.00")
141172

142-
breakout_response = await suite.orders.place_stop_order(
143-
contract_id="MNQ",
144-
side=0, # Buy
173+
breakout_response = await suite["MNQ"].orders.place_stop_order(
174+
contract_id=suite["MNQ"].instrument_info.id,
175+
side=0, # Buy
145176
size=1,
146-
stop_price=breakout_price
177+
stop_price=float(breakout_price),
147178
)
148179

149180
print(f"Breakout order placed at ${breakout_price}")
150-
```
151-
152-
### OCO Orders (One Cancels Other)
153-
154-
OCO orders link two orders where filling one automatically cancels the other.
155-
156-
```python
157-
async def place_oco_order():
158-
suite = await TradingSuite.create("MNQ")
159181

160-
current_price = await suite.data.get_current_price()
161-
162-
# OCO for profit target and stop loss
163-
profit_target = Decimal(str(current_price)) + Decimal("75") # $75 above
164-
stop_loss = Decimal(str(current_price)) - Decimal("50") # $50 below
165-
166-
response = await suite.orders.place_oco_order(
167-
contract_id="MNQ",
168182

169-
# First leg: Profit target (sell limit)
170-
first_side=1, # Sell
171-
first_size=1,
172-
first_order_type="LIMIT",
173-
first_price=profit_target,
174-
175-
# Second leg: Stop loss (sell stop)
176-
second_side=1, # Sell
177-
second_size=1,
178-
second_order_type="STOP",
179-
second_price=stop_loss
180-
)
181-
182-
print(f"OCO placed: Target ${profit_target}, Stop ${stop_loss}")
183-
print(f"OCO Group ID: {response.oco_group_id}")
184-
185-
# Both order IDs are available
186-
print(f"Target Order: {response.first_order_id}")
187-
print(f"Stop Order: {response.second_order_id}")
183+
asyncio.run(place_stop_order())
188184
```
189185

190186
### Bracket Orders
191187

192188
Bracket orders are the most sophisticated order type, combining entry, stop loss, and take profit in one operation.
193189

194190
```python
191+
import asyncio
192+
from decimal import Decimal
193+
194+
from project_x_py import TradingSuite
195+
from project_x_py.models import BracketOrderResponse
196+
197+
195198
async def place_bracket_order():
196199
suite = await TradingSuite.create("MNQ")
197200

198-
current_price = await suite.data.get_current_price()
201+
current_price = await suite["MNQ"].data.get_current_price()
199202

200203
# Complete bracket order setup
201-
response = await suite.orders.place_bracket_order(
202-
contract_id="MNQ",
203-
side=0, # Buy entry
204+
response = await suite["MNQ"].orders.place_bracket_order(
205+
contract_id=suite["MNQ"].instrument_info.id,
206+
side=0, # Buy entry
204207
size=1,
205-
206208
# Entry order (optional - if None, uses market order)
207-
entry_price=Decimal(str(current_price)) - Decimal("10"), # Buy limit
208-
209+
entry_type="market",
210+
entry_price=None,
209211
# Risk management
210-
stop_offset=Decimal("40"), # Stop loss $40 from entry
211-
target_offset=Decimal("80"), # Take profit $80 from entry
212-
212+
stop_loss_price=float(
213+
Decimal(str(current_price)) - Decimal("4")
214+
), # Stop loss $4 from entry
215+
take_profit_price=float(
216+
Decimal(str(current_price)) + Decimal("8")
217+
), # Take profit $8 from entry
213218
# Order timing
214-
time_in_force="DAY"
215219
)
216220

217-
print(f"Bracket order placed:")
218-
print(f" Entry: {response.main_order_id}")
221+
222+
print("Bracket order placed:")
223+
print(f" Entry: {response.entry_order_id}")
219224
print(f" Stop Loss: {response.stop_order_id}")
220225
print(f" Take Profit: {response.target_order_id}")
221226

222227
# Monitor bracket order progress
223228
await monitor_bracket_order(suite, response)
224229

225-
async def monitor_bracket_order(suite, bracket_response):
230+
231+
async def monitor_bracket_order(
232+
suite: TradingSuite, bracket_response: BracketOrderResponse
233+
):
226234
"""Monitor all three orders in a bracket."""
227235

228236
while True:
237+
if bracket_response.entry_order_id is None:
238+
continue
229239
# Check main order status
230-
main_status = await suite.orders.get_order_status(
231-
bracket_response.main_order_id
240+
main_status = await suite["MNQ"].orders.get_order_by_id(
241+
bracket_response.entry_order_id
232242
)
233243

234244
print(f"Entry order: {main_status}")
@@ -238,17 +248,25 @@ async def monitor_bracket_order(suite, bracket_response):
238248

239249
# Now monitor the exit orders
240250
while True:
241-
stop_status = await suite.orders.get_order_status(
251+
if bracket_response.stop_order_id is None:
252+
continue
253+
stop_status = await suite["MNQ"].orders.get_order_by_id(
242254
bracket_response.stop_order_id
243255
)
244-
target_status = await suite.orders.get_order_status(
256+
if bracket_response.target_order_id is None:
257+
continue
258+
target_status = await suite["MNQ"].orders.get_order_by_id(
245259
bracket_response.target_order_id
246260
)
247261

248-
if stop_status == "FILLED":
262+
if stop_status is None:
263+
continue
264+
if target_status is None:
265+
continue
266+
if stop_status.status == 2:
249267
print("Stop loss triggered!")
250268
break
251-
elif target_status == "FILLED":
269+
elif target_status.status == 2:
252270
print("Take profit hit!")
253271
break
254272

@@ -260,6 +278,9 @@ async def monitor_bracket_order(suite, bracket_response):
260278
break
261279

262280
await asyncio.sleep(5)
281+
282+
283+
asyncio.run(place_bracket_order())
263284
```
264285

265286
## Order Lifecycle and Tracking
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import asyncio
2+
from decimal import Decimal
3+
4+
from project_x_py import TradingSuite
5+
6+
7+
async def main():
8+
# Initialize with order management capabilities
9+
suite = await TradingSuite.create("MNQ")
10+
11+
mnq_context = suite["MNQ"]
12+
# Order manager is automatically available
13+
order_manager = mnq_context.orders
14+
15+
# Get instrument information for proper pricing
16+
instrument = mnq_context.instrument_info
17+
print(f"Tick size: ${instrument.tickSize}")
18+
19+
20+
asyncio.run(main())

0 commit comments

Comments
 (0)