Skip to content

Commit 3e101e0

Browse files
TexasCodingclaude
andcommitted
Phase 8: Fix type checking and linting errors
- Fixed type checking errors in position_manager operations and core modules - Updated ProjectXBase references to use ProjectXClientProtocol for better type safety - Added proper isinstance checks before calling .get() on API responses - Fixed import sorting issues flagged by ruff - All mypy type checks now pass successfully 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent c66242d commit 3e101e0

File tree

4 files changed

+28
-13
lines changed

4 files changed

+28
-13
lines changed

src/project_x_py/position_manager/core.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ async def main():
7474
from datetime import datetime
7575
from typing import TYPE_CHECKING, Any, Optional
7676

77-
from project_x_py.client.base import ProjectXBase
7877
from project_x_py.models import Position
7978
from project_x_py.position_manager.analytics import PositionAnalyticsMixin
8079
from project_x_py.position_manager.monitoring import PositionMonitoringMixin
@@ -83,7 +82,10 @@ async def main():
8382
from project_x_py.position_manager.tracking import PositionTrackingMixin
8483
from project_x_py.risk_manager import RiskManager
8584
from project_x_py.types.config_types import PositionManagerConfig
86-
from project_x_py.types.protocols import RealtimeDataManagerProtocol
85+
from project_x_py.types.protocols import (
86+
ProjectXClientProtocol,
87+
RealtimeDataManagerProtocol,
88+
)
8789
from project_x_py.types.response_types import (
8890
PositionSizingResponse,
8991
RiskAnalysisResponse,
@@ -96,7 +98,6 @@ async def main():
9698
from project_x_py.utils.stats_tracking import StatsTrackingMixin
9799

98100
if TYPE_CHECKING:
99-
from project_x_py.client import ProjectXBase
100101
from project_x_py.order_manager import OrderManager
101102
from project_x_py.realtime import ProjectXRealtimeClient
102103

@@ -175,7 +176,7 @@ class PositionManager(
175176

176177
def __init__(
177178
self,
178-
project_x_client: "ProjectXBase",
179+
project_x_client: "ProjectXClientProtocol",
179180
event_bus: Any,
180181
risk_manager: Optional["RiskManager"] = None,
181182
data_manager: Optional["RealtimeDataManagerProtocol"] = None,
@@ -227,7 +228,7 @@ def __init__(
227228
PositionMonitoringMixin.__init__(self)
228229
StatsTrackingMixin._init_stats_tracking(self)
229230

230-
self.project_x = project_x_client
231+
self.project_x: ProjectXClientProtocol = project_x_client
231232
self.event_bus = event_bus # Store the event bus for emitting events
232233
self.risk_manager = risk_manager
233234
self.data_manager = data_manager

src/project_x_py/position_manager/monitoring.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ async def on_alert(event):
6060
if TYPE_CHECKING:
6161
from asyncio import Lock
6262

63+
from project_x_py.types.protocols import ProjectXClientProtocol
64+
6365
logger = logging.getLogger(__name__)
6466

6567

@@ -75,7 +77,7 @@ class PositionMonitoringMixin:
7577
logger: logging.Logger
7678
stats: dict[str, Any]
7779
_realtime_enabled: bool
78-
project_x: "ProjectXBase"
80+
project_x: "ProjectXClientProtocol"
7981
data_manager: "RealtimeDataManagerProtocol | None"
8082

8183
# Methods from other mixins/main class

src/project_x_py/position_manager/operations.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,17 @@ async def close_position_direct(
149149
):
150150
response = await self.project_x._make_request("POST", url, data=payload)
151151

152-
if response:
152+
if response and isinstance(response, dict):
153153
success = response.get("success", False)
154154

155155
if success:
156156
logger.info(
157157
LogMessages.POSITION_CLOSED,
158158
extra={
159159
"contract_id": contract_id,
160-
"order_id": response.get("orderId"),
160+
"order_id": response.get("orderId")
161+
if isinstance(response, dict)
162+
else None,
161163
},
162164
)
163165
# Remove from tracked positions if present
@@ -175,7 +177,11 @@ async def close_position_direct(
175177

176178
self.stats["closed_positions"] += 1
177179
else:
178-
error_msg = response.get("errorMessage", "Unknown error")
180+
error_msg = (
181+
response.get("errorMessage", "Unknown error")
182+
if isinstance(response, dict)
183+
else "Unknown error"
184+
)
179185
logger.error(
180186
LogMessages.POSITION_ERROR,
181187
extra={"operation": "close_position", "error": error_msg},
@@ -280,7 +286,7 @@ async def partially_close_position(
280286

281287
response = await self.project_x._make_request("POST", url, data=payload)
282288

283-
if response:
289+
if response and isinstance(response, dict):
284290
success = response.get("success", False)
285291

286292
if success:
@@ -290,7 +296,9 @@ async def partially_close_position(
290296
"contract_id": contract_id,
291297
"partial": True,
292298
"size": close_size,
293-
"order_id": response.get("orderId"),
299+
"order_id": response.get("orderId")
300+
if isinstance(response, dict)
301+
else None,
294302
},
295303
)
296304
# Trigger position refresh to get updated sizes
@@ -301,7 +309,11 @@ async def partially_close_position(
301309

302310
self.stats["positions_partially_closed"] += 1
303311
else:
304-
error_msg = response.get("errorMessage", "Unknown error")
312+
error_msg = (
313+
response.get("errorMessage", "Unknown error")
314+
if isinstance(response, dict)
315+
else "Unknown error"
316+
)
305317
logger.error(
306318
LogMessages.POSITION_ERROR,
307319
extra={"operation": "partial_close", "error": error_msg},

src/project_x_py/types/protocols.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ async def close_position(
354354
class PositionManagerProtocol(Protocol):
355355
"""Protocol defining the interface that mixins expect from PositionManager."""
356356

357-
project_x: "ProjectXBase"
357+
project_x: "ProjectXClientProtocol"
358358
logger: Any
359359
event_bus: Any # EventBus instance
360360
position_lock: asyncio.Lock

0 commit comments

Comments
 (0)