Bugfix: Atomic writes for active_trades.json + Dashboard now reads real state (not stale). Bot and Dashboard fully synced (2026-07-09 20:14)
This commit is contained in:
parent
2b09ab6d13
commit
572bfdfb0d
|
|
@ -218,11 +218,14 @@ class TradingBotV03:
|
||||||
self.place_buy_order(best_signal, trade_amount)
|
self.place_buy_order(best_signal, trade_amount)
|
||||||
|
|
||||||
logger.info(f"CYCLE END | Active trades: {len(self.active_trades)} | Free USDT: ${usdt_free:.2f}")
|
logger.info(f"CYCLE END | Active trades: {len(self.active_trades)} | Free USDT: ${usdt_free:.2f}")
|
||||||
# Save active trades for dashboard
|
|
||||||
import json
|
# Save active trades for dashboard (atomic write with temp file)
|
||||||
|
import json, os
|
||||||
try:
|
try:
|
||||||
with open('/home/marc/bot-deploy/active_trades.json', 'w') as f:
|
temp_file = '/home/marc/bot-deploy/active_trades.json.tmp'
|
||||||
|
with open(temp_file, 'w') as f:
|
||||||
json.dump({'active_trades': self.active_trades, 'count': len(self.active_trades)}, f)
|
json.dump({'active_trades': self.active_trades, 'count': len(self.active_trades)}, f)
|
||||||
|
os.replace(temp_file, '/home/marc/bot-deploy/active_trades.json')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f'Failed to save active_trades.json: {e}')
|
logger.warning(f'Failed to save active_trades.json: {e}')
|
||||||
logger.info("=" * 70)
|
logger.info("=" * 70)
|
||||||
|
|
@ -233,8 +236,7 @@ class TradingBotV03:
|
||||||
logger.info("TRADING BOT V0.3 STARTED")
|
logger.info("TRADING BOT V0.3 STARTED")
|
||||||
logger.info(f"Symbols: {SYMBOLS}")
|
logger.info(f"Symbols: {SYMBOLS}")
|
||||||
logger.info(f"Strategy: Local Min Signals | Risk: TP=+{TAKE_PROFIT_PCT*100:.1f}% / SL={STOP_LOSS_PCT*100:.1f}%")
|
logger.info(f"Strategy: Local Min Signals | Risk: TP=+{TAKE_PROFIT_PCT*100:.1f}% / SL={STOP_LOSS_PCT*100:.1f}%")
|
||||||
logger.info(f"Position size: Max ${MAX_TRADE_USDT}/trade (50% capital avail)")
|
logger.info(f"KEY FIX: Fresh balance fetched EVERY cycle (no stale cache!)")
|
||||||
logger.info(f"")
|
|
||||||
logger.info("=" * 70)
|
logger.info("=" * 70)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -251,3 +253,4 @@ class TradingBotV03:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bot = TradingBotV03()
|
bot = TradingBotV03()
|
||||||
bot.run()
|
bot.run()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,16 +84,24 @@ async def get_state():
|
||||||
pnl_status = "🟢 PROFIT" if pnl_usdt > 0.01 else ("🔴 LOSS" if pnl_usdt < -0.01 else "⚪ BREAK")
|
pnl_status = "🟢 PROFIT" if pnl_usdt > 0.01 else ("🔴 LOSS" if pnl_usdt < -0.01 else "⚪ BREAK")
|
||||||
pnl_color = "accent" if pnl_usdt > 0.01 else ("negative" if pnl_usdt < -0.01 else "neutral")
|
pnl_color = "accent" if pnl_usdt > 0.01 else ("negative" if pnl_usdt < -0.01 else "neutral")
|
||||||
|
|
||||||
# Count active positions = open orders from Binance API
|
# Count active positions from bot's active_trades.json (REAL source of truth)
|
||||||
|
active_positions = 0
|
||||||
try:
|
try:
|
||||||
open_orders = binance.get_open_orders()
|
import json
|
||||||
active_positions = len(open_orders)
|
with open('/home/marc/bot-deploy/active_trades.json', 'r') as f:
|
||||||
|
bot_state = json.load(f)
|
||||||
|
active_positions = bot_state.get('count', 0)
|
||||||
except:
|
except:
|
||||||
# Fallback to locked coins if API fails
|
# Fallback: count from Binance open orders
|
||||||
active_positions = 0
|
try:
|
||||||
for asset in ['BTC', 'ETH', 'SOL', 'BNB', 'XRP']:
|
open_orders = binance.get_open_orders()
|
||||||
if asset in balance and balance[asset]['locked'] > 0.00001:
|
active_positions = len(open_orders)
|
||||||
active_positions += 1
|
except:
|
||||||
|
# Last resort: count locked coins
|
||||||
|
active_positions = 0
|
||||||
|
for asset in ['BTC', 'ETH', 'SOL', 'BNB', 'XRP']:
|
||||||
|
if asset in balance and balance[asset]['locked'] > 0.00001:
|
||||||
|
active_positions += 1
|
||||||
|
|
||||||
trades = load_bot_state()
|
trades = load_bot_state()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue