Spaces:
Running
Running
saadrizvi09
commited on
Commit
·
2181dd6
1
Parent(s):
a4a7fb9
live portfolio
Browse files- live_trading.py +32 -12
- simulated_exchange.py +23 -2
live_trading.py
CHANGED
|
@@ -80,7 +80,7 @@ def get_account_balance():
|
|
| 80 |
|
| 81 |
|
| 82 |
def get_portfolio_value():
|
| 83 |
-
"""Get total portfolio value in USDT (with caching)"""
|
| 84 |
global _portfolio_cache
|
| 85 |
|
| 86 |
# Check cache first
|
|
@@ -92,12 +92,36 @@ def get_portfolio_value():
|
|
| 92 |
try:
|
| 93 |
client = get_testnet_client()
|
| 94 |
account = client.get_account()
|
| 95 |
-
total_usdt = 0.0
|
| 96 |
-
holdings = []
|
| 97 |
|
| 98 |
# Assets that are stablecoins or don't have USDT pairs on testnet
|
| 99 |
skip_assets = {'USDT', 'BUSD', 'USDC', 'DAI', 'TUSD', 'PAX', 'TRY', 'ZAR', 'UAH', 'BRL', 'EUR', 'GBP', 'AUD', 'NGN', 'RUB', 'UAH', 'BIDR', 'IDRT', 'VAI'}
|
| 100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
for balance in account['balances']:
|
| 102 |
try:
|
| 103 |
free = float(balance.get('free', 0))
|
|
@@ -117,11 +141,12 @@ def get_portfolio_value():
|
|
| 117 |
})
|
| 118 |
total_usdt += value_usdt
|
| 119 |
elif asset not in skip_assets:
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
|
|
|
|
|
|
| 123 |
value_usdt = total * price
|
| 124 |
-
|
| 125 |
if value_usdt > 0.01:
|
| 126 |
holdings.append({
|
| 127 |
'asset': asset,
|
|
@@ -129,11 +154,6 @@ def get_portfolio_value():
|
|
| 129 |
'value_usdt': value_usdt
|
| 130 |
})
|
| 131 |
total_usdt += value_usdt
|
| 132 |
-
except Exception as price_error:
|
| 133 |
-
# Only log if it's not a known invalid symbol
|
| 134 |
-
error_str = str(price_error)
|
| 135 |
-
if 'Invalid symbol' not in error_str:
|
| 136 |
-
print(f"[Portfolio] Cannot get price for {asset}USDT: {price_error}")
|
| 137 |
except Exception as balance_error:
|
| 138 |
print(f"[Portfolio] Error processing balance: {balance_error}")
|
| 139 |
continue
|
|
|
|
| 80 |
|
| 81 |
|
| 82 |
def get_portfolio_value():
|
| 83 |
+
"""Get total portfolio value in USDT (with caching and SAFE batch price fetch)"""
|
| 84 |
global _portfolio_cache
|
| 85 |
|
| 86 |
# Check cache first
|
|
|
|
| 92 |
try:
|
| 93 |
client = get_testnet_client()
|
| 94 |
account = client.get_account()
|
|
|
|
|
|
|
| 95 |
|
| 96 |
# Assets that are stablecoins or don't have USDT pairs on testnet
|
| 97 |
skip_assets = {'USDT', 'BUSD', 'USDC', 'DAI', 'TUSD', 'PAX', 'TRY', 'ZAR', 'UAH', 'BRL', 'EUR', 'GBP', 'AUD', 'NGN', 'RUB', 'UAH', 'BIDR', 'IDRT', 'VAI'}
|
| 98 |
|
| 99 |
+
# First pass: identify symbols to fetch (ONLY what user actually holds)
|
| 100 |
+
symbols_to_fetch = []
|
| 101 |
+
for balance in account['balances']:
|
| 102 |
+
free = float(balance.get('free', 0))
|
| 103 |
+
locked = float(balance.get('locked', 0))
|
| 104 |
+
total = free + locked
|
| 105 |
+
if total > 0.001:
|
| 106 |
+
asset = balance.get('asset', 'UNKNOWN')
|
| 107 |
+
if asset not in skip_assets and asset != 'USDT':
|
| 108 |
+
symbols_to_fetch.append(f"{asset}USDT")
|
| 109 |
+
|
| 110 |
+
# Batch fetch ONLY needed prices (API weight: 2 per symbol - very safe!)
|
| 111 |
+
price_map = {}
|
| 112 |
+
for symbol in symbols_to_fetch:
|
| 113 |
+
try:
|
| 114 |
+
ticker = client.get_symbol_ticker(symbol=symbol)
|
| 115 |
+
price_map[symbol] = float(ticker['price'])
|
| 116 |
+
except Exception as e:
|
| 117 |
+
# Silently skip invalid symbols
|
| 118 |
+
pass
|
| 119 |
+
|
| 120 |
+
total_usdt = 0.0
|
| 121 |
+
holdings = []
|
| 122 |
+
|
| 123 |
+
# Second pass: calculate values using pre-fetched prices
|
| 124 |
+
|
| 125 |
for balance in account['balances']:
|
| 126 |
try:
|
| 127 |
free = float(balance.get('free', 0))
|
|
|
|
| 141 |
})
|
| 142 |
total_usdt += value_usdt
|
| 143 |
elif asset not in skip_assets:
|
| 144 |
+
# Use pre-fetched price from batch call
|
| 145 |
+
trading_pair = f"{asset}USDT"
|
| 146 |
+
price = price_map.get(trading_pair, 0.0)
|
| 147 |
+
|
| 148 |
+
if price > 0:
|
| 149 |
value_usdt = total * price
|
|
|
|
| 150 |
if value_usdt > 0.01:
|
| 151 |
holdings.append({
|
| 152 |
'asset': asset,
|
|
|
|
| 154 |
'value_usdt': value_usdt
|
| 155 |
})
|
| 156 |
total_usdt += value_usdt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
except Exception as balance_error:
|
| 158 |
print(f"[Portfolio] Error processing balance: {balance_error}")
|
| 159 |
continue
|
simulated_exchange.py
CHANGED
|
@@ -305,7 +305,7 @@ def execute_sell(
|
|
| 305 |
|
| 306 |
def get_portfolio_summary(user_email: str = "default_user") -> dict:
|
| 307 |
"""
|
| 308 |
-
Get complete portfolio summary with current values
|
| 309 |
|
| 310 |
Args:
|
| 311 |
user_email: User identifier
|
|
@@ -317,6 +317,25 @@ def get_portfolio_summary(user_email: str = "default_user") -> dict:
|
|
| 317 |
statement = select(PortfolioAsset).where(PortfolioAsset.user_email == user_email)
|
| 318 |
assets = session.exec(statement).all()
|
| 319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 320 |
portfolio = []
|
| 321 |
total_value_usdt = 0.0
|
| 322 |
|
|
@@ -325,7 +344,9 @@ def get_portfolio_summary(user_email: str = "default_user") -> dict:
|
|
| 325 |
if asset.symbol == "USDT":
|
| 326 |
value_usdt = asset.balance
|
| 327 |
else:
|
| 328 |
-
price
|
|
|
|
|
|
|
| 329 |
value_usdt = asset.balance * price if price else 0.0
|
| 330 |
|
| 331 |
portfolio.append({
|
|
|
|
| 305 |
|
| 306 |
def get_portfolio_summary(user_email: str = "default_user") -> dict:
|
| 307 |
"""
|
| 308 |
+
Get complete portfolio summary with current values (OPTIMIZED - only fetch needed symbols)
|
| 309 |
|
| 310 |
Args:
|
| 311 |
user_email: User identifier
|
|
|
|
| 317 |
statement = select(PortfolioAsset).where(PortfolioAsset.user_email == user_email)
|
| 318 |
assets = session.exec(statement).all()
|
| 319 |
|
| 320 |
+
# Build list of symbols to fetch (ONLY what user holds - very light API usage)
|
| 321 |
+
symbols_to_fetch = [f"{asset.symbol}USDT" for asset in assets
|
| 322 |
+
if asset.balance > 0.00000001 and asset.symbol != "USDT"]
|
| 323 |
+
|
| 324 |
+
# Batch fetch ONLY needed prices (API weight: 2 per symbol, much safer!)
|
| 325 |
+
price_map = {}
|
| 326 |
+
if symbols_to_fetch:
|
| 327 |
+
try:
|
| 328 |
+
client = get_binance_client()
|
| 329 |
+
# Use bookTicker for minimal weight (weight=1 per symbol vs weight=40 for all)
|
| 330 |
+
for symbol in symbols_to_fetch:
|
| 331 |
+
try:
|
| 332 |
+
ticker = client.get_symbol_ticker(symbol=symbol)
|
| 333 |
+
price_map[symbol] = float(ticker['price'])
|
| 334 |
+
except Exception as e:
|
| 335 |
+
print(f"[SimEx] Price fetch failed for {symbol}: {e}")
|
| 336 |
+
except Exception as e:
|
| 337 |
+
print(f"[SimEx] Failed to fetch prices: {e}")
|
| 338 |
+
|
| 339 |
portfolio = []
|
| 340 |
total_value_usdt = 0.0
|
| 341 |
|
|
|
|
| 344 |
if asset.symbol == "USDT":
|
| 345 |
value_usdt = asset.balance
|
| 346 |
else:
|
| 347 |
+
# Use pre-fetched price from batch call
|
| 348 |
+
trading_pair = f"{asset.symbol}USDT"
|
| 349 |
+
price = price_map.get(trading_pair, 0.0)
|
| 350 |
value_usdt = asset.balance * price if price else 0.0
|
| 351 |
|
| 352 |
portfolio.append({
|