feat: Add /status command to Telegram bot for position monitoring
- Implemented /status command handler in telegram_command_bot.py - Shows real-time P&L, entry/current prices, TP/SL levels, position info - Added TRADING_BOT_URL and API_SECRET_KEY environment variables - Updated docker-compose.telegram-bot.yml with new env vars - Bot connects to trading-bot-v4:3000 API via internal Docker network - Added comprehensive documentation and testing guides - Command displays formatted position info with emojis (profit/loss indicators) - Shows 'No open positions' message when no trades active
This commit is contained in:
@@ -9,3 +9,9 @@ N8N_WEBHOOK_URL=https://flow.egonetix.de/webhook/3371ad7c-0866-4161-90a4-f251de4
|
|||||||
|
|
||||||
# Your Telegram chat ID (already set to 579304651)
|
# Your Telegram chat ID (already set to 579304651)
|
||||||
TELEGRAM_CHAT_ID=579304651
|
TELEGRAM_CHAT_ID=579304651
|
||||||
|
|
||||||
|
# Trading Bot API URL (internal Docker network)
|
||||||
|
TRADING_BOT_URL=http://trading-bot-v4:3000
|
||||||
|
|
||||||
|
# API Secret Key (same as in main .env file)
|
||||||
|
API_SECRET_KEY=2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb
|
||||||
|
|||||||
66
STATUS_COMMAND_QUICKREF.txt
Normal file
66
STATUS_COMMAND_QUICKREF.txt
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
╔════════════════════════════════════════════════════════════════╗
|
||||||
|
║ TELEGRAM /status COMMAND ║
|
||||||
|
║ ✅ READY TO USE ║
|
||||||
|
╚════════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
📱 HOW TO USE
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
1. Open your Telegram bot chat
|
||||||
|
2. Send: /status
|
||||||
|
3. Get instant position info!
|
||||||
|
|
||||||
|
📊 WHAT YOU'LL SEE
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
✅ Current P&L ($ and % of account)
|
||||||
|
✅ Entry price & current price
|
||||||
|
✅ TP1, TP2, and SL levels with status
|
||||||
|
✅ Position size & leverage
|
||||||
|
✅ Trade age in minutes
|
||||||
|
|
||||||
|
🎯 EXAMPLE OUTPUT
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
🟢 SOL-PERP 📈 LONG
|
||||||
|
|
||||||
|
💰 P&L: $3.50 (+0.70% account)
|
||||||
|
📊 Price Change: +0.07%
|
||||||
|
|
||||||
|
Entry: $142.5000
|
||||||
|
Current: $142.6000
|
||||||
|
|
||||||
|
Targets:
|
||||||
|
TP1: $143.4975 ⏳
|
||||||
|
TP2: $144.6375
|
||||||
|
SL: $140.3625
|
||||||
|
|
||||||
|
Position: $500.00 @ 10x
|
||||||
|
Age: 5 min
|
||||||
|
|
||||||
|
🔧 TECHNICAL STATUS
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
✅ Container: telegram-trade-bot (Running)
|
||||||
|
✅ Network: Connected to trading-bot-v4
|
||||||
|
✅ API: Authenticated & tested
|
||||||
|
✅ Command: /status handler active
|
||||||
|
|
||||||
|
📝 ALL COMMANDS
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
/status → Show current position
|
||||||
|
/buySOL → Long SOL
|
||||||
|
/sellSOL → Short SOL
|
||||||
|
/buyBTC → Long BTC
|
||||||
|
/sellBTC → Short BTC
|
||||||
|
/buyETH → Long ETH
|
||||||
|
/sellETH → Short ETH
|
||||||
|
|
||||||
|
🔐 SECURITY
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
✅ Only works in YOUR chat (579304651)
|
||||||
|
✅ API authentication required
|
||||||
|
✅ Internal Docker network
|
||||||
|
✅ No internet exposure
|
||||||
|
|
||||||
|
🎉 READY!
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
Open Telegram and send /status to try it now!
|
||||||
|
|
||||||
|
Next: Open a position, then check /status to see it in action! 🚀
|
||||||
@@ -26,6 +26,34 @@ Paste your bot token when asked.
|
|||||||
|
|
||||||
## 📱 Using it on your phone
|
## 📱 Using it on your phone
|
||||||
|
|
||||||
|
### Check Position Status
|
||||||
|
Send `/status` to see your current open position with:
|
||||||
|
- Real-time P&L (both $ amount and % of account)
|
||||||
|
- Entry price and current price
|
||||||
|
- TP1, TP2, and SL levels with status indicators
|
||||||
|
- Position size and leverage
|
||||||
|
- Trade age in minutes
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
```
|
||||||
|
🟢 SOL-PERP 📈 LONG
|
||||||
|
|
||||||
|
💰 P&L: $3.50 (+0.70% account)
|
||||||
|
📊 Price Change: +0.07%
|
||||||
|
|
||||||
|
Entry: $142.5000
|
||||||
|
Current: $142.6000
|
||||||
|
|
||||||
|
Targets:
|
||||||
|
TP1: $143.4975 ⏳
|
||||||
|
TP2: $144.6375
|
||||||
|
SL: $140.3625
|
||||||
|
|
||||||
|
Position: $500.00 @ 10x
|
||||||
|
Age: 5 min
|
||||||
|
```
|
||||||
|
|
||||||
|
### Execute Trades
|
||||||
Just send messages to your Telegram chat:
|
Just send messages to your Telegram chat:
|
||||||
```
|
```
|
||||||
buy sol
|
buy sol
|
||||||
@@ -34,6 +62,14 @@ buy eth
|
|||||||
sell sol
|
sell sol
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or use commands:
|
||||||
|
```
|
||||||
|
/buySOL
|
||||||
|
/sellBTC
|
||||||
|
/buyETH
|
||||||
|
/status
|
||||||
|
```
|
||||||
|
|
||||||
The bot will:
|
The bot will:
|
||||||
1. ✅ Parse your message
|
1. ✅ Parse your message
|
||||||
2. ✅ Forward to n8n webhook
|
2. ✅ Forward to n8n webhook
|
||||||
|
|||||||
172
TELEGRAM_STATUS_IMPLEMENTATION.md
Normal file
172
TELEGRAM_STATUS_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
# Telegram /status Command - Implementation Summary
|
||||||
|
|
||||||
|
## ✅ **Feature Complete**
|
||||||
|
|
||||||
|
You can now send `/status` in your Telegram channel to get real-time information about your open position on Drift Protocol.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 What You'll See
|
||||||
|
|
||||||
|
### When No Position Is Open:
|
||||||
|
```
|
||||||
|
📊 No open positions
|
||||||
|
|
||||||
|
All clear! Ready for new signals.
|
||||||
|
```
|
||||||
|
|
||||||
|
### When You Have an Open Position:
|
||||||
|
```
|
||||||
|
🟢 SOL-PERP 📈 LONG
|
||||||
|
|
||||||
|
💰 P&L: $3.50 (+0.70% account)
|
||||||
|
📊 Price Change: +0.07%
|
||||||
|
|
||||||
|
Entry: $142.5000
|
||||||
|
Current: $142.6000
|
||||||
|
|
||||||
|
Targets:
|
||||||
|
TP1: $143.4975 ✅ (if hit)
|
||||||
|
TP2: $144.6375 ⏳
|
||||||
|
SL: $140.3625
|
||||||
|
|
||||||
|
Position: $500.00 @ 10x
|
||||||
|
Age: 5 min
|
||||||
|
```
|
||||||
|
|
||||||
|
### Legend:
|
||||||
|
- 🟢 = Profit | 🔴 = Loss | ⚪ = Breakeven
|
||||||
|
- 📈 = Long | 📉 = Short
|
||||||
|
- ✅ = Target hit | ⏳ = Pending
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 How to Use
|
||||||
|
|
||||||
|
1. Open your Telegram bot chat
|
||||||
|
2. Send: `/status`
|
||||||
|
3. Get instant position info!
|
||||||
|
|
||||||
|
You can send it anytime - while trading, after hours, whenever you want to check your position.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 What Changed
|
||||||
|
|
||||||
|
### Files Modified:
|
||||||
|
1. **`telegram_command_bot.py`**
|
||||||
|
- Added `status_command()` function
|
||||||
|
- Fetches data from trading bot API
|
||||||
|
- Formats beautiful status messages
|
||||||
|
|
||||||
|
2. **`docker-compose.telegram-bot.yml`**
|
||||||
|
- Added `TRADING_BOT_URL` environment variable
|
||||||
|
- Added `API_SECRET_KEY` environment variable
|
||||||
|
|
||||||
|
3. **`.env.telegram-bot`**
|
||||||
|
- Added trading bot URL (internal Docker network)
|
||||||
|
- Added API secret key for authentication
|
||||||
|
|
||||||
|
### New Environment Variables:
|
||||||
|
```bash
|
||||||
|
TRADING_BOT_URL=http://trading-bot-v4:3000
|
||||||
|
API_SECRET_KEY=2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Verification
|
||||||
|
|
||||||
|
**Container Status:**
|
||||||
|
```bash
|
||||||
|
docker ps | grep telegram-trade-bot
|
||||||
|
# Output: Up About a minute
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bot Logs:**
|
||||||
|
```bash
|
||||||
|
docker logs telegram-trade-bot --tail 10
|
||||||
|
# Shows: ✅ Commands: /status - Show open positions
|
||||||
|
```
|
||||||
|
|
||||||
|
**API Connectivity Test:**
|
||||||
|
```bash
|
||||||
|
docker exec telegram-trade-bot python3 -c "import requests; r=requests.get('http://trading-bot-v4:3000/api/trading/positions', headers={'Authorization': 'Bearer 2a344f0149442c857fb56c038c0c7d1b113883b830bec792c76f1e0efa15d6bb'}); print(r.status_code)"
|
||||||
|
# Output: 200 ✅
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Live Example Use Cases
|
||||||
|
|
||||||
|
### Morning Check:
|
||||||
|
```
|
||||||
|
You: /status
|
||||||
|
Bot: 🟢 SOL-PERP 📈 LONG
|
||||||
|
💰 P&L: $8.25 (+1.65% account)
|
||||||
|
TP1: $143.50 ✅
|
||||||
|
Runner position active!
|
||||||
|
```
|
||||||
|
|
||||||
|
### During Volatile Move:
|
||||||
|
```
|
||||||
|
You: /status
|
||||||
|
Bot: 🔴 SOL-PERP 📈 LONG
|
||||||
|
💰 P&L: -$3.75 (-0.75% account)
|
||||||
|
Current: $141.80
|
||||||
|
SL: $140.36 (still safe!)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Times Per Day:
|
||||||
|
- Check before meetings
|
||||||
|
- Monitor during lunch
|
||||||
|
- Quick check before bed
|
||||||
|
- Anytime you're curious!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Security
|
||||||
|
|
||||||
|
✅ **Only works in YOUR Telegram chat** (TELEGRAM_CHAT_ID=579304651)
|
||||||
|
✅ **Requires API authentication** (API_SECRET_KEY)
|
||||||
|
✅ **Internal Docker network** (not exposed to internet)
|
||||||
|
✅ **Same security as main trading bot**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Available Commands
|
||||||
|
|
||||||
|
Your Telegram bot now supports:
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `/status` | Show current open position |
|
||||||
|
| `/buySOL` | Open long SOL position |
|
||||||
|
| `/sellSOL` | Open short SOL position |
|
||||||
|
| `/buyBTC` | Open long BTC position |
|
||||||
|
| `/sellBTC` | Open short BTC position |
|
||||||
|
| `/buyETH` | Open long ETH position |
|
||||||
|
| `/sellETH` | Open short ETH position |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎉 Ready to Use!
|
||||||
|
|
||||||
|
Your Telegram bot is running and ready. Just send `/status` to try it out!
|
||||||
|
|
||||||
|
**Container:** `telegram-trade-bot` ✅ Running
|
||||||
|
**Network:** Connected to `trading-bot-v4` ✅
|
||||||
|
**API:** Authenticated and tested ✅
|
||||||
|
**Commands:** `/status` handler active ✅
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Documentation Updated
|
||||||
|
|
||||||
|
- ✅ `TELEGRAM_BOT_README.md` - Updated with /status usage
|
||||||
|
- ✅ `TEST_STATUS_COMMAND.md` - Testing guide
|
||||||
|
- ✅ `TELEGRAM_STATUS_IMPLEMENTATION.md` - This file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Next time you open a position, send `/status` to see it in action!** 🚀
|
||||||
110
TEST_STATUS_COMMAND.md
Normal file
110
TEST_STATUS_COMMAND.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# Testing the /status Command
|
||||||
|
|
||||||
|
## ✅ Feature Implemented
|
||||||
|
|
||||||
|
The Telegram bot now supports the `/status` command to show current open positions.
|
||||||
|
|
||||||
|
## What It Shows
|
||||||
|
|
||||||
|
When you send `/status` in your Telegram chat, you'll receive:
|
||||||
|
|
||||||
|
### If No Positions Are Open:
|
||||||
|
```
|
||||||
|
📊 No open positions
|
||||||
|
|
||||||
|
All clear! Ready for new signals.
|
||||||
|
```
|
||||||
|
|
||||||
|
### If Position Is Open:
|
||||||
|
```
|
||||||
|
🟢 SOL-PERP 📈 LONG
|
||||||
|
|
||||||
|
💰 P&L: $3.50 (+0.70% account)
|
||||||
|
📊 Price Change: +0.07%
|
||||||
|
|
||||||
|
Entry: $142.5000
|
||||||
|
Current: $142.6000
|
||||||
|
|
||||||
|
Targets:
|
||||||
|
TP1: $143.4975 ⏳
|
||||||
|
TP2: $144.6375
|
||||||
|
SL: $140.3625
|
||||||
|
|
||||||
|
Position: $500.00 @ 10x
|
||||||
|
Age: 5 min
|
||||||
|
```
|
||||||
|
|
||||||
|
### Emojis Used:
|
||||||
|
- 🟢 Green = Position in profit
|
||||||
|
- 🔴 Red = Position in loss
|
||||||
|
- ⚪ White = Breakeven
|
||||||
|
- 📈 = Long position
|
||||||
|
- 📉 = Short position
|
||||||
|
- ✅ = Target hit
|
||||||
|
- ⏳ = Target pending
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
### How It Works:
|
||||||
|
1. User sends `/status` in Telegram
|
||||||
|
2. Bot calls `GET /api/trading/positions` on trading-bot-v4:3000
|
||||||
|
3. Bot parses response and formats position data
|
||||||
|
4. Bot sends formatted message back to user
|
||||||
|
|
||||||
|
### Files Modified:
|
||||||
|
- `telegram_command_bot.py` - Added `status_command()` handler
|
||||||
|
- `docker-compose.telegram-bot.yml` - Added environment variables
|
||||||
|
- `.env.telegram-bot` - Added `TRADING_BOT_URL` and `API_SECRET_KEY`
|
||||||
|
|
||||||
|
### Environment Variables Required:
|
||||||
|
```bash
|
||||||
|
TRADING_BOT_URL=http://trading-bot-v4:3000
|
||||||
|
API_SECRET_KEY=<same as main .env file>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### 1. Test from Terminal (API):
|
||||||
|
```bash
|
||||||
|
curl -H "Authorization: Bearer YOUR_API_SECRET_KEY" \
|
||||||
|
http://localhost:3001/api/trading/positions | jq .
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Test from Telegram:
|
||||||
|
- Open your Telegram bot chat
|
||||||
|
- Send: `/status`
|
||||||
|
- Should receive position info or "No open positions"
|
||||||
|
|
||||||
|
### 3. Test with Active Position:
|
||||||
|
- Execute a test trade first:
|
||||||
|
- Send `/buySOL` or use settings page "Test LONG"
|
||||||
|
- Then send `/status`
|
||||||
|
- Should see full position details
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
✅ Container running:
|
||||||
|
```bash
|
||||||
|
docker ps | grep telegram-trade-bot
|
||||||
|
```
|
||||||
|
|
||||||
|
✅ Logs showing /status handler:
|
||||||
|
```bash
|
||||||
|
docker logs telegram-trade-bot --tail 20
|
||||||
|
```
|
||||||
|
|
||||||
|
✅ Network connectivity:
|
||||||
|
```bash
|
||||||
|
docker exec telegram-trade-bot python3 -c "import requests; r=requests.get('http://trading-bot-v4:3000/api/trading/positions', headers={'Authorization': 'Bearer YOUR_KEY'}); print(r.status_code)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Should output: `200`
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
You can now monitor your positions in real-time from your phone!
|
||||||
|
|
||||||
|
Just send `/status` anytime to check:
|
||||||
|
- Current P&L
|
||||||
|
- How close you are to TP/SL
|
||||||
|
- How long the trade has been open
|
||||||
@@ -14,6 +14,8 @@ services:
|
|||||||
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
|
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
|
||||||
- N8N_WEBHOOK_URL=${N8N_WEBHOOK_URL}
|
- N8N_WEBHOOK_URL=${N8N_WEBHOOK_URL}
|
||||||
- TELEGRAM_CHAT_ID=579304651
|
- TELEGRAM_CHAT_ID=579304651
|
||||||
|
- TRADING_BOT_URL=${TRADING_BOT_URL:-http://trading-bot-v4:3000}
|
||||||
|
- API_SECRET_KEY=${API_SECRET_KEY}
|
||||||
networks:
|
networks:
|
||||||
- traderv4_trading-net
|
- traderv4_trading-net
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,94 @@ from telegram.ext import Application, CommandHandler, ContextTypes
|
|||||||
# Configuration
|
# Configuration
|
||||||
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
|
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
|
||||||
N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL')
|
N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL')
|
||||||
|
TRADING_BOT_URL = os.getenv('TRADING_BOT_URL', 'http://trading-bot-v4:3000')
|
||||||
|
API_SECRET_KEY = os.getenv('API_SECRET_KEY', '')
|
||||||
ALLOWED_CHAT_ID = int(os.getenv('TELEGRAM_CHAT_ID', '579304651'))
|
ALLOWED_CHAT_ID = int(os.getenv('TELEGRAM_CHAT_ID', '579304651'))
|
||||||
|
|
||||||
|
async def status_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
"""Handle /status command - show current open positions"""
|
||||||
|
|
||||||
|
# Only process from YOUR chat
|
||||||
|
if update.message.chat_id != ALLOWED_CHAT_ID:
|
||||||
|
await update.message.reply_text("❌ Unauthorized")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"📊 /status command received", flush=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Fetch positions from trading bot API
|
||||||
|
response = requests.get(
|
||||||
|
f"{TRADING_BOT_URL}/api/trading/positions",
|
||||||
|
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"📥 API Response: {response.status_code}", flush=True)
|
||||||
|
|
||||||
|
if not response.ok:
|
||||||
|
await update.message.reply_text(f"❌ Error fetching positions: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if not data.get('success'):
|
||||||
|
await update.message.reply_text("❌ Failed to fetch positions")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if there are active positions
|
||||||
|
positions = data.get('positions', [])
|
||||||
|
|
||||||
|
if not positions:
|
||||||
|
await update.message.reply_text("📊 *No open positions*\n\nAll clear! Ready for new signals.", parse_mode='Markdown')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Format position information
|
||||||
|
for pos in positions:
|
||||||
|
symbol = pos['symbol']
|
||||||
|
direction = pos['direction'].upper()
|
||||||
|
entry = pos['entryPrice']
|
||||||
|
current = pos['currentPrice']
|
||||||
|
size = pos['currentSize']
|
||||||
|
leverage = pos['leverage']
|
||||||
|
|
||||||
|
# P&L
|
||||||
|
pnl_pct = pos['profitPercent']
|
||||||
|
account_pnl = pos['accountPnL']
|
||||||
|
unrealized_pnl = pos['unrealizedPnL']
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
sl = pos['stopLoss']
|
||||||
|
tp1 = pos['takeProfit1']
|
||||||
|
tp2 = pos['takeProfit2']
|
||||||
|
tp1_hit = pos['tp1Hit']
|
||||||
|
|
||||||
|
# Age
|
||||||
|
age_min = pos['ageMinutes']
|
||||||
|
|
||||||
|
# Build status message
|
||||||
|
emoji = "🟢" if account_pnl > 0 else "🔴" if account_pnl < 0 else "⚪"
|
||||||
|
direction_emoji = "📈" if direction == "LONG" else "📉"
|
||||||
|
|
||||||
|
message = f"{emoji} *{symbol}* {direction_emoji} {direction}\n\n"
|
||||||
|
message += f"💰 *P&L:* ${unrealized_pnl:.2f} ({account_pnl:+.2f}% account)\n"
|
||||||
|
message += f"📊 *Price Change:* {pnl_pct:+.2f}%\n\n"
|
||||||
|
message += f"*Entry:* ${entry:.4f}\n"
|
||||||
|
message += f"*Current:* ${current:.4f}\n\n"
|
||||||
|
message += f"*Targets:*\n"
|
||||||
|
message += f" TP1: ${tp1:.4f} {'✅' if tp1_hit else '⏳'}\n"
|
||||||
|
message += f" TP2: ${tp2:.4f}\n"
|
||||||
|
message += f" SL: ${sl:.4f}\n\n"
|
||||||
|
message += f"*Position:* ${size:.2f} @ {leverage}x\n"
|
||||||
|
message += f"*Age:* {age_min} min"
|
||||||
|
|
||||||
|
await update.message.reply_text(message, parse_mode='Markdown')
|
||||||
|
|
||||||
|
print(f"✅ Status sent: {len(positions)} position(s)", flush=True)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error: {e}", flush=True)
|
||||||
|
await update.message.reply_text(f"❌ Error: {str(e)}")
|
||||||
|
|
||||||
async def trade_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def trade_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
"""Handle trade commands like /buySOL, /sellBTC, etc."""
|
"""Handle trade commands like /buySOL, /sellBTC, etc."""
|
||||||
|
|
||||||
@@ -72,7 +158,9 @@ def main():
|
|||||||
print(f"🚀 Telegram Trade Bot Starting...", flush=True)
|
print(f"🚀 Telegram Trade Bot Starting...", flush=True)
|
||||||
print(f"📱 Allowed Chat ID: {ALLOWED_CHAT_ID}", flush=True)
|
print(f"📱 Allowed Chat ID: {ALLOWED_CHAT_ID}", flush=True)
|
||||||
print(f"🔗 Webhook: {N8N_WEBHOOK_URL}", flush=True)
|
print(f"🔗 Webhook: {N8N_WEBHOOK_URL}", flush=True)
|
||||||
|
print(f"🤖 Trading Bot: {TRADING_BOT_URL}", flush=True)
|
||||||
print(f"\n✅ Commands:", flush=True)
|
print(f"\n✅ Commands:", flush=True)
|
||||||
|
print(f" /status - Show open positions", flush=True)
|
||||||
print(f" /buySOL, /sellSOL", flush=True)
|
print(f" /buySOL, /sellSOL", flush=True)
|
||||||
print(f" /buyBTC, /sellBTC", flush=True)
|
print(f" /buyBTC, /sellBTC", flush=True)
|
||||||
print(f" /buyETH, /sellETH", flush=True)
|
print(f" /buyETH, /sellETH", flush=True)
|
||||||
@@ -81,6 +169,7 @@ def main():
|
|||||||
application = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
|
application = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
|
||||||
|
|
||||||
# Add command handlers
|
# Add command handlers
|
||||||
|
application.add_handler(CommandHandler("status", status_command))
|
||||||
application.add_handler(CommandHandler("buySOL", trade_command))
|
application.add_handler(CommandHandler("buySOL", trade_command))
|
||||||
application.add_handler(CommandHandler("sellSOL", trade_command))
|
application.add_handler(CommandHandler("sellSOL", trade_command))
|
||||||
application.add_handler(CommandHandler("buyBTC", trade_command))
|
application.add_handler(CommandHandler("buyBTC", trade_command))
|
||||||
|
|||||||
@@ -7,13 +7,96 @@ Run: python3 telegram_trade_bot.py
|
|||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
from telegram import Update
|
from telegram import Update
|
||||||
from telegram.ext import Application, MessageHandler, filters, ContextTypes
|
from telegram.ext import Application, MessageHandler, CommandHandler, filters, ContextTypes
|
||||||
|
|
||||||
# Configuration - SET THESE!
|
# Configuration - SET THESE!
|
||||||
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', 'YOUR_BOT_TOKEN_HERE')
|
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', 'YOUR_BOT_TOKEN_HERE')
|
||||||
N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL', 'https://your-n8n.com/webhook/manual-trade')
|
N8N_WEBHOOK_URL = os.getenv('N8N_WEBHOOK_URL', 'https://your-n8n.com/webhook/manual-trade')
|
||||||
|
TRADING_BOT_URL = os.getenv('TRADING_BOT_URL', 'http://trading-bot-v4:3000')
|
||||||
|
API_SECRET_KEY = os.getenv('API_SECRET_KEY', '')
|
||||||
ALLOWED_CHAT_ID = int(os.getenv('TELEGRAM_CHAT_ID', '579304651'))
|
ALLOWED_CHAT_ID = int(os.getenv('TELEGRAM_CHAT_ID', '579304651'))
|
||||||
|
|
||||||
|
async def handle_status_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
"""Handle /status command - show current open positions"""
|
||||||
|
|
||||||
|
# Only your chat
|
||||||
|
if update.message.chat_id != ALLOWED_CHAT_ID:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"📊 /status command received")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Fetch positions from trading bot API
|
||||||
|
response = requests.get(
|
||||||
|
f"{TRADING_BOT_URL}/api/trading/positions",
|
||||||
|
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if not response.ok:
|
||||||
|
await update.message.reply_text(f"❌ Error fetching positions: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if not data.get('success'):
|
||||||
|
await update.message.reply_text("❌ Failed to fetch positions")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if there are active positions
|
||||||
|
positions = data.get('positions', [])
|
||||||
|
|
||||||
|
if not positions:
|
||||||
|
await update.message.reply_text("📊 *No open positions*\n\nAll clear! Ready for new signals.", parse_mode='Markdown')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Format position information
|
||||||
|
for pos in positions:
|
||||||
|
symbol = pos['symbol']
|
||||||
|
direction = pos['direction'].upper()
|
||||||
|
entry = pos['entryPrice']
|
||||||
|
current = pos['currentPrice']
|
||||||
|
size = pos['currentSize']
|
||||||
|
leverage = pos['leverage']
|
||||||
|
|
||||||
|
# P&L
|
||||||
|
pnl_pct = pos['profitPercent']
|
||||||
|
account_pnl = pos['accountPnL']
|
||||||
|
unrealized_pnl = pos['unrealizedPnL']
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
sl = pos['stopLoss']
|
||||||
|
tp1 = pos['takeProfit1']
|
||||||
|
tp2 = pos['takeProfit2']
|
||||||
|
tp1_hit = pos['tp1Hit']
|
||||||
|
|
||||||
|
# Age
|
||||||
|
age_min = pos['ageMinutes']
|
||||||
|
|
||||||
|
# Build status message
|
||||||
|
emoji = "🟢" if account_pnl > 0 else "🔴" if account_pnl < 0 else "⚪"
|
||||||
|
direction_emoji = "📈" if direction == "LONG" else "📉"
|
||||||
|
|
||||||
|
message = f"{emoji} *{symbol}* {direction_emoji} {direction}\n\n"
|
||||||
|
message += f"💰 *P&L:* ${unrealized_pnl:.2f} ({account_pnl:+.2f}% account)\n"
|
||||||
|
message += f"📊 *Price Change:* {pnl_pct:+.2f}%\n\n"
|
||||||
|
message += f"*Entry:* ${entry:.4f}\n"
|
||||||
|
message += f"*Current:* ${current:.4f}\n\n"
|
||||||
|
message += f"*Targets:*\n"
|
||||||
|
message += f" TP1: ${tp1:.4f} {'✅' if tp1_hit else '⏳'}\n"
|
||||||
|
message += f" TP2: ${tp2:.4f}\n"
|
||||||
|
message += f" SL: ${sl:.4f}\n\n"
|
||||||
|
message += f"*Position:* ${size:.2f} @ {leverage}x\n"
|
||||||
|
message += f"*Age:* {age_min} min"
|
||||||
|
|
||||||
|
await update.message.reply_text(message, parse_mode='Markdown')
|
||||||
|
|
||||||
|
print(f"✅ Status sent: {len(positions)} position(s)")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error: {e}")
|
||||||
|
await update.message.reply_text(f"❌ Error: {str(e)}")
|
||||||
|
|
||||||
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
"""Forward trade commands to n8n"""
|
"""Forward trade commands to n8n"""
|
||||||
|
|
||||||
@@ -63,16 +146,20 @@ def main():
|
|||||||
print(f"🚀 Telegram Trade Bot Starting...")
|
print(f"🚀 Telegram Trade Bot Starting...")
|
||||||
print(f"📱 Chat ID: {ALLOWED_CHAT_ID}")
|
print(f"📱 Chat ID: {ALLOWED_CHAT_ID}")
|
||||||
print(f"🔗 Webhook: {N8N_WEBHOOK_URL}")
|
print(f"🔗 Webhook: {N8N_WEBHOOK_URL}")
|
||||||
print(f"\n✅ Send messages like:")
|
print(f"🤖 Trading Bot: {TRADING_BOT_URL}")
|
||||||
|
print(f"\n✅ Commands:")
|
||||||
|
print(f" /status - Show open positions")
|
||||||
|
print(f"\n✅ Trade messages:")
|
||||||
print(f" buy sol")
|
print(f" buy sol")
|
||||||
print(f" sell btc")
|
print(f" sell btc")
|
||||||
print(f" buy eth")
|
print(f" buy eth")
|
||||||
print(f" sell sol")
|
print(f" sell sol")
|
||||||
|
|
||||||
app = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
|
app = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
|
||||||
|
app.add_handler(CommandHandler("status", handle_status_command))
|
||||||
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
|
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
|
||||||
|
|
||||||
print(f"\n🤖 Bot ready! Listening for trade commands...\n")
|
print(f"\n🤖 Bot ready! Listening for commands...\n")
|
||||||
app.run_polling(allowed_updates=Update.ALL_TYPES)
|
app.run_polling(allowed_updates=Update.ALL_TYPES)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user