Spaces:
Paused
Paused
| # π Deploy Scalping Bot on Hugging Face Spaces | |
| ## Prerequisites | |
| 1. **Hugging Face Account**: Create account at [huggingface.co](https://huggingface.co) | |
| 2. **API Credentials**: Your Bybit API keys ready | |
| 3. **Git Repository**: Push your code to GitHub/GitLab | |
| ## Step 1: Create Hugging Face Space | |
| 1. Go to [huggingface.co/spaces](https://huggingface.co/spaces) | |
| 2. Click "Create new Space" | |
| 3. Choose: | |
| - **Space name**: `your-scalping-bot` | |
| - **License**: Apache-2.0 | |
| - **SDK**: **Docker** (for full control) | |
| - **Storage**: Small (sufficient) | |
| ## Step 2: Repository Structure | |
| Your repository should look like: | |
| ``` | |
| your-scalping-bot/ | |
| βββ app.py # Streamlit/FastAPI app | |
| βββ requirements.txt # Dependencies | |
| βββ packages.txt # System packages (if needed) | |
| βββ config/ | |
| β βββ settings.yaml | |
| β βββ pairs.yaml | |
| βββ core/ | |
| β βββ exchange.py | |
| β βββ strategy.py | |
| β βββ ... | |
| βββ services/ | |
| β βββ ... | |
| βββ README.md | |
| ``` | |
| ## Step 3: Create app.py | |
| ```python | |
| 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*") | |
| ``` | |
| ## Step 4: Create requirements.txt | |
| ```txt | |
| fastapi==0.104.1 | |
| uvicorn[standard]==0.24.0 | |
| streamlit==1.28.1 | |
| requests==2.31.0 | |
| python-dotenv==1.0.0 | |
| pybit==5.7.0 | |
| pyyaml==6.0.1 | |
| pandas==2.1.3 | |
| numpy==1.26.2 | |
| websockets==12.0 | |
| ``` | |
| ## Step 5: Create packages.txt (Optional) | |
| ``` | |
| # No system packages needed | |
| ``` | |
| ## Step 6: Deploy to Hugging Face | |
| 1. **Push to Git**: Commit and push your code to a Git repository | |
| 2. **Connect Space**: In your Hugging Face Space settings: | |
| - Go to "Settings" β "Connect Repository" | |
| - Enter your repository URL | |
| - Set branch to `main` | |
| 3. **Auto-deploy**: Hugging Face will automatically build and deploy | |
| ## Step 7: Access Your Bot | |
| Once deployed, you'll get a public URL like: | |
| ``` | |
| https://yourusername-your-scalping-bot.hf.space | |
| ``` | |
| This will be your **public IP/URL** for accessing the bot remotely! | |
| ## Step 8: Start the Bot | |
| In your Hugging Face Space: | |
| 1. β Configure API keys in the sidebar | |
| 2. β Click "Start Trading" for your desired pairs | |
| 3. β Monitor analysis in real-time | |
| 4. β View logs and performance | |
| ## π Security Notes | |
| - **Never expose real API keys** in public repositories | |
| - **Use environment variables** for sensitive data | |
| - **Consider IP restrictions** on your Bybit API keys | |
| - **Monitor your bot regularly** via the web interface | |
| ## π Public Access | |
| Your bot will be accessible worldwide via: | |
| ``` | |
| https://[your-username]-[space-name].hf.space | |
| ``` | |
| This serves as your **public IP address** for remote access! | |
| ## π‘ Usage Examples | |
| ```bash | |
| # Direct API calls (replace with your HF Space URL) | |
| curl -X POST "https://your-bot.hf.space/start/BTCUSDT" | |
| curl "https://your-bot.hf.space/status" | |
| curl "https://your-bot.hf.space/analysis/status" | |
| ``` | |
| ## π You're Done! | |
| Your scalping bot is now hosted on Hugging Face with: | |
| - π **Public web interface** | |
| - π **Real-time analysis dashboard** | |
| - ποΈ **Remote control via API** | |
| - π± **Mobile-friendly interface** | |
| **Happy trading!** ππ€ | |