Add TP1/SL consistency check on trade restore

This commit is contained in:
mindesbunister
2025-11-06 12:18:31 +01:00
parent 7c888282ec
commit 6c7eaf5f04
7 changed files with 265 additions and 26 deletions

View File

@@ -6,7 +6,7 @@ Only responds to YOUR commands in YOUR chat
import os
import requests
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
# Configuration
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
@@ -15,6 +15,38 @@ 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'))
SYMBOL_MAP = {
'sol': {
'tradingview': 'SOLUSDT',
'label': 'SOL'
},
'eth': {
'tradingview': 'ETHUSDT',
'label': 'ETH'
},
'btc': {
'tradingview': 'BTCUSDT',
'label': 'BTC'
},
}
MANUAL_METRICS = {
'long': {
'atr': 0.45,
'adx': 32,
'rsi': 58,
'volumeRatio': 1.25,
'pricePosition': 55,
},
'short': {
'atr': 0.45,
'adx': 32,
'rsi': 42,
'volumeRatio': 1.25,
'pricePosition': 45,
},
}
async def status_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle /status command - show current open positions"""
@@ -496,6 +528,100 @@ async def trade_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
print(f"❌ Error: {e}", flush=True)
await update.message.reply_text(f"❌ Error: {str(e)}")
async def manual_trade_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Execute manual long/short commands sent as plain text."""
if update.message is None:
return
if update.message.chat_id != ALLOWED_CHAT_ID:
return
text = update.message.text.strip().lower()
parts = text.split()
if len(parts) != 2:
return
direction, symbol_key = parts[0], parts[1]
if direction not in ('long', 'short'):
return
symbol_info = SYMBOL_MAP.get(symbol_key)
if not symbol_info:
return
metrics = MANUAL_METRICS[direction]
payload = {
'symbol': symbol_info['tradingview'],
'direction': direction,
'timeframe': 'manual',
'signalStrength': 'manual',
'atr': metrics['atr'],
'adx': metrics['adx'],
'rsi': metrics['rsi'],
'volumeRatio': metrics['volumeRatio'],
'pricePosition': metrics['pricePosition'],
}
try:
print(f"🚀 Manual trade: {direction.upper()} {symbol_info['label']}", flush=True)
response = requests.post(
f"{TRADING_BOT_URL}/api/trading/execute",
headers={'Authorization': f'Bearer {API_SECRET_KEY}'},
json=payload,
timeout=30,
)
print(f"📥 Manual trade response: {response.status_code}", flush=True)
if not response.ok:
await update.message.reply_text(
f"❌ Execution error ({response.status_code})"
)
return
data = response.json()
if not data.get('success'):
message = data.get('message') or data.get('error') or 'Trade rejected'
await update.message.reply_text(f"{message}")
return
entry_price = data.get('entryPrice')
notional = data.get('positionSize')
leverage = data.get('leverage')
tp1 = data.get('takeProfit1')
tp2 = data.get('takeProfit2')
sl = data.get('stopLoss')
entry_text = f"${entry_price:.4f}" if entry_price is not None else 'n/a'
size_text = (
f"${notional:.2f} @ {leverage}x"
if notional is not None and leverage is not None
else 'n/a'
)
tp1_text = f"${tp1:.4f}" if tp1 is not None else 'n/a'
tp2_text = f"${tp2:.4f}" if tp2 is not None else 'n/a'
sl_text = f"${sl:.4f}" if sl is not None else 'n/a'
success_message = (
f"✅ OPENED {direction.upper()} {symbol_info['label']}\n"
f"Entry: {entry_text}\n"
f"Size: {size_text}\n"
f"TP1: {tp1_text}\nTP2: {tp2_text}\nSL: {sl_text}"
)
await update.message.reply_text(success_message)
except Exception as exc:
print(f"❌ Manual trade failed: {exc}", flush=True)
await update.message.reply_text(f"❌ Error: {exc}")
def main():
"""Start the bot"""
@@ -511,6 +637,7 @@ def main():
print(f" /buySOL, /sellSOL", flush=True)
print(f" /buyBTC, /sellBTC", flush=True)
print(f" /buyETH, /sellETH", flush=True)
print(f" long sol | short btc (plain text)", flush=True)
# Create application
application = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
@@ -527,6 +654,10 @@ def main():
application.add_handler(CommandHandler("sellBTC", trade_command))
application.add_handler(CommandHandler("buyETH", trade_command))
application.add_handler(CommandHandler("sellETH", trade_command))
application.add_handler(MessageHandler(
filters.TEXT & (~filters.COMMAND),
manual_trade_handler,
))
# Start polling
print("\n🤖 Bot ready! Send commands to your Telegram.\n", flush=True)