Skip to content

Commit 9deb500

Browse files
authored
fix:fix total equity zero (#566)
## 📝 Pull Request Template ### 1. Related Issue Closes # (issue number) ### 2. Type of Change (select one) Type of Change: Bug Fix ### 3. Description Please describe the changes made and why they are necessary. ### 4. Testing - [x] I have tested this locally. - [ ] I have updated or added relevant tests. ### 5. Checklist - [x] I have read the [Code of Conduct](./CODE_OF_CONDUCT.md) - [x] I have followed the [Contributing Guidelines](./CONTRIBUTING.md) - [x] My changes follow the project's coding style
1 parent c8e56b7 commit 9deb500

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

python/valuecell/agents/common/trading/execution/ccxt_trading.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,8 +1329,10 @@ async def fetch_positions(self, symbols: Optional[List[str]] = None) -> List[Dic
13291329
positions = await exchange.fetch_positions(normalized_symbols)
13301330
return positions
13311331
except Exception as e:
1332-
print(f"Warning: Could not fetch positions: {e}")
1333-
return []
1332+
# Do NOT return an empty list on network/exchange errors; propagate
1333+
# so upstream retry/backoff logic can kick in and avoid wiping holdings.
1334+
logger.warning(f"⚠️ Could not fetch positions: {e}")
1335+
raise
13341336

13351337
async def cancel_order(self, order_id: str, symbol: str) -> Dict:
13361338
"""Cancel an open order.

python/valuecell/agents/common/trading/utils.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ async def fetch_free_cash_from_gateway(
3131
logger.info("Fetching exchange balance for LIVE trading mode")
3232
try:
3333
if not hasattr(execution_gateway, "fetch_balance"):
34-
return 0.0, 0.0
34+
raise AttributeError(
35+
f"Execution gateway {execution_gateway.__class__.__name__} "
36+
"does not implement the required 'fetch_balance' method."
37+
)
3538
balance = await execution_gateway.fetch_balance()
3639
except Exception as e:
3740
if retry_cnt < max_retries:
@@ -44,11 +47,12 @@ async def fetch_free_cash_from_gateway(
4447
return await fetch_free_cash_from_gateway(
4548
execution_gateway, symbols, retry_cnt + 1, max_retries
4649
)
50+
# Propagate after exhausting retries so upstream can keep cached portfolio
4751
logger.error(
48-
f"Failed to fetch free cash from exchange after {max_retries} retries, returning 0.0",
52+
f"Failed to fetch free cash from exchange after {max_retries} retries.",
4953
exception=e,
5054
)
51-
return 0.0, 0.0
55+
raise
5256

5357
logger.info(f"Raw balance response: {balance}")
5458
free_map: dict[str, float] = {}
@@ -70,6 +74,10 @@ async def fetch_free_cash_from_gateway(
7074
except Exception:
7175
continue
7276

77+
# If balance structure is unrecognized, avoid returning zeros silently
78+
if not isinstance(balance, dict) or (not free_map and free_section is None):
79+
raise ValueError("Unrecognized balance response shape from exchange")
80+
7381
logger.info(f"Parsed free balance map: {free_map}")
7482
# Derive quote currencies from symbols, fallback to common USD-stable quotes
7583
quotes: list[str] = []

0 commit comments

Comments
 (0)