feat: robust fee collection in clp_manager.py - positions in 'CLOSING' state are now monitored and fee collection retries until successful before marking as 'CLOSED'
This commit is contained in:
@ -739,12 +739,14 @@ def main():
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
status_data = load_status_data()
|
status_data = load_status_data()
|
||||||
open_positions = [p for p in status_data if p.get('status') == 'OPEN']
|
# Include CLOSING status to ensure we finish what we started (fee collection retries)
|
||||||
|
open_positions = [p for p in status_data if p.get('status') in ['OPEN', 'CLOSING']]
|
||||||
|
|
||||||
active_auto_pos = next((p for p in open_positions if p.get('type') == 'AUTOMATIC'), None)
|
active_auto_pos = next((p for p in open_positions if p.get('type') == 'AUTOMATIC'), None)
|
||||||
|
|
||||||
if active_auto_pos:
|
if active_auto_pos:
|
||||||
token_id = active_auto_pos['token_id']
|
token_id = active_auto_pos['token_id']
|
||||||
|
current_status = active_auto_pos.get('status')
|
||||||
pos_details, pool_c = get_position_details(w3, npm, factory, token_id)
|
pos_details, pool_c = get_position_details(w3, npm, factory, token_id)
|
||||||
|
|
||||||
if pos_details:
|
if pos_details:
|
||||||
@ -851,29 +853,33 @@ def main():
|
|||||||
'hedge_pnl_realized_usd': active_auto_pos.get('hedge_pnl_realized', 0.0),
|
'hedge_pnl_realized_usd': active_auto_pos.get('hedge_pnl_realized', 0.0),
|
||||||
'hedge_fees_paid_usd': active_auto_pos.get('hedge_fees_paid', 0.0)
|
'hedge_fees_paid_usd': active_auto_pos.get('hedge_fees_paid', 0.0)
|
||||||
}
|
}
|
||||||
# We use 'target_value' as a proxy for 'Initial Hedge Equity' + 'Initial Uni Val' if strictly tracking strategy?
|
|
||||||
# For now, let's pass what we have.
|
|
||||||
# To get 'hedge_equity', we ideally need clp_hedger to write it to JSON.
|
|
||||||
# Current implementation of kpi_tracker uses 'hedge_equity' in NAV.
|
|
||||||
# If we leave it 0, NAV will be underreported.
|
|
||||||
# WORKAROUND: Assume Hedge PnL Realized IS the equity change if we ignore margin.
|
|
||||||
|
|
||||||
log_kpi_snapshot(snapshot)
|
log_kpi_snapshot(snapshot)
|
||||||
|
|
||||||
if not in_range and CLOSE_POSITION_ENABLED:
|
# --- CLOSING LOGIC ---
|
||||||
logger.warning(f"🛑 Closing Position {token_id} (Out of Range)")
|
if current_status == "CLOSING" or (not in_range and CLOSE_POSITION_ENABLED):
|
||||||
update_position_status(token_id, "CLOSING")
|
if current_status != "CLOSING":
|
||||||
|
logger.warning(f"🛑 Closing Position {token_id} (Out of Range)")
|
||||||
|
update_position_status(token_id, "CLOSING")
|
||||||
|
|
||||||
# 1. Remove Liquidity
|
# 1. Remove Liquidity (if any left)
|
||||||
if decrease_liquidity(w3, npm, account, token_id, pos_details['liquidity'], pos_details['token0_decimals'], pos_details['token1_decimals']):
|
liq_to_remove = pos_details['liquidity']
|
||||||
# 2. Collect Fees
|
success_liq = True
|
||||||
collect_fees(w3, npm, account, token_id)
|
if liq_to_remove > 0:
|
||||||
update_position_status(token_id, "CLOSED")
|
success_liq = decrease_liquidity(w3, npm, account, token_id, liq_to_remove, pos_details['token0_decimals'], pos_details['token1_decimals'])
|
||||||
|
|
||||||
# 3. Optional Rebalance (Sell 50% WETH if fell below)
|
# 2. Collect Fees (Retry if previous attempt failed or if liquidity was just removed)
|
||||||
if REBALANCE_ON_CLOSE_BELOW_RANGE and current_tick < tick_lower:
|
if success_liq:
|
||||||
# Simple rebalance logic here (similar to original check_and_swap surplus logic)
|
if collect_fees(w3, npm, account, token_id):
|
||||||
pass
|
update_position_status(token_id, "CLOSED")
|
||||||
|
|
||||||
|
# 3. Optional Rebalance (Sell 50% WETH if fell below)
|
||||||
|
if REBALANCE_ON_CLOSE_BELOW_RANGE and current_tick < tick_lower:
|
||||||
|
# Simple rebalance logic here (similar to original check_and_swap surplus logic)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
logger.error(f"❌ Fee collection failed for {token_id}. Will retry in next loop.")
|
||||||
|
else:
|
||||||
|
logger.error(f"❌ Liquidity removal failed for {token_id}. Will retry in next loop.")
|
||||||
|
|
||||||
elif OPEN_POSITION_ENABLED:
|
elif OPEN_POSITION_ENABLED:
|
||||||
logger.info("🔍 No active position. Analyzing market (Fast scan: 37s)...")
|
logger.info("🔍 No active position. Analyzing market (Fast scan: 37s)...")
|
||||||
|
|||||||
Reference in New Issue
Block a user