🚀 Introducción
La API de B.E.N.D.E.R. te permite acceder a las señales de trading REALES generadas por el Bot Master especializado en NASDAQ 100.
🌐 Base URL
https://api.benderbot.es/api/v1
🔐 Autenticación HMAC
Todas las peticiones requieren autenticación HMAC-SHA256.
Headers Requeridos
| Header | Descripción |
|---|---|
X-API-Key | Tu API Key |
X-Timestamp | Timestamp Unix (segundos) |
X-Signature | Firma HMAC-SHA256 |
X-Session-ID | UUID único de sesión |
Generar Firma
message = api_key + timestamp signature = SHA256(api_secret + message)
📡 Endpoints
Health check público - No requiere autenticación.
Señales de trading REALES activas del Bot Master.
Respuesta incluye: success, count, signals[], system_status (objeto con estado del mercado o null), your_plan, note, timestamp.
null. Cuando el Bot Master detecta condiciones de mercado lateral (MARKET_LATERAL), devuelve un objeto con status, message, market_score, since y expires_at.
Historial de señales (limitado según plan).
Parámetros query: limit opcional (1-500, default 100) — symbol opcional (filtrar por símbolo, ej: ?symbol=DDOG)
Respuesta incluye: success, count, history[], your_plan, history_limit_days, timestamp.
Estadísticas del Bot Master.
Respuesta: stats.total_signal_batches (total historico), stats.signal_batches_today (hoy), stats.active_signal_batches (activas ahora), stats.last_signal (objeto con action, timestamp, num_symbols).
Información de tu cuenta y uso actual.
Ver tus sesiones activas.
Terminar una sesión específica.
📋 Estructura de Señal
💡 Filosofía del sistema
B.E.N.D.E.R. gestiona internamente toda la complejidad del trading: stops dinámicos, trailing stops, targets, sizing por Kelly, gestión de riesgo y protección de capital. El desarrollador no necesita preocuparse por nada de eso.
La API refleja acciones ya tomadas por el Bot Master, no órdenes pendientes de configurar. Cuando ves BUY_NEW, el bot ya ha calculado la cantidad óptima, el momento de entrada y el riesgo asumido. Tu sistema solo tiene que replicar la acción.
La gestión de stops, trailing stops y targets vive en el Master y se ejecuta en tiempo real de forma interna. Cuando un stop salta, el Master envía la acción de cierre correspondiente (SELL_ALL, COVER_SHORT, etc.) — el desarrollador no necesita gestionar stops manualmente.
Cada señal del endpoint /signals contiene los siguientes campos:
Campos de Identificación
| Campo | Tipo | Descripción |
|---|---|---|
signal_id | integer | ID único de la señal |
id | integer | Alias de signal_id (compatibilidad) |
symbol | string | Símbolo del activo (ej: "DDOG", "ARM") |
Campos de Acción
| Campo | Tipo | Descripción |
|---|---|---|
action | string | Tipo de acción (ver tipos) |
action_type | string | Alias de action (compatibilidad) |
quantity | integer | Cantidad de acciones/contratos |
Campos de Precios
| Campo | Tipo | Descripción |
|---|---|---|
entry_price | float | null | Precio de entrada en el momento de la señal |
price | float | null | Alias de entry_price (compatibilidad con limit orders) |
Extra Data (datos adicionales por tipo de acción)
El campo extra_data varía según la acción:
| Acción | Campos en extra_data |
|---|---|
BUY_NEW | entry_price, reason, kelly_fraction, capital_pct, tif |
BUY_INCREASE | entry_price, new_avg_cost, total_quantity, capital_pct, reason, tif |
SHORT_NEW | entry_price, reason, kelly_fraction, capital_pct, tif |
SELL_ALL | entry_price, current_price, reason, tif |
SELL_PARTIAL | entry_price, current_price, sell_percentage, reason, tif |
COVER_SHORT | entry_price, current_price, reason, tif |
COVER_PARTIAL | entry_price, current_price, sell_percentage, reason, tif |
BUY_PARTIAL_SHORT | entry_price, current_price, sell_percentage, reason, tif |
PLACE_LIMIT | limit_price, entry_price, reason, capital_pct, tif |
MARKET_ORDER | entry_price, fill_price, reason, capital_pct, tif |
CLOSE_ALL | close_reason, tif |
Campos de Control
| Campo | Tipo | Descripción |
|---|---|---|
tif | string | Time in Force: "DAY", "GTC", etc. |
close_positions | boolean | Si true, cerrar todas las posiciones (señal CLOSE_ALL) |
Campos de Confianza
| Campo | Tipo | Descripción |
|---|---|---|
kelly_fraction | float | Fracción Kelly para sizing (0.0 - 1.0). Presente en BUY_NEW y SHORT_NEW |
confidence | float | Alias de kelly_fraction (compatibilidad) |
Campos de Estado y Tiempo
| Campo | Tipo | Descripción |
|---|---|---|
status | string | "active" o "inactive" |
is_active | boolean | Si la señal está activa |
created_at | string (ISO) | Fecha de creación |
expires_at | string (ISO) | Fecha de expiración |
time_to_live_minutes | integer | TTL en minutos |
master_timestamp | string (ISO) | Timestamp original del Bot Master |
Ejemplo de Respuesta
{
"success": true,
"count": 1,
"signals": [
{
// Identificación
"signal_id": 12345,
"symbol": "DDOG",
// Acción
"action": "BUY_NEW",
"action_type": "BUY_NEW",
"quantity": 50,
// Precio de entrada
"entry_price": 140.42,
// Confianza del modelo ML
"kelly_fraction": 0.75,
"confidence": 0.75,
// Control
"tif": "DAY",
"close_positions": false,
// Datos adicionales según tipo de acción
"extra_data": {
"tif": "DAY",
"entry_price": 140.42,
"reason": "nueva_posicion",
"kelly_fraction": 0.75,
"capital_pct": 0.15
},
// Estado
"is_active": true,
"expires_at": "2025-12-20T15:35:00Z",
"time_to_live_minutes": 5
}
],
"timestamp": "2025-12-20T15:30:05Z",
// null cuando el mercado opera con normalidad
"system_status": null
}
👤 Estructura de Cuenta /account
El endpoint GET /api/v1/account devuelve la información completa de la cuenta autenticada.
Campos Principales
| Campo | Tipo | Descripción |
|---|---|---|
email | string | Email asociado a la cuenta |
plan | string | Plan activo: sandbox, basic, pro, enterprise |
status | string | Estado: trialing, active, past_due, unpaid, canceled |
monthly_fee | float | Tarifa mensual en euros |
rate_limit_per_minute | integer | Máximo de requests por minuto según plan |
history_days | integer | null | Días de historial disponibles. null = ilimitado (Enterprise) |
current_period_end | string (ISO) | null | Fecha de próxima renovación. null en sandbox/trial |
created_at | string (ISO) | Fecha de creación de la cuenta |
Objeto usage — Uso Actual
| Campo | Tipo | Descripción |
|---|---|---|
active_connections | integer | Conexiones simultáneas activas en este momento |
max_connections | integer | Máximo de conexiones simultáneas permitidas según plan |
total_requests | integer | Total acumulado de requests realizados |
Objeto trial_info — Solo en plan Sandbox
Presente únicamente cuando plan = sandbox. null en planes de pago.
| Campo | Tipo | Descripción |
|---|---|---|
trial_end | string (ISO) | Fecha y hora de expiración del trial |
days_remaining | integer | Días restantes del trial |
hours_remaining | integer | Horas restantes del trial |
expired | boolean | true si el trial ha expirado |
Ejemplo de Respuesta
{
"success": true,
"account": {
"email": "user@example.com",
"plan": "basic",
"status": "active",
"monthly_fee": 79.0,
"rate_limit_per_minute": 8,
"history_days": 7,
"current_period_end": "2026-05-04T18:00:00Z",
"trial_info": null,
"usage": {
"active_connections": 1,
"max_connections": 1,
"total_requests": 1240
},
"created_at": "2026-03-09T14:28:53Z"
},
"timestamp": "2026-03-09T18:06:01Z"
}
🎯 Tipos de Acción
El campo action puede tener los siguientes valores:
Acciones de Apertura
| Acción | Descripción | TTL |
|---|---|---|
BUY_NEW | Abrir nueva posición LONG | 5 min |
BUY_INCREASE | Incrementar posición LONG existente | 5 min |
SHORT_NEW | Abrir nueva posición SHORT | 5 min |
Acciones de Cierre
| Acción | Descripción | TTL |
|---|---|---|
SELL_ALL | Cerrar toda la posición LONG | 5 min |
SELL_PARTIAL | Cerrar parcialmente una posición LONG (profit-taking por tiers) | 5 min |
COVER_SHORT | Cerrar toda la posición SHORT (buy-to-cover) | 5 min |
COVER_PARTIAL | Cubrir parcialmente una posición SHORT (profit-taking por tiers) | 5 min |
BUY_PARTIAL_SHORT | Cubrir parcialmente una posición SHORT (alternativo) | 5 min |
CLOSE_ALL | Cerrar todas las posiciones abiertas (emergencia / cierre de mercado) | 5 min |
Órdenes de Protección de Capital
| Acción | Descripción | TTL |
|---|---|---|
PLACE_LIMIT | Colocar orden límite | 60 min |
MARKET_ORDER | Ejecutar orden a mercado | 5 min |
⏱️ Rate Limits
| Plan | Precio | Req/Min | Conexiones | Webhooks | Historial |
|---|---|---|---|---|---|
| Sandbox | Gratis (15 días) | 8 | 1 | 0 | 1 día |
| Basic | €79/mes | 8 | 1 | 0 | 7 días |
| Pro | €199/mes | 25 | 3 | 1 | 30 días |
| Enterprise | €349/mes | 50 | 6 | 3 | Ilimitado |
💰 Planes
❌ Códigos de Error
| Código | Descripción |
|---|---|
| 400 | Parámetro inválido (ej: limit no es entero, session_id falta o UUID inválido) |
| 401 | API Key inválida o firma incorrecta |
| 403 | Suscripción inactiva o trial expirado |
| 404 | Recurso no encontrado (ej: sesión inexistente en /sessions/terminate) |
| 429 | Rate limit o conexiones excedidas |
| 500 | Error interno del servidor |
| 503 | Servicio temporalmente no disponible (rate limiter en modo protección) |
💻 Ejemplos de Código
Python - Obtener Señales
import hmac, hashlib, time, uuid, requests API_KEY = "bdr_live_tu_api_key" API_SECRET = "tu_api_secret" BASE_URL = "https://api.benderbot.es/api/v1" SESSION_ID = str(uuid.uuid4()) def get_headers(): timestamp = str(int(time.time())) message = API_KEY + timestamp signature = hashlib.sha256((API_SECRET + message).encode()).hexdigest() return { "X-API-Key": API_KEY, "X-Timestamp": timestamp, "X-Signature": signature, "X-Session-ID": SESSION_ID } # Obtener señales response = requests.get(f"{BASE_URL}/signals", headers=get_headers()) data = response.json() for s in data.get("signals", []): print(f"{s['action']} {s['quantity']} {s['symbol']} @ ${s.get('entry_price', 'N/A')}") # Kelly fraction (confianza del modelo ML) if s.get('kelly_fraction'): print(f" Kelly: {s['kelly_fraction']}")
Python - Procesar Acciones
def process_signal(signal): action = signal.get('action') symbol = signal.get('symbol') extra = signal.get('extra_data', {}) if action == 'BUY_NEW': # Abrir nueva posicion LONG execute_buy( symbol=symbol, quantity=signal.get('quantity'), entry_price=signal.get('entry_price') ) elif action == 'COVER_SHORT': # Cerrar posicion SHORT (buy-to-cover) cover_short(symbol, signal.get('quantity')) elif action == 'SELL_ALL': # Cerrar toda la posicion close_position(symbol, signal.get('quantity')) elif action == 'SELL_PARTIAL': # Venta parcial (profit-taking) partial_sell(symbol, signal.get('quantity'), extra.get('sell_percentage'))