diff --git a/main.py b/main.py index e6aa475..ab2dec9 100644 --- a/main.py +++ b/main.py @@ -149,6 +149,7 @@ def run_cycle(): logger.info("Cancelled outdated stop %s for %s (amt=%.6f, px=%.6g)", s["id"], sym, abs(s["amount"]), s["price"]) tracked_stops.pop(sym, None) + time.sleep(0.3) # Wait for Bitfinex to release locked balance logger.warning("Position %s missing/outdated stop-loss, placing now", sym) sl = trader.place_stop_loss_order(sym, amount, entry) @@ -345,6 +346,10 @@ def run_cycle(): if result and result.get("status") == "failed": logger.warning("Order failed at exchange: %s %s — %s", action, validated["symbol"], result.get("error", "")) rejected.append({**validated, "reject_reason": f"交易所錯誤: {result.get('error', 'unknown')}"}) + # BUY failed at exchange — mark balance as unreliable to skip remaining BUYs + if action == "BUY" and "not enough" in result.get("error", "").lower(): + port["available_usdt"] = 0 + logger.info("Marked available_usdt=0 to prevent further BUY attempts this cycle") continue if result and result.get("status") in ("filled", "submitted"): @@ -369,9 +374,13 @@ def run_cycle(): if action == "BUY": # Cancel existing exchange stop orders before placing new one pos = port.get("positions", {}).get(sym, {}) + cancelled_any = False for s in stop_orders_by_sym.get(sym, []): trader.cancel_order(s["id"]) + cancelled_any = True logger.info("Cancelled old stop %s for %s (position size changed)", s["id"], sym) + if cancelled_any: + time.sleep(0.3) # Wait for Bitfinex to release locked balance # Place new stop-loss for TOTAL position amount at new avg entry total_amount = pos.get("amount", amount)