Tradovate API

Fallan las órdenes bracket (OSO/OCO) de la API de Tradovate

Su entrada se ejecuta en ES o NQ y el stop-loss o el take-profit nunca aparece. Esto es lo que realmente significan el 200 OK, el 404 y el rechazo 'Wrong OCO combination', y cómo corregir cada uno.

Revisado por el equipo de Sistemas de Trading de PickMyTrade Última actualización
· Lectura de 8 minutos
Respuesta de una orden bracket de la API de Tradovate que muestra HTTP 200 OK con failureReason y failureText en el cuerpo

Su automatización envía una orden bracket de la API de Tradovate, la entrada se ejecuta en ES o NQ y luego… nada. Sin stop-loss, sin take-profit. Ahora está a un mal tick de distancia de una posición sin protección, y su registro indica que la orden se “envió correctamente”. Esa es la trampa. En 2026 el fallo clásico ya no es una pantalla de error roja, sino un estado HTTP 200 OK que oculta un failureReason y un failureText en el cuerpo, o una llamada a orderStrategy que vuelve como un simple 404. Las variantes más frecuentes: un 404 (undocumented) de startOrderStrategy, un error de análisis Invalid JSON, un rechazo Wrong OCO combination, y el más traicionero, una ejecución parcial silenciosa en la que solo sobrevive la entrada. A continuación, lo que significa realmente cada error, cómo corregir los problemas de endpoint y de campos detrás de ellos, y cómo PickMyTrade evita que una ejecución sin protección llegue a su cuenta.

Lista rápida de verificación para órdenes bracket (OSO/OCO) que fallan

  • Lea el cuerpo de la respuesta, no solo el código HTTP. Tradovate le devuelve 200 OK incluso cuando la orden nace muerta. La verdad está en failureReason / failureText.
  • Confirme el endpoint. Use order/placeOSO para una entrada que envía piernas de stop/objetivo, order/placeOCO para dos salidas vinculadas, y orderStrategy/startOrderStrategy para un bracket del lado del servidor.
  • Envíe ambos campos de cuenta. Necesita el accountId numérico (de account/list) y el nombre de cuenta accountSpec. Si omite uno, o no coinciden, obtendrá Access is denied.
  • Serialice JSON real. Envíe un cuerpo JSON (json= en Python requests), no un diccionario en bruto, de lo contrario obtendrá Invalid JSON: expected '{'.
  • Use orderStrategyTypeId: 2. Es el único valor válido. Un 1 le dará un 404 (undocumented).
  • Tenga un plan de respaldo listo. Si el endpoint de estrategia sigue fallando, coloque la entrada y luego adjunte un placeOCO de stop/objetivo en cuanto mantenga la posición.

Qué significan «Wrong OCO Combination» y los errores 404

Tradovate le ofrece varias formas de enviar órdenes protegidas, y cada una falla a su manera. Un bracket es una orden de entrada más dos piernas hijas, un stop protector y un objetivo de beneficio, donde ejecutar o cancelar una hija cancela la otra. En la API REST, esto se construye con order/placeOSO (One-Sends-Other): una orden padre lleva objetos bracket1 y bracket2 que solo se activan tras la ejecución de la orden padre. order/placeOCO (One-Cancels-Other) vincula dos órdenes de forma que la ejecución de una cancela la otra, útil para añadir un stop y un objetivo a una posición que ya mantiene.

Lo confuso: estos endpoints devuelven alegremente 200 OK mientras siguen rechazando la orden. Tradovate informa los fallos de lógica de negocio dentro del cuerpo de la respuesta, no en el estado HTTP. Así, un payload que llega limpio al servidor puede volver con {"failureReason": "InvalidPrice", "failureText": "Wrong OCO combination"}, lo que significa que los niveles de precio o el emparejamiento de tipos de orden elegidos no forman una OCO válida. Un stop y un límite situados en el lado equivocado del mercado bastan para provocarlo. Trate cualquier cuerpo que contenga failureReason como un rechazo, sin excepción, sin importar lo que diga la línea de estado.

El endpoint orderStrategy/startOrderStrategy es harina de otro costal. Ejecuta una estrategia bracket del lado del servidor, el equivalente en API de una estrategia ATM, y es mucho más exigente con su payload. Si envía el orderStrategyTypeId incorrecto, o lo llama por REST plano cuando espera un frame de WebSocket, obtendrá un 404 (undocumented) poco útil. Parece una ruta inexistente, pero en realidad es una solicitud rechazada.

Principales causas de fallo en las órdenes bracket de la API de Tradovate

1. Solo comprobó el estado HTTP, no el cuerpo

Esta es la trampa número uno. Su cliente ve 200 OK, registra “orden enviada” y sigue adelante, pero la entrada fue rechazada, o solo la orden padre se completó. Analice cada respuesta OSO/OCO en busca de failureReason y failureText antes de dar el bracket por activo.

2. orderStrategyTypeId incorrecto en startOrderStrategy

Mucha gente prueba orderStrategyTypeId: 1 y solo consigue un 404 (undocumented) por sus molestias. Solo hay un valor válido, y es 2. Cualquier otro se rechaza antes de que la estrategia siquiera se construya.

Solicitud startOrderStrategy de la API de Tradovate con el campo orderStrategyTypeId resaltado y establecido en 2

3. Llamar a startOrderStrategy por REST en lugar de WebSocket

Incluso con el id de tipo correcto, este endpoint no es fiable por HTTP REST plano. Está diseñado para funcionar sobre un WebSocket, y funciona de forma fiable cuando se controla así. Una llamada REST que sigue devolviendo 404 suele tener éxito, sin cambios, en el momento en que la envía como frame de WebSocket.

4. JSON mal formado o un diccionario en bruto en lugar de un cuerpo JSON

Un fallo habitual de placeOCO es Invalid JSON: expected '{', offset: 0x00000075. Esto ocurre cuando la solicitud envía un diccionario codificado como formulario en lugar de una cadena JSON serializada, en Python, al pasar data=payload en vez de json=payload (o al olvidar json.dumps()). El servidor nunca ve JSON válido, así que descarta todo el bracket.

5. accountSpec ausente, accountId incorrecto o una combinación de precios ilegal

Los endpoints de bracket requieren tanto el accountId numérico (extraído de account/list) como la cadena accountSpec (el nombre de su cuenta). Omita cualquiera de los dos y se encontrará con Access is denied. Por separado, placeOCO y placeOSO comprueban que las dos piernas formen una combinación válida, un stop y un límite con precio en el lado equivocado del mercado vuelven como Wrong OCO combination. Los brackets con entrada Market añaden una complicación más: como la API necesita niveles de precio concretos para las piernas hijas, en general no puede adjuntar un TP/SL relativo en ticks a una entrada Market simple mediante placeOSO. O calcula los niveles de precio usted mismo, o deja que el motor de estrategias gestione los offsets.

Cómo corregir las órdenes bracket de la API de Tradovate: paso a paso

Cómo corregir la trampa «200 OK, pero sin piernas»

  • Tras cada llamada a placeOSO / placeOCO / startOrderStrategy, analice el cuerpo JSON.
  • Compruebe si existe una clave failureReason. Si está presente, trate la orden como rechazada y lea failureText para conocer la causa.
  • Marque el bracket como activo solo cuando tenga los IDs de orden confirmados para el padre y ambas piernas hijas, consulte order/list o suscríbase a los eventos de orden por WebSocket.
  • Registre el cuerpo completo, no solo el código de estado, para que las ejecuciones parciales aparezcan en su registro de auditoría.

Cómo corregir los 404 de startOrderStrategy

  • Establezca orderStrategyTypeId en 2, el único valor que acepta.
  • Envíe tanto accountId como accountSpec, además de symbol, action y el objeto params (con su entryVersion y brackets).
  • Envíe la solicitud como un frame de WebSocket en lugar de un POST REST. Este endpoint está diseñado para funcionar sobre WebSocket, y el formato de frame que espera está bien documentado.
  • Reintente el mismo payload por el socket antes de asumir que su JSON está mal formado, el 404 suele ser un problema de transporte, no de esquema.
Payload placeOSO de la API de Tradovate mostrando las piernas bracket1 de stop-loss y bracket2 de take-profit con accountId y accountSpec

Cómo corregir Invalid JSON y Wrong OCO combination

  • Serialice el payload como JSON. En Python requests, use requests.post(url, headers=..., json=payload), nunca data=payload con un diccionario.
  • Confirme que el encabezado Content-Type: application/json esté configurado.
  • Para placeOCO, revise la geometría de las dos piernas: el stop y el límite deben situarse en lados opuestos y válidos del precio actual según la dirección de la posición. Si ve Wrong OCO combination, cambie la pierna que está en el lado equivocado.
  • Para una entrada Market, espere a la ejecución y adjunte un stop/objetivo placeOCO a la posición resultante, o cambie a startOrderStrategy, que acepta offsets relativos.

El respaldo fiable: entrada separada + OCO

Cuando un bracket nativo simplemente no coopera, desacople la entrada de las salidas. Coloque la orden de entrada por separado con order/placeOrder, confirme la ejecución y después envíe un placeOCO que empareje el stop protector con el objetivo de beneficio contra la posición ya abierta. Es un viaje de ida y vuelta adicional, pero evita por completo el endpoint de estrategia y le da control explícito sobre cada pierna.

Flujo de respaldo de la API de Tradovate: una orden de entrada ejecutada seguida de un placeOCO que adjunta las piernas de stop y objetivo

Tabla de resolución de problemas

Error Significado Solución
200 OK con failureReason en el cuerpoOrden rechazada en la capa de negocio pese a un estado HTTP limpioAnalice el cuerpo; nunca confíe solo en el código de estado
404 (undocumented) en startOrderStrategyorderStrategyTypeId incorrecto, o se usó REST cuando se esperaba WebSocketEstablezca orderStrategyTypeId: 2 y envíe por WebSocket
Invalid JSON: expected '{', offset: 0x...Se envió un diccionario en bruto / cuerpo de formulario en lugar de JSON serializadoEnvíe un cuerpo JSON (json= en requests) o aplique json.dumps() primero
failureReason: InvalidPrice, failureText: Wrong OCO combinationLas dos piernas OCO no forman un emparejamiento de precio/tipo válidoReprecie de forma que el stop y el límite queden en lados opuestos válidos
Access is deniedaccountId o accountSpec ausente o incorrectoEnvíe el accountId numérico de account/list junto con el nombre accountSpec
La entrada se ejecuta, no aparece stop/objetivoLas piernas hijas fueron rechazadas silenciosamente mientras el padre se aceptóConfirme los tres IDs de orden, o recurra a entrada + placeOCO

Cómo prevenirlo con PickMyTrade

Construir a mano los payloads OSO/OCO significa asumir usted mismo cada uno de los modos de fallo anteriores. PickMyTrade se sitúa entre sus alertas de TradingView y Tradovate y gestiona por usted la instalación del bracket:

  • Gestión de brackets y OCO, adjunta correctamente las piernas de stop-loss y take-profit, de modo que una entrada nunca queda sin protección.
  • Validación de respuestas, inspecciona la respuesta completa de la orden, no solo el estado HTTP, y muestra los rechazos reales en lugar de un falso “éxito”.
  • Filtros de habilitación y riesgo, respeta el estado del acuerdo de datos de su cuenta y los límites de la prop firm antes de enrutar una orden.
  • Enrutamiento seguro frente a límites de tasa, espacia el flujo de órdenes para que las piernas del bracket no choquen con los topes de solicitudes.
  • Sincronización multicuenta, replica el mismo bracket protegido en todas las cuentas conectadas.

Opere sin rechazos

Inicie su prueba gratuita de 5 días, conecte hoy mismo sus alertas y deje que PickMyTrade adjunte el stop-loss y el take-profit correctamente cada vez.

Inicie su prueba gratuita de 5 días

Preguntas frecuentes

Use order/placeOSO cuando una sola entrada deba enviar un stop y un objetivo como bracket1 y bracket2. Use order/placeOCO para vincular dos órdenes de salida de modo que la ejecución de una cancele la otra. Use orderStrategy/startOrderStrategy para una estrategia bracket del lado del servidor con offsets relativos.

Tradovate informa los rechazos de lógica de negocio dentro del cuerpo de la respuesta, no en el estado HTTP. Analice el cuerpo en busca de failureReason y failureText, y trate el bracket como activo solo cuando tenga los IDs de orden confirmados para el padre y ambas piernas hijas.

Es un rechazo InvalidPrice que significa que sus dos piernas OCO no forman un emparejamiento válido, normalmente el stop y el límite tienen precio en el lado equivocado del mercado para la dirección de la posición. Reprecie la pierna problemática.

Casi siempre por un orderStrategyTypeId incorrecto (debe ser 2) o por una llamada REST donde Tradovate espera un frame de WebSocket. Corrija el id de tipo y reenvíe por WebSocket.

Está enviando un diccionario en bruto o un cuerpo codificado como formulario. Serialice primero el payload a JSON, en Python requests, pase json=payload en lugar de data=payload.

No directamente, placeOSO espera niveles de precio concretos para sus piernas hijas. O calcule los precios exactos antes de enviar, espere a la ejecución y adjunte un placeOCO, o use startOrderStrategy, que acepta offsets relativos.

Desacople el flujo. Coloque la entrada con order/placeOrder, confirme la ejecución y después envíe un placeOCO que empareje el stop y el objetivo contra la posición abierta. Evita por completo el endpoint de estrategia.

Sí. Los endpoints de bracket esperan el accountId numérico de account/list y el nombre de cuenta accountSpec en formato de cadena. Omitir cualquiera de los dos devuelve Access is denied.

Esta guía tiene únicamente fines educativos e informativos y no constituye asesoramiento financiero, de inversión o de trading. Operar con futuros y otros productos apalancados conlleva un riesgo sustancial de pérdida y no es adecuado para todos los inversores. PickMyTrade es una plataforma de automatización independiente de terceros y no está afiliada, respaldada ni patrocinada por Tradovate, Inc. ni por Bookmap. Todos los nombres, logotipos y marcas relacionados son propiedad de sus respectivos dueños. Las funciones y los pasos de la plataforma cambian con el tiempo, por lo que siempre debe confirmar el proceso actual en la documentación oficial de la plataforma antes de actuar.