@@ -1529,7 +1529,7 @@ async def telegram_handle_message(update: Update, context: ContextTypes.DEFAULT_
15291529 sync_positions_with_binance (client , positions )
15301530
15311531 # Support both button text and commands
1532- if text in ["� Portfolio" , "�📊 Balance " , "/balance" , "/bal" ]:
1532+ if text in ["💰 Portfolio" , "/balance" , "/bal" ]:
15331533 fetch_all_balances () # ✅ Use cross-asset balance fetching
15341534
15351535 btc = balance ['btc' ]
@@ -1580,10 +1580,8 @@ async def telegram_handle_message(update: Update, context: ContextTypes.DEFAULT_
15801580
15811581
15821582
1583- elif text in ["💼 Positions" , "💼 Investments" , "/investments" , "/inv" , "/positions" ]:
1584- msg = format_investments_message (positions , get_latest_price , DUST_LIMIT )
1585- await send_with_keyboard (update , msg )
1586-
1583+ # Positions handler removed - use Portfolio instead
1584+
15871585 elif text in ["⏸ Pause Trading" , "/pause" ]:
15881586 set_paused (True )
15891587 await send_with_keyboard (update , "⏸ Trading is now *paused*. Bot will not auto-invest or auto-sell until resumed." , parse_mode = 'Markdown' )
@@ -1625,7 +1623,6 @@ async def telegram_handle_message(update: Update, context: ContextTypes.DEFAULT_
16251623
16261624 # Capture diagnostic output
16271625 import io
1628- import sys
16291626
16301627 old_stdout = sys .stdout
16311628 sys .stdout = captured_output = io .StringIO ()
@@ -1739,8 +1736,8 @@ async def telegram_handle_message(update: Update, context: ContextTypes.DEFAULT_
17391736 except Exception as e :
17401737 await send_with_keyboard (update , f"❌ Quick momentum check failed: { str (e )} " )
17411738
1742- elif text in ["� Overview" , "📈 Status" , "�📊 Trading Status" , "/status" , "/trading" , "/overview" ]:
1743- await send_with_keyboard (update , "� Getting complete cross-asset overview..." )
1739+ elif text in ["📈 Overview" , "📈 Status" , "/status" , "/trading" , "/overview" ]:
1740+ await send_with_keyboard (update , "📈 Getting complete cross-asset overview..." )
17441741
17451742 fetch_all_balances () # Get all asset balances
17461743 btc = balance ['btc' ]
@@ -2057,7 +2054,7 @@ def is_paused():
20572054 return state .get ("paused" , False )
20582055
20592056main_keyboard = [
2060- ["� Portfolio" , "💼 Positions" ], # Clear financial info
2057+ ["💰 Portfolio" ], # Financial info
20612058 ["⏸ Pause Trading" , "▶️ Resume Trading" ], # Trading control
20622059 ["📝 Trade Log" , "🔍 Diagnostics" ], # History & enhanced diagnostics
20632060 ["🔄 Connection" , "⚡ Quick Check" ], # WebSocket + fast momentum
@@ -2304,6 +2301,61 @@ def determine_trading_pair(from_asset, to_asset):
23042301 else :
23052302 raise ValueError (f"Unsupported trading pair: { from_asset } -> { to_asset } " )
23062303
2304+ def suggest_alternative_trades (from_asset , to_asset , min_notional_needed ):
2305+ """Suggest alternative trading strategies when single-asset trade fails"""
2306+ print (f"\n === ALTERNATIVE TRADING SUGGESTIONS ===" )
2307+
2308+ # Refresh balances to get accurate data
2309+ fetch_all_balances ()
2310+
2311+ # Calculate current asset values
2312+ btc_price = get_latest_price ('BTCUSDC' ) or 0
2313+ eth_price = get_latest_price ('ETHUSDC' ) or 0
2314+
2315+ btc_value = balance ['btc' ] * btc_price
2316+ eth_value = balance ['eth' ] * eth_price
2317+ total_value = btc_value + eth_value + balance ['usd' ]
2318+
2319+ print (f"Current Portfolio Values:" )
2320+ print (f" BTC: { balance ['btc' ]:.6f} (~${ btc_value :.2f} )" )
2321+ print (f" ETH: { balance ['eth' ]:.6f} (~${ eth_value :.2f} )" )
2322+ print (f" USDC: ${ balance ['usd' ]:.2f} " )
2323+ print (f" Total: ${ total_value :.2f} " )
2324+
2325+ # Suggest strategies
2326+ suggestions = []
2327+
2328+ if to_asset == 'USDC' :
2329+ # Want to convert to USDC
2330+ if btc_value >= min_notional_needed and from_asset != 'BTC' :
2331+ suggestions .append (f"• Sell BTC instead: { balance ['btc' ]:.6f} BTC → ${ btc_value :.2f} USDC" )
2332+ if eth_value >= min_notional_needed and from_asset != 'ETH' :
2333+ suggestions .append (f"• Sell ETH instead: { balance ['eth' ]:.6f} ETH → ${ eth_value :.2f} USDC" )
2334+
2335+ # Multi-asset liquidation
2336+ combined_value = (btc_value if from_asset != 'BTC' else 0 ) + (eth_value if from_asset != 'ETH' else 0 )
2337+ if combined_value >= min_notional_needed :
2338+ suggestions .append (f"• Partial liquidation: Combine assets for ${ combined_value :.2f} total" )
2339+
2340+ elif from_asset == 'USDC' and balance ['usd' ] < min_notional_needed :
2341+ # Need more USDC
2342+ if btc_value >= 5 : # Minimum viable conversion
2343+ suggestions .append (f"• Convert BTC to USDC first: ${ btc_value :.2f} available" )
2344+ if eth_value >= 5 :
2345+ suggestions .append (f"• Convert ETH to USDC first: ${ eth_value :.2f} available" )
2346+
2347+ if suggestions :
2348+ print (f"\n Suggested alternatives:" )
2349+ for suggestion in suggestions :
2350+ print (f" { suggestion } " )
2351+ else :
2352+ print (f"\n ⚠️ No viable alternatives found. Consider:" )
2353+ print (f" • Add more funds to your account" )
2354+ print (f" • Wait for price movements" )
2355+ print (f" • Reduce position sizes" )
2356+
2357+ print (f"=== END SUGGESTIONS ===\n " )
2358+
23072359def cross_asset_trade (from_asset , to_asset , amount , symbol_for_position = None ):
23082360 """Execute a cross-asset trade between BTC, ETH, and USDC"""
23092361 try :
@@ -2359,8 +2411,33 @@ def cross_asset_trade(from_asset, to_asset, amount, symbol_for_position=None):
23592411 rounded_amount = adjusted_amount
23602412 trade_value = rounded_amount * current_price
23612413 else :
2362- print (f"[ERROR] Cannot meet minimum notional. Required: { adjusted_amount :.8f} , Available: { balance [balance_key ]:.8f} " )
2363- return None
2414+ # For SELL operations, try using maximum available balance if it's reasonably close
2415+ if side == 'SELL' :
2416+ max_available = balance [balance_key ]
2417+ max_rounded = round_qty (symbol , max_available )
2418+ max_value = max_rounded * current_price
2419+
2420+ # If max available is within 90% of minimum notional, allow the trade
2421+ if max_value >= (min_notional * 0.90 ) and max_rounded > 0 :
2422+ print (f"[AUTO-ADJUST] Using maximum available balance: { max_rounded :.8f} (${ max_value :.2f} )" )
2423+ print (f"[AUTO-ADJUST] Trade allowed as it's { (max_value / min_notional )* 100 :.1f} % of minimum notional" )
2424+ rounded_amount = max_rounded
2425+ trade_value = max_value
2426+ else :
2427+ print (f"[SKIP] Insufficient balance for minimum notional trade:" )
2428+ print (f" Required: { adjusted_amount :.8f} { from_asset } (${ min_notional :.2f} )" )
2429+ print (f" Available: { max_available :.8f} { from_asset } (${ max_value :.2f} )" )
2430+
2431+ # Provide alternative trading suggestions
2432+ suggest_alternative_trades (from_asset , to_asset , min_notional )
2433+ return None
2434+ else :
2435+ # For BUY operations, we need exact minimum notional
2436+ print (f"[ERROR] Cannot meet minimum notional. Required: { adjusted_amount :.8f} , Available: { balance [balance_key ]:.8f} " )
2437+
2438+ # Provide alternative trading suggestions
2439+ suggest_alternative_trades (from_asset , to_asset , min_notional )
2440+ return None
23642441
23652442 print (f"[CROSS-TRADE] Trade validation passed - Value: ${ trade_value :.2f} , Min: ${ min_notional :.2f} " )
23662443
0 commit comments