100 lines
3.0 KiB
Python
100 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Bot Persistence & Auto-Recovery System
|
|
- Saves all trades to persistent storage (JSON)
|
|
- On restart: Loads all trades + binance positions
|
|
- Dashboard syncs with persistent storage
|
|
- Bot operates autonomously even after restart
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, '/home/marc/bot-deploy')
|
|
|
|
# Paths
|
|
TRADES_FILE = '/home/marc/bot-deploy/data/trades_persistent.json'
|
|
BOT_STATE_FILE = '/home/marc/bot-deploy/data/bot_state.json'
|
|
DATA_DIR = '/home/marc/bot-deploy/data'
|
|
|
|
# Ensure data directory exists
|
|
os.makedirs(DATA_DIR, exist_ok=True)
|
|
|
|
def init_persistence():
|
|
"""Initialize persistence files if they don't exist"""
|
|
if not os.path.exists(TRADES_FILE):
|
|
with open(TRADES_FILE, 'w') as f:
|
|
json.dump({
|
|
'current_trades': {},
|
|
'completed_trades': [],
|
|
'swaps': []
|
|
}, f, indent=2)
|
|
|
|
if not os.path.exists(BOT_STATE_FILE):
|
|
with open(BOT_STATE_FILE, 'w') as f:
|
|
json.dump({
|
|
'last_restart': None,
|
|
'total_capital_deployed': 0.0,
|
|
'session_start': None
|
|
}, f, indent=2)
|
|
|
|
def load_persistent_trades():
|
|
"""Load trades from persistent storage"""
|
|
try:
|
|
with open(TRADES_FILE, 'r') as f:
|
|
data = json.load(f)
|
|
return data.get('current_trades', {}), data.get('completed_trades', []), data.get('swaps', [])
|
|
except:
|
|
return {}, [], []
|
|
|
|
def save_persistent_trades(current_trades, completed_trades, swaps):
|
|
"""Save trades to persistent storage"""
|
|
data = {
|
|
'current_trades': current_trades,
|
|
'completed_trades': completed_trades,
|
|
'swaps': swaps
|
|
}
|
|
with open(TRADES_FILE, 'w') as f:
|
|
json.dump(data, f, indent=2)
|
|
|
|
def load_binance_positions_on_startup():
|
|
"""Load current open positions from Binance on startup"""
|
|
from src.bot.binance_client import BinanceClient
|
|
import asyncio
|
|
|
|
async def _load():
|
|
client = BinanceClient()
|
|
positions = {}
|
|
|
|
# Get account balances
|
|
balances = await client.get_balance()
|
|
|
|
# Scan for open positions (non-zero balances excluding USDT)
|
|
for symbol, amount in balances.items():
|
|
if symbol != 'USDT' and amount > 0.00001:
|
|
# Get current price for this asset
|
|
price = await client.get_price(f'{symbol}USDT')
|
|
positions[f'{symbol}USDT'] = {
|
|
'qty': amount,
|
|
'buy_price': price, # Current price as reference
|
|
'entry_time': None, # Lost on restart
|
|
'status': 'open'
|
|
}
|
|
print(f'✅ Loaded from Binance: {symbol}USDT - Qty: {amount} @ ${price}')
|
|
|
|
return positions
|
|
|
|
try:
|
|
loop = asyncio.get_event_loop()
|
|
except:
|
|
loop = asyncio.new_event_loop()
|
|
asyncio.set_event_loop(loop)
|
|
|
|
return loop.run_until_complete(_load())
|
|
|
|
# Initialize on import
|
|
init_persistence()
|
|
|
|
print('✅ Persistence module initialized')
|