Skip to content

Commit 9f0af7d

Browse files
committed
fix mypy issues
1 parent ea2a133 commit 9f0af7d

File tree

3 files changed

+51
-54
lines changed

3 files changed

+51
-54
lines changed

src/project_x_py/order_templates.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
import logging
3737
from abc import ABC, abstractmethod
38-
from typing import TYPE_CHECKING, Any, Optional
38+
from typing import TYPE_CHECKING, Any
3939

4040
from project_x_py.indicators import ATR
4141
from project_x_py.models import BracketOrderResponse
@@ -55,11 +55,10 @@ async def create_order(
5555
self,
5656
suite: "TradingSuite",
5757
side: int,
58-
size: Optional[int] = None,
58+
size: int | None = None,
5959
**kwargs: Any,
6060
) -> BracketOrderResponse:
6161
"""Create an order using this template."""
62-
pass
6362

6463

6564
class RiskRewardTemplate(OrderTemplate):
@@ -73,7 +72,7 @@ class RiskRewardTemplate(OrderTemplate):
7372
def __init__(
7473
self,
7574
risk_reward_ratio: float = 2.0,
76-
stop_distance: Optional[float] = None,
75+
stop_distance: float | None = None,
7776
use_limit_entry: bool = True,
7877
):
7978
"""
@@ -92,9 +91,9 @@ async def create_order(
9291
self,
9392
suite: "TradingSuite",
9493
side: int,
95-
size: Optional[int] = None,
96-
risk_amount: Optional[float] = None,
97-
risk_percent: Optional[float] = None,
94+
size: int | None = None,
95+
risk_amount: float | None = None,
96+
risk_percent: float | None = None,
9897
entry_offset: float = 0,
9998
**kwargs: Any,
10099
) -> BracketOrderResponse:
@@ -131,7 +130,7 @@ async def create_order(
131130
stop_dist = self.stop_distance
132131
else:
133132
# Use 1% of price as default
134-
stop_dist = current_price * 0.01
133+
stop_dist = current_price * 0.01 if current_price else 0.0
135134

136135
# Calculate position size if needed
137136
if size is None:
@@ -215,7 +214,7 @@ async def create_order(
215214
self,
216215
suite: "TradingSuite",
217216
side: int,
218-
size: Optional[int] = None,
217+
size: int | None = None,
219218
use_limit_entry: bool = False,
220219
entry_offset: float = 0,
221220
**kwargs: Any,
@@ -236,7 +235,7 @@ async def create_order(
236235
# Get data for ATR calculation
237236
data = await suite.data.get_data(self.timeframe, bars=self.atr_period + 1)
238237
if data is None or len(data) < self.atr_period:
239-
raise ValueError(f"Insufficient data for ATR calculation")
238+
raise ValueError("Insufficient data for ATR calculation")
240239

241240
# Calculate ATR
242241
data_with_atr = data.pipe(ATR, period=self.atr_period)
@@ -308,9 +307,9 @@ async def create_order(
308307
self,
309308
suite: "TradingSuite",
310309
side: int,
311-
size: Optional[int] = None,
312-
breakout_level: Optional[float] = None,
313-
range_size: Optional[float] = None,
310+
size: int | None = None,
311+
breakout_level: float | None = None,
312+
range_size: float | None = None,
314313
lookback_bars: int = 20,
315314
**kwargs: Any,
316315
) -> BracketOrderResponse:
@@ -336,10 +335,9 @@ async def create_order(
336335
if not range_stats:
337336
raise ValueError("Cannot calculate price range")
338337

339-
if side == 0: # BUY - breakout above high
340-
breakout_level = range_stats["high"]
341-
else: # SELL - breakout below low
342-
breakout_level = range_stats["low"]
338+
breakout_level = (
339+
range_stats["high"] if side == 0 else range_stats["low"]
340+
) # BUY=high, SELL=low
343341

344342
if range_size is None:
345343
range_size = range_stats["range"]
@@ -415,7 +413,7 @@ async def create_order(
415413
self,
416414
suite: "TradingSuite",
417415
side: int,
418-
size: Optional[int] = None,
416+
size: int | None = None,
419417
check_spread: bool = True,
420418
**kwargs: Any,
421419
) -> BracketOrderResponse:

src/project_x_py/order_tracker.py

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,12 @@
5555
import asyncio
5656
import logging
5757
from types import TracebackType
58-
from typing import TYPE_CHECKING, Any, Optional, Type, Union
58+
from typing import TYPE_CHECKING, Any, Union
5959

6060
from project_x_py.event_bus import EventType
6161
from project_x_py.models import BracketOrderResponse, Order, OrderPlaceResponse
6262

6363
if TYPE_CHECKING:
64-
from project_x_py.order_manager import OrderManager
6564
from project_x_py.trading_suite import TradingSuite
6665

6766
logger = logging.getLogger(__name__)
@@ -84,7 +83,7 @@ class OrderTracker:
8483
- Thread-safe operation
8584
"""
8685

87-
def __init__(self, trading_suite: "TradingSuite", order: Optional[Order] = None):
86+
def __init__(self, trading_suite: "TradingSuite", order: Order | None = None):
8887
"""
8988
Initialize OrderTracker.
9089
@@ -96,14 +95,14 @@ def __init__(self, trading_suite: "TradingSuite", order: Optional[Order] = None)
9695
self.order_manager = trading_suite.orders
9796
self.event_bus = trading_suite.events
9897
self.order = order
99-
self.order_id: Optional[int] = order.id if order else None
98+
self.order_id: int | None = order.id if order else None
10099

101100
# State tracking
102101
self._fill_event = asyncio.Event()
103102
self._status_events: dict[int, asyncio.Event] = {}
104-
self._current_status: Optional[int] = order.status if order else None
105-
self._filled_order: Optional[Order] = None
106-
self._error: Optional[Exception] = None
103+
self._current_status: int | None = order.status if order else None
104+
self._filled_order: Order | None = None
105+
self._error: Exception | None = None
107106

108107
# Event handlers
109108
self._event_handlers: list[tuple[EventType, Any]] = []
@@ -116,9 +115,9 @@ async def __aenter__(self) -> "OrderTracker":
116115

117116
async def __aexit__(
118117
self,
119-
exc_type: Optional[Type[BaseException]],
120-
exc_val: Optional[BaseException],
121-
exc_tb: Optional[TracebackType],
118+
exc_type: type[BaseException] | None,
119+
exc_val: BaseException | None,
120+
exc_tb: TracebackType | None,
122121
) -> None:
123122
"""Exit the context manager and clean up."""
124123
await self.cleanup()
@@ -226,10 +225,10 @@ async def wait_for_fill(self, timeout: float = 30.0) -> Order:
226225
"Order fill event received but order not filled"
227226
)
228227

229-
except asyncio.TimeoutError:
228+
except TimeoutError:
230229
raise TimeoutError(
231230
f"Order {self.order_id} not filled within {timeout} seconds"
232-
)
231+
) from None
233232

234233
async def wait_for_status(self, status: int, timeout: float = 30.0) -> Order:
235234
"""
@@ -274,13 +273,13 @@ async def wait_for_status(self, status: int, timeout: float = 30.0) -> Order:
274273
f"Status event received but order not in expected state {status}"
275274
)
276275

277-
except asyncio.TimeoutError:
276+
except TimeoutError:
278277
raise TimeoutError(
279278
f"Order {self.order_id} did not reach status {status} within {timeout} seconds"
280-
)
279+
) from None
281280

282281
async def modify_or_cancel(
283-
self, new_price: Optional[float] = None, new_size: Optional[int] = None
282+
self, new_price: float | None = None, new_size: int | None = None
284283
) -> bool:
285284
"""
286285
Attempt to modify the order, or cancel if modification fails.
@@ -318,7 +317,7 @@ async def modify_or_cancel(
318317
logger.error(f"Failed to cancel order {self.order_id}: {e}")
319318
raise
320319

321-
async def get_current_status(self) -> Optional[Order]:
320+
async def get_current_status(self) -> Order | None:
322321
"""
323322
Get the current order status.
324323
@@ -379,15 +378,15 @@ def __init__(self, trading_suite: "TradingSuite"):
379378

380379
# Order configuration
381380
self.entry_type = "market"
382-
self.side: Optional[int] = None
383-
self.size: Optional[int] = None
384-
self.entry_price: Optional[float] = None
385-
self.contract_id: Optional[str] = None
381+
self.side: int | None = None
382+
self.size: int | None = None
383+
self.entry_price: float | None = None
384+
self.contract_id: str | None = None
386385

387386
# Risk orders
388-
self.stop_loss: Optional[dict[str, Any]] = None
389-
self.take_profit: Optional[dict[str, Any]] = None
390-
self.trail_stop: Optional[dict[str, Any]] = None
387+
self.stop_loss: dict[str, Any] | None = None
388+
self.take_profit: dict[str, Any] | None = None
389+
self.trail_stop: dict[str, Any] | None = None
391390

392391
def market_order(self, size: int, side: int = 0) -> "OrderChainBuilder":
393392
"""Configure a market order as entry."""
@@ -420,24 +419,24 @@ def for_instrument(self, contract_id: str) -> "OrderChainBuilder":
420419
return self
421420

422421
def with_stop_loss(
423-
self, offset: Optional[float] = None, price: Optional[float] = None
422+
self, offset: float | None = None, price: float | None = None
424423
) -> "OrderChainBuilder":
425424
"""Add a stop loss to the order chain."""
426425
self.stop_loss = {"offset": offset, "price": price}
427426
return self
428427

429428
def with_take_profit(
430429
self,
431-
offset: Optional[float] = None,
432-
price: Optional[float] = None,
430+
offset: float | None = None,
431+
price: float | None = None,
433432
limit: bool = True,
434433
) -> "OrderChainBuilder":
435434
"""Add a take profit to the order chain."""
436435
self.take_profit = {"offset": offset, "price": price, "limit": limit}
437436
return self
438437

439438
def with_trail_stop(
440-
self, offset: float, trigger_offset: Optional[float] = None
439+
self, offset: float, trigger_offset: float | None = None
441440
) -> "OrderChainBuilder":
442441
"""Add a trailing stop to the order chain."""
443442
self.trail_stop = {"offset": offset, "trigger_offset": trigger_offset}
@@ -570,13 +569,11 @@ async def execute(self) -> BracketOrderResponse:
570569
class OrderLifecycleError(Exception):
571570
"""Exception raised when order lifecycle encounters an error."""
572571

573-
pass
574-
575572

576573
# Convenience function for creating order trackers
577574
def track_order(
578575
trading_suite: "TradingSuite",
579-
order: Optional[Union[Order, OrderPlaceResponse, int]] = None,
576+
order: Union[Order, OrderPlaceResponse, int] | None = None,
580577
) -> OrderTracker:
581578
"""
582579
Create an OrderTracker instance.
@@ -598,7 +595,7 @@ def track_order(
598595
"""
599596
tracker = OrderTracker(trading_suite)
600597
if order:
601-
if isinstance(order, (Order, OrderPlaceResponse)):
598+
if isinstance(order, Order | OrderPlaceResponse):
602599
tracker.track(order)
603600
else: # int
604601
tracker.order_id = order

src/project_x_py/risk_manager/core.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,12 @@ async def validate_trade(
236236
)
237237

238238
# Check trading hours if restricted
239-
if self.config.restrict_trading_hours:
240-
if not self._is_within_trading_hours():
241-
is_valid = False
242-
reasons.append("Outside allowed trading hours")
239+
if (
240+
self.config.restrict_trading_hours
241+
and not self._is_within_trading_hours()
242+
):
243+
is_valid = False
244+
reasons.append("Outside allowed trading hours")
243245

244246
# Check for correlated positions
245247
correlated_count = await self._count_correlated_positions(
@@ -379,7 +381,7 @@ async def attach_risk_orders(
379381
)
380382
if use_trailing and self.config.trailing_stop_distance > 0:
381383
# Monitor position for trailing stop activation
382-
asyncio.create_task(
384+
_trailing_task = asyncio.create_task( # noqa: RUF006
383385
self._monitor_trailing_stop(
384386
position,
385387
{

0 commit comments

Comments
 (0)