@@ -77,7 +77,9 @@ async def try_get_data(days: int, interval: int) -> float | None:
7777 return None
7878
7979
80- async def display_positions (position_manager : "PositionManager" ) -> None :
80+ async def display_positions (
81+ position_manager : "PositionManager" , suite : TradingSuite | None = None
82+ ) -> None :
8183 """Display current positions with detailed information."""
8284 print ("\n 📊 Current Positions:" )
8385 print ("-" * 80 )
@@ -88,17 +90,45 @@ async def display_positions(position_manager: "PositionManager") -> None:
8890 print ("No open positions" )
8991 return
9092
91- # Get portfolio P&L concurrently with position display
92- pnl_task = asyncio .create_task (position_manager .get_portfolio_pnl ())
93-
94- portfolio_pnl = await pnl_task
95- # Display each position
93+ # Display each position with real P&L calculation
9694 for position in positions :
9795 print (f"\n { position .contractId } :" )
9896 print (f" Quantity: { position .size } " )
9997 print (f" Average Price: ${ position .averagePrice :.2f} " )
100- print (f" Position Value: ${ position .averagePrice :.2f} " )
101- print (f" Unrealized P&L: ${ portfolio_pnl .get ('unrealized_pnl' , 0 ):.2f} " )
98+
99+ # Calculate position value
100+ position_value = position .averagePrice * position .size
101+ print (f" Position Value: ${ position_value :,.2f} " )
102+
103+ # Calculate real P&L if we have market data
104+ unrealized_pnl = 0.0
105+ if suite :
106+ try :
107+ # Get current market price
108+ current_price = await suite .data .get_current_price ()
109+ if current_price :
110+ # Get instrument info for tick value
111+ instrument_info = await suite .client .get_instrument (
112+ suite .instrument
113+ )
114+ tick_value = instrument_info .tickValue
115+
116+ # Calculate P&L using position manager's method
117+ pnl_data = await position_manager .calculate_position_pnl (
118+ position , float (current_price ), point_value = tick_value
119+ )
120+ unrealized_pnl = pnl_data ["unrealized_pnl" ]
121+ except Exception :
122+ # If we can't get real-time price, try portfolio P&L
123+ try :
124+ portfolio_pnl = await position_manager .get_portfolio_pnl ()
125+ unrealized_pnl = portfolio_pnl .get ("unrealized_pnl" , 0 ) / len (
126+ positions
127+ )
128+ except Exception :
129+ pass
130+
131+ print (f" Unrealized P&L: ${ unrealized_pnl :,.2f} " )
102132
103133
104134async def display_risk_metrics (position_manager : "PositionManager" ) -> None :
@@ -137,7 +167,9 @@ async def display_risk_metrics(position_manager: "PositionManager") -> None:
137167
138168
139169async def monitor_positions (
140- position_manager : "PositionManager" , duration : int = 30
170+ position_manager : "PositionManager" ,
171+ suite : TradingSuite | None = None ,
172+ duration : int = 30 ,
141173) -> None :
142174 """Monitor positions for a specified duration with async updates."""
143175 print (f"\n 👁️ Monitoring positions for { duration } seconds..." )
@@ -157,13 +189,36 @@ async def monitor_positions(
157189 if positions :
158190 print (f" Active positions: { len (positions )} " )
159191
160- # Get P&L if available
192+ # Get P&L with current market prices
193+ total_pnl = 0.0
161194 try :
162- pnl = await position_manager .get_portfolio_pnl ()
163- print (f" Total P&L: ${ pnl .get ('total_pnl' , 0 ):,.2f} " )
195+ # Try to calculate real P&L with current prices
196+ if suite and positions :
197+ current_price = await suite .data .get_current_price ()
198+ if current_price :
199+ instrument_info = await suite .client .get_instrument (
200+ suite .instrument
201+ )
202+ tick_value = instrument_info .tickValue
203+
204+ for position in positions :
205+ pnl_data = (
206+ await position_manager .calculate_position_pnl (
207+ position ,
208+ float (current_price ),
209+ point_value = tick_value ,
210+ )
211+ )
212+ total_pnl += pnl_data ["unrealized_pnl" ]
213+ else :
214+ # Fallback to portfolio P&L
215+ pnl = await position_manager .get_portfolio_pnl ()
216+ total_pnl = pnl .get ("total_pnl" , 0 )
164217 except Exception :
165218 pass
166219
220+ print (f" Total P&L: ${ total_pnl :,.2f} " )
221+
167222 # Get summary if available
168223 if hasattr (position_manager , "get_portfolio_summary" ):
169224 try :
@@ -194,7 +249,6 @@ async def main() -> bool:
194249 print ("\n 🔑 Initializing TradingSuite v3..." )
195250 suite = await TradingSuite .create (
196251 "MNQ" ,
197- features = ["realtime_tracking" ],
198252 timeframes = ["1min" , "5min" ],
199253 )
200254
@@ -208,7 +262,7 @@ async def main() -> bool:
208262
209263 if existing_positions :
210264 print (f"Found { len (existing_positions )} existing positions" )
211- await display_positions (suite .positions )
265+ await display_positions (suite .positions , suite )
212266 else :
213267 print ("No existing positions found" )
214268
@@ -218,11 +272,14 @@ async def main() -> bool:
218272 )
219273 print (" (This will place a REAL order on the market)" )
220274
221- # Get current price for order placement
275+ # Get instrument info and current price for order placement
276+ instrument_info = await suite .client .get_instrument ("MNQ" )
277+ contract_id = instrument_info .id
222278 current_price = await get_current_market_price (suite )
223279
224280 if current_price :
225281 print (f"\n Current MNQ price: ${ current_price :.2f} " )
282+ print (f" Contract ID: { contract_id } " )
226283 print (" Test order: BUY 1 MNQ at market" )
227284
228285 # Wait for user confirmation
@@ -236,7 +293,7 @@ async def main() -> bool:
236293 if response == "y" :
237294 print ("\n Placing market order..." )
238295 order_response = await suite .orders .place_market_order (
239- contract_id = "MNQ" ,
296+ contract_id = contract_id ,
240297 side = 0 ,
241298 size = 1 , # Buy
242299 )
@@ -266,7 +323,7 @@ async def main() -> bool:
266323 print ("=" * 80 )
267324
268325 # 1. Display current positions
269- await display_positions (suite .positions )
326+ await display_positions (suite .positions , suite )
270327
271328 # 2. Show risk metrics
272329 await display_risk_metrics (suite .positions )
@@ -313,7 +370,7 @@ async def main() -> bool:
313370 print ("=" * 80 )
314371
315372 # Monitor for 30 seconds
316- await monitor_positions (suite .positions , duration = 30 )
373+ await monitor_positions (suite .positions , suite , duration = 30 )
317374
318375 # 6. Offer to close positions
319376 if await suite .positions .get_all_positions ():
0 commit comments