Spaces:
Paused
Paused
| import streamlit as st | |
| import subprocess | |
| import os | |
| import signal | |
| import time | |
| from threading import Thread | |
| import requests | |
| # Set page config | |
| st.set_page_config( | |
| page_title="Scalping Bot Control", | |
| page_icon="π€", | |
| layout="wide" | |
| ) | |
| st.title("π€ Bybit Scalping Bot Control Panel") | |
| # Sidebar | |
| st.sidebar.header("βοΈ Configuration") | |
| # Environment variables setup | |
| st.sidebar.subheader("π API Configuration") | |
| bybit_key = st.sidebar.text_input("Bybit API Key", type="password") | |
| bybit_secret = st.sidebar.text_input("Bybit API Secret", type="password") | |
| bybit_testnet = st.sidebar.checkbox("Use Testnet", value=False) | |
| telegram_token = st.sidebar.text_input("Telegram Bot Token (optional)") | |
| telegram_chat = st.sidebar.text_input("Telegram Chat ID (optional)") | |
| if st.sidebar.button("πΎ Save Configuration"): | |
| # Save to .env file | |
| env_content = f"""BYBIT_API_KEY={bybit_key} | |
| BYBIT_API_SECRET={bybit_secret} | |
| BYBIT_TESTNET={str(bybit_testnet).lower()} | |
| TELEGRAM_BOT_TOKEN={telegram_token} | |
| TELEGRAM_CHAT_ID={telegram_chat} | |
| """ | |
| with open('.env', 'w') as f: | |
| f.write(env_content) | |
| st.sidebar.success("Configuration saved!") | |
| # Main content | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| st.subheader("π Start Trading") | |
| symbol = st.selectbox("Symbol", ["BTCUSDT", "ETHUSDT", "SOLUSDT"]) | |
| duration = st.slider("Duration (hours)", 1, 24, 18) | |
| max_trades = st.number_input("Max Trades (optional)", min_value=1, value=50) | |
| if st.button("βΆοΈ Start Trading", key="start"): | |
| try: | |
| response = requests.post(f"http://localhost:8000/start/{symbol}", | |
| params={"duration_hours": duration, "max_trades": max_trades}) | |
| if response.status_code == 200: | |
| st.success(f"β Started trading {symbol} for {duration} hours") | |
| else: | |
| st.error(f"β Failed to start: {response.text}") | |
| except Exception as e: | |
| st.error(f"β Error: {e}") | |
| with col2: | |
| st.subheader("π Stop Trading") | |
| stop_symbol = st.selectbox("Symbol to Stop", ["BTCUSDT", "ETHUSDT", "SOLUSDT"], key="stop_select") | |
| if st.button("βΉοΈ Stop Trading", key="stop"): | |
| try: | |
| response = requests.post(f"http://localhost:8000/stop/{stop_symbol}") | |
| if response.status_code == 200: | |
| st.success(f"β Stopped trading {stop_symbol}") | |
| else: | |
| st.error(f"β Failed to stop: {response.text}") | |
| except Exception as e: | |
| st.error(f"β Error: {e}") | |
| with col3: | |
| st.subheader("π¨ Emergency") | |
| if st.button("π¨ EMERGENCY STOP ALL", key="emergency"): | |
| try: | |
| response = requests.post("http://localhost:8000/emergency_stop") | |
| if response.status_code == 200: | |
| st.error("π¨ ALL TRADING STOPPED!") | |
| else: | |
| st.error(f"β Failed: {response.text}") | |
| except Exception as e: | |
| st.error(f"β Error: {e}") | |
| # Status section | |
| st.header("π Bot Status") | |
| if st.button("π Refresh Status"): | |
| try: | |
| response = requests.get("http://localhost:8000/status") | |
| if response.status_code == 200: | |
| status = response.json() | |
| # Overall status | |
| if status["is_running"]: | |
| st.success("β Bot is RUNNING") | |
| else: | |
| st.warning("βΈοΈ Bot is STOPPED") | |
| st.metric("Total P&L", f"${status['total_pnl']:.2f}") | |
| st.metric("Trades Today", status['trades_today']) | |
| # Active sessions | |
| if status["active_sessions"]: | |
| st.subheader("π― Active Sessions") | |
| for session in status["active_sessions"]: | |
| with st.expander(f"{session['symbol']} - {session['status'].upper()}"): | |
| st.write(f"**Session ID:** {session['session_id']}") | |
| st.write(f"**Started:** {session['start_time'][:19]}") | |
| st.write(f"**P&L:** ${session['pnl']:.2f}") | |
| st.write(f"**Trades:** {session['trades']}") | |
| else: | |
| st.info("No active sessions") | |
| else: | |
| st.error(f"β Failed to get status: {response.status_code}") | |
| except Exception as e: | |
| st.error(f"β Connection error: {e}") | |
| # Analysis section | |
| st.header("π Live Analysis") | |
| if st.button("π Refresh Analysis"): | |
| try: | |
| response = requests.get("http://localhost:8000/analysis/status") | |
| if response.status_code == 200: | |
| analysis = response.json() | |
| for symbol, data in analysis["analysis_status"].items(): | |
| with st.expander(f"π {symbol} Analysis"): | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.metric("Current Price", f"${data['current_price']:.2f}" if data['current_price'] else "N/A") | |
| indicators = data['indicators'] | |
| st.write("**Indicators:**") | |
| st.write(f"EMA 9: {indicators['ema_9']:.4f}" if indicators['ema_9'] else "EMA 9: N/A") | |
| st.write(f"EMA 21: {indicators['ema_21']:.4f}" if indicators['ema_21'] else "EMA 21: N/A") | |
| st.write(f"RSI 14: {indicators['rsi_14']:.1f}" if indicators['rsi_14'] else "RSI 14: N/A") | |
| with col2: | |
| conditions = data['strategy_conditions'] | |
| st.write("**Strategy Conditions:**") | |
| st.write(f"π Trend Up: {'β ' if conditions['trend_up'] else 'β'}") | |
| st.write(f"π RSI Valid: {'β ' if conditions['rsi_valid'] else 'β'}") | |
| st.write(f"π₯ Volume Spike: {'β ' if conditions['volume_spike'] else 'β'}") | |
| st.write(f"π― Orderbook OK: {'β ' if conditions['orderbook_aligned'] else 'β'}") | |
| all_conditions = all([conditions['trend_up'], conditions['rsi_valid'], | |
| conditions['volume_spike'], conditions['orderbook_aligned']]) | |
| if all_conditions: | |
| st.success("π― TRADE SIGNAL READY!") | |
| else: | |
| st.info("β³ Waiting for conditions...") | |
| else: | |
| st.error(f"β Failed to get analysis: {response.status_code}") | |
| except Exception as e: | |
| st.error(f"β Connection error: {e}") | |
| # Logs section | |
| st.header("π Recent Logs") | |
| log_type = st.selectbox("Log Type", ["Live Logs", "Analysis Logs"]) | |
| if st.button("π Refresh Logs"): | |
| try: | |
| if log_type == "Live Logs": | |
| response = requests.get("http://localhost:8000/logs/live") | |
| else: | |
| response = requests.get("http://localhost:8000/logs/analysis") | |
| if response.status_code == 200: | |
| logs_data = response.json() | |
| st.write(f"**Total {log_type}:** {logs_data['count']}") | |
| logs_text = "" | |
| for log_line in logs_data['logs'][-10:]: # Show last 10 | |
| logs_text += log_line | |
| st.code(logs_text, language="text") | |
| else: | |
| st.error(f"β Failed to get logs: {response.status_code}") | |
| except Exception as e: | |
| st.error(f"β Connection error: {e}") | |
| # Footer | |
| st.markdown("---") | |
| st.markdown("*π€ Bybit Scalping Bot - FastAPI Control Interface*") | |
| st.markdown("*Made with β€οΈ for automated crypto trading*") | |