2020from hummingbot .strategy_v2 .executors .lp_executor .lp_executor import LPExecutor
2121from hummingbot .strategy_v2 .executors .order_executor .order_executor import OrderExecutor
2222from hummingbot .strategy_v2 .executors .position_executor .position_executor import PositionExecutor
23+ from hummingbot .strategy_v2 .executors .swap_executor .swap_executor import SwapExecutor
2324from hummingbot .strategy_v2 .executors .twap_executor .twap_executor import TWAPExecutor
2425from hummingbot .strategy_v2 .executors .xemm_executor .xemm_executor import XEMMExecutor
2526from hummingbot .strategy_v2 .models .executor_actions import (
3334
3435
3536class PositionHold :
36- def __init__ (self , connector_name : str , trading_pair : str , side : TradeType ):
37+ def __init__ (self , connector_name : str , trading_pair : str , side : TradeType = None ):
3738 self .connector_name = connector_name
3839 self .trading_pair = trading_pair
3940 self .side = side
@@ -67,6 +68,7 @@ def add_orders_from_executor(self, executor: ExecutorInfo):
6768 # Update metrics incrementally
6869 executed_amount_base = Decimal (str (order .get ("executed_amount_base" , 0 )))
6970 executed_amount_quote = Decimal (str (order .get ("executed_amount_quote" , 0 )))
71+
7072 is_buy = order .get ("trade_type" ) == "BUY"
7173
7274 # Update volume traded in quote
@@ -80,16 +82,10 @@ def add_orders_from_executor(self, executor: ExecutorInfo):
8082 self .sell_amount_base += executed_amount_base
8183 self .sell_amount_quote += executed_amount_quote
8284
83- # Update fees
85+ # Update fees (tx fees paid)
8486 self .cum_fees_quote += Decimal (str (order .get ("cumulative_fee_paid_quote" , 0 )))
8587
8688 def get_position_summary (self , mid_price : Decimal ):
87- # Handle NaN quote amounts by calculating them lazily
88- if self .buy_amount_quote .is_nan () and self .buy_amount_base > 0 :
89- self .buy_amount_quote = self .buy_amount_base * mid_price
90- if self .sell_amount_quote .is_nan () and self .sell_amount_base > 0 :
91- self .sell_amount_quote = self .sell_amount_base * mid_price
92-
9389 # Calculate buy and sell breakeven prices
9490 buy_breakeven_price = self .buy_amount_quote / self .buy_amount_base if self .buy_amount_base > 0 else Decimal ("0" )
9591 sell_breakeven_price = self .sell_amount_quote / self .sell_amount_base if self .sell_amount_base > 0 else Decimal ("0" )
@@ -112,13 +108,13 @@ def get_position_summary(self, mid_price: Decimal):
112108 # Long position: remaining buy amount
113109 remaining_base = net_amount_base
114110 remaining_quote = self .buy_amount_quote - (matched_amount_base * buy_breakeven_price )
115- breakeven_price = remaining_quote / remaining_base
111+ breakeven_price = remaining_quote / remaining_base if remaining_base != 0 else Decimal ( "0" )
116112 unrealized_pnl_quote = (mid_price - breakeven_price ) * remaining_base
117113 else :
118114 # Short position: remaining sell amount
119115 remaining_base = abs (net_amount_base )
120116 remaining_quote = self .sell_amount_quote - (matched_amount_base * sell_breakeven_price )
121- breakeven_price = remaining_quote / remaining_base
117+ breakeven_price = remaining_quote / remaining_base if remaining_base != 0 else Decimal ( "0" )
122118 unrealized_pnl_quote = (breakeven_price - mid_price ) * remaining_base
123119
124120 return PositionSummary (
@@ -147,6 +143,7 @@ class ExecutorOrchestrator:
147143 "xemm_executor" : XEMMExecutor ,
148144 "order_executor" : OrderExecutor ,
149145 "lp_executor" : LPExecutor ,
146+ "swap_executor" : SwapExecutor ,
150147 }
151148
152149 @classmethod
@@ -255,7 +252,7 @@ def _load_position_from_db(self, controller_id: str, db_position: Position):
255252 def _create_initial_positions (self ):
256253 """
257254 Create initial positions from config overrides.
258- Uses NaN for quote amounts initially - they will be calculated lazily when needed .
255+ Quote amounts are calculated using current mid_price .
259256 """
260257 for controller_id , initial_positions in self .initial_positions_by_controller .items ():
261258 if controller_id not in self .cached_performance :
@@ -264,22 +261,28 @@ def _create_initial_positions(self):
264261 self .positions_held [controller_id ] = []
265262
266263 for position_config in initial_positions :
264+ # Get mid_price for quote amount calculation
265+ mid_price = self .strategy .market_data_provider .get_price_by_type (
266+ position_config .connector_name , position_config .trading_pair , PriceType .MidPrice
267+ )
268+ quote_amount = position_config .amount * mid_price
269+
267270 # Create PositionHold object
268271 position_hold = PositionHold (
269272 position_config .connector_name ,
270273 position_config .trading_pair ,
271274 position_config .side
272275 )
273276
274- # Set amounts based on side, using NaN for quote amounts
277+ # Set amounts based on side
275278 if position_config .side == TradeType .BUY :
276279 position_hold .buy_amount_base = position_config .amount
277- position_hold .buy_amount_quote = Decimal ( "NaN" ) # Will be calculated lazily
280+ position_hold .buy_amount_quote = quote_amount
278281 position_hold .sell_amount_base = Decimal ("0" )
279282 position_hold .sell_amount_quote = Decimal ("0" )
280283 else :
281284 position_hold .sell_amount_base = position_config .amount
282- position_hold .sell_amount_quote = Decimal ( "NaN" ) # Will be calculated lazily
285+ position_hold .sell_amount_quote = quote_amount
283286 position_hold .buy_amount_base = Decimal ("0" )
284287 position_hold .buy_amount_quote = Decimal ("0" )
285288
@@ -305,7 +308,7 @@ async def stop(self, max_executors_close_attempts: int = 3):
305308 for i in range (max_executors_close_attempts ):
306309 if all ([executor .executor_info .is_done for executors_list in self .active_executors .values ()
307310 for executor in executors_list ]):
308- continue
311+ break # All executors are done, exit early
309312 await asyncio .sleep (2.0 )
310313 # Store all positions and executors
311314 self .store_all_positions ()
@@ -466,7 +469,7 @@ def _update_positions_from_done_executors(self):
466469 if existing_position :
467470 existing_position .add_orders_from_executor (executor_info )
468471 else :
469- # Create new position
472+ # Create new position (handles both spot/perp and LP)
470473 position = PositionHold (
471474 executor_info .connector_name ,
472475 executor_info .trading_pair ,
0 commit comments