3535
3636import logging
3737from abc import ABC , abstractmethod
38- from typing import TYPE_CHECKING , Optional
38+ from typing import TYPE_CHECKING , Any , Optional
3939
4040from project_x_py .indicators import ATR
4141from project_x_py .models import BracketOrderResponse
@@ -52,7 +52,11 @@ class OrderTemplate(ABC):
5252
5353 @abstractmethod
5454 async def create_order (
55- self , suite : "TradingSuite" , side : int , size : Optional [int ] = None , ** kwargs
55+ self ,
56+ suite : "TradingSuite" ,
57+ side : int ,
58+ size : Optional [int ] = None ,
59+ ** kwargs : Any ,
5660 ) -> BracketOrderResponse :
5761 """Create an order using this template."""
5862 pass
@@ -92,7 +96,7 @@ async def create_order(
9296 risk_amount : Optional [float ] = None ,
9397 risk_percent : Optional [float ] = None ,
9498 entry_offset : float = 0 ,
95- ** kwargs ,
99+ ** kwargs : Any ,
96100 ) -> BracketOrderResponse :
97101 """
98102 Create an order with fixed risk/reward ratio.
@@ -109,7 +113,7 @@ async def create_order(
109113 BracketOrderResponse with order details
110114 """
111115 # Get current price
112- current_price = await suite .data .get_latest_price ()
116+ current_price = await suite .data .get_current_price ()
113117 if not current_price :
114118 raise ValueError ("Cannot get current price" )
115119
@@ -138,8 +142,10 @@ async def create_order(
138142 size = int (risk_amount / (stop_dist * tick_value ))
139143 elif risk_percent :
140144 # Get account balance
141- account = await suite .client .get_account_info ()
142- risk_amount = account .balance * risk_percent
145+ account = suite .client .account_info
146+ if not account :
147+ raise ValueError ("No account information available" )
148+ risk_amount = float (account .balance ) * risk_percent
143149 instrument = await suite .client .get_instrument (suite .instrument )
144150 tick_value = instrument .tickValue if instrument else 1.0
145151 size = int (risk_amount / (stop_dist * tick_value ))
@@ -149,6 +155,9 @@ async def create_order(
149155 # Build order chain
150156 builder = OrderChainBuilder (suite )
151157
158+ if size is None :
159+ raise ValueError ("Size is required" )
160+
152161 if self .use_limit_entry :
153162 builder .limit_order (size = size , price = entry_price , side = side )
154163 else :
@@ -206,10 +215,10 @@ async def create_order(
206215 self ,
207216 suite : "TradingSuite" ,
208217 side : int ,
209- size : int ,
218+ size : Optional [ int ] = None ,
210219 use_limit_entry : bool = False ,
211220 entry_offset : float = 0 ,
212- ** kwargs ,
221+ ** kwargs : Any ,
213222 ) -> BracketOrderResponse :
214223 """
215224 Create an order with ATR-based stops.
@@ -234,7 +243,7 @@ async def create_order(
234243 current_atr = float (data_with_atr [f"atr_{ self .atr_period } " ][- 1 ])
235244
236245 # Get current price
237- current_price = await suite .data .get_latest_price ()
246+ current_price = await suite .data .get_current_price ()
238247 if not current_price :
239248 raise ValueError ("Cannot get current price" )
240249
@@ -251,6 +260,9 @@ async def create_order(
251260 # Build order
252261 builder = OrderChainBuilder (suite )
253262
263+ if size is None :
264+ raise ValueError ("Size is required" )
265+
254266 if use_limit_entry :
255267 if side == 0 : # BUY
256268 entry_price = current_price - entry_offset
@@ -296,11 +308,11 @@ async def create_order(
296308 self ,
297309 suite : "TradingSuite" ,
298310 side : int ,
299- size : int ,
311+ size : Optional [ int ] = None ,
300312 breakout_level : Optional [float ] = None ,
301313 range_size : Optional [float ] = None ,
302314 lookback_bars : int = 20 ,
303- ** kwargs ,
315+ ** kwargs : Any ,
304316 ) -> BracketOrderResponse :
305317 """
306318 Create a breakout order.
@@ -335,12 +347,16 @@ async def create_order(
335347 # Calculate entry price
336348 if side == 0 : # BUY
337349 entry_price = breakout_level + self .breakout_offset
350+ if range_size is None :
351+ raise ValueError ("Range size is required" )
338352 stop_price = (
339353 breakout_level if self .stop_at_level else breakout_level - range_size
340354 )
341355 target_price = entry_price + (range_size * self .target_range_multiplier )
342356 else : # SELL
343357 entry_price = breakout_level - self .breakout_offset
358+ if range_size is None :
359+ raise ValueError ("Range size is required" )
344360 stop_price = (
345361 breakout_level if self .stop_at_level else breakout_level + range_size
346362 )
@@ -353,6 +369,9 @@ async def create_order(
353369 )
354370
355371 # Build order
372+ if size is None :
373+ raise ValueError ("Size is required" )
374+
356375 builder = (
357376 OrderChainBuilder (suite )
358377 .stop_order (size = size , price = entry_price , side = side )
@@ -396,9 +415,9 @@ async def create_order(
396415 self ,
397416 suite : "TradingSuite" ,
398417 side : int ,
399- size : int ,
418+ size : Optional [ int ] = None ,
400419 check_spread : bool = True ,
401- ** kwargs ,
420+ ** kwargs : Any ,
402421 ) -> BracketOrderResponse :
403422 """
404423 Create a scalping order.
@@ -422,10 +441,10 @@ async def create_order(
422441 # Check spread if requested
423442 if check_spread and hasattr (suite , "orderbook" ) and suite .orderbook :
424443 orderbook = suite .orderbook
425- spread_info = await orderbook .get_spread ()
444+ spread = await orderbook .get_bid_ask_spread ()
426445
427- if spread_info :
428- spread_ticks = spread_info [ " spread" ] / tick_size
446+ if spread is not None :
447+ spread_ticks = spread / tick_size
429448 if spread_ticks > self .max_spread_ticks :
430449 raise ValueError (
431450 f"Spread too wide: { spread_ticks :.1f} ticks "
@@ -439,11 +458,14 @@ async def create_order(
439458 # Build order
440459 builder = OrderChainBuilder (suite )
441460
461+ if size is None :
462+ raise ValueError ("Size is required" )
463+
442464 if self .use_market_entry :
443465 builder .market_order (size = size , side = side )
444466 else :
445467 # Use limit at best bid/ask
446- current_price = await suite .data .get_latest_price ()
468+ current_price = await suite .data .get_current_price ()
447469 if not current_price :
448470 raise ValueError ("Cannot get current price" )
449471 builder .limit_order (size = size , price = current_price , side = side )
0 commit comments