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:
mindesbunister
2025-10-27 12:40:10 +01:00
parent 4ae9c38ad8
commit 97ba6a9856
8 changed files with 571 additions and 3 deletions

View File

@@ -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

View 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! 🚀

View File

@@ -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

View 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
View 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

View File

@@ -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

View File

@@ -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))

View File

@@ -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__':