Trouble Submitting Bracket Order via API

I am currently working on an algorithm with my team using Visual Studio. I am running into an issue creating a bracket order in which I use ‘startorderstrategy’ but returns a 404 error. Reading other posts, this is a commonly encountered issue. Any help on a fix?

You should use a WebSocket to call the orderStrategy/startOrderStrategy endpoint. We’ve got an example of how to do that in the API FAQ - here the start order strategy sample code.

Could you supply a WebSocket example for the bracket order? I am using the REST API which was described in API documentation.

Here’s the simplest way without really any overhead, of course there are better ways to do this on a large scale (as the API FAQ docs show, I use a function constructor wrapper over my WebSocket to help abstract away these bits, feel free to reuse that implementation).

First instantiate a WebSocket:

const SIM_URL = 'wss://demo.tradovateapi.com/v1/websocket'
const mySocket = new WebSocket(SIM_URL)

Then you need to authorize the socket. You will use the access token you received using the REST API:

mySocket.onopen = _ => mySocket.send(`authorize\n1\n\n${myAccessToken}`)

Your WebSocket should now be authorized. You can make the /startOrderStrategy request like so:

//you need your account ID. You can get it using the rest API endpoint /account/list
//since you know how to use the REST API we'll assume you've gotten that already:
const myAccount = 123456

const params = {
    entryVersion: {
        orderId: 0,
        orderQty: 1,
        orderType: 'Market',
        timeInForce: 'Day',
    },
    brackets: [{
        qty: 1,
        profitTarget: 75,
        stopLoss: -33,
        trailingStop: false
    }]
}

const body = {
    symbol: "MNQZ1",
    accountId: accounts[0].id,
    action: "Buy",
    orderStrategyTypeId: 2,
    params: JSON.stringify(params)
}

mySocket.send(`orderStrategy/startOrderStrategy\n2\n\n${JSON.stringify(body)}`)

Of course, you can modify all of that data as long as it equates to a valid order.

Eventually, you’ll need to setup a listener for message events. You can use this handler:

mySocket.onmessage = msg => { /*implementation*/ }

I personally like to use this function to process the messages (which come as strings):

function prepareMessage(raw) {
    const T = raw.slice(0, 1)
    const data = raw.length > 1 ? JSON.parse(raw.slice(1)) : []

    return [T, data]
}

So then in your message handler:

mySocket.onmessage = msg => {
    const [type, data] = prepareMessage(msg)
    //determine what to do based on type and data. Keep in mind data may be null
    //the types are o  open, h  heartbeat, a  data message, and c close
} 

For more info on using WebSockets with Tradovate’s API, please review the JS WebSocket course.

Here is an image of our terminal after receiving the 404 error. We tried using the WebSocket. It authorized correctly but still returned 404.

We used same exact URL you used in the example along with access token. We need 200 response but get 404 every time we run the program.

I’m not a Python expert, but I’m looking at the sent data - it looks like the strings get escaped in the bracketOrder when you use json.dumps but not in the params variable. I think that probably has something to do with it. Can you try to assign the params variable before you call json.dumps on the whole object?

Tried doing what you said and got the same error in terminal. I’m not sure where to go from here. We are using a combination of WebSocket and REST API at this point…


We copied your text exactly and got same issue.

I’ve double checked my own working example and your request looks OK.

Can you confirm you are using the id field from the result of the http request to /accounts/list and not the userId field? It should be a 5 digit integer.

Thanks for the response, but we don’t want to exceed the API rate limit. Any detail on the limits for WebSocket and REST? What do we do if the limit is exceeded?

This depends on the endpoint that you’ve exceeded. If you receive the standard rate limit response it will look something like this:

{ "p-ticket": ...,  "p-time": 60 }

In this scenario, simply try again after “p-time” seconds and include the value of “p-ticket” in the body of your request. There is also this scenario:

{ "p-ticket": ..., "p-time": 60, "p-captcha": true }

If you get the response with the captcha, you can’t resolve it via third party application (such as an app you’re building that uses our API). You will need to wait an hour and try again in this case.

However, this scenario only occurs when you break into the limits of select endpoints. One example of where you will get this response is logging in with bad credentials. If a user uses bad credentials a few times in a row (typically 3 or more) the server will send the p-captcha response and you’ll need to instruct your users to wait an hour to resolve the limit.

WebSockets work the same way - you’ll find on large chart requests that you may get the limit response. But in these cases usually the time limit is only a second or two and you can retry using the steps above. In the API FAQ example code, I automated this possibility in my WebSocket wrapper object’s subscribe function. Here’s a link to the implementation of the code I used to wrap a WebSocket. (the lines for resending on p-ticket response are highlighted)

We are getting the same 404 error still. I don’t know how to move forward with this. A solution we came up with is if we can’t submit bracket orders, we can send 2 separate orders: entry limit, oco bracket order. The downside to this is the rate limit is of concern. I read on another post (Clarity on WebSocket Request Limits?) that had some numbers regarding rate limits. Could you give me a number that the rates are limited to so we know what our options are, such as how many requests per minute?

Also, would a Zoom call with us two be an option? I feel we can nail the issue down if we are looking at the code together.

1 Like

Bump, anyone have a solution because this thread has been abandoned since a couple weeks ago…

Thanks.

Waiting on your PM, I’ll work 1 on 1 with you asap.

In case this didn’t get resolved already - if I had to guess, the capitalization on the WebSocket is probably the issue - 404 is a Not Found error, i.e., the endpoint doesn’t exist - so, since the official endpoint is:

orderStrategy/startOrderStrategy

and you were calling:

orderStrategy/startorderstrategy

(note the capital O and S in Order and Strategy) - the endpoint wasn’t found, hence the error; double check the capitalization and you should be ready to go.

I modified my strategy a bit and turns out it is more successful not using bracket orders. If any problems arise in the future regarding bracket orders, I will be sure to PM so we can work 1 on 1 with it; I appreciate that greatly Alexander. Maybe @Jackson_Grave solution works but my programmer has already made modifications so the algorithm doesn’t need bracket orders.

OK good to hear you have a solution. Regarding the casing of strings, our servers are not case-sensitive, so that likely was not the issue. Be sure to reach out to me if you need further assistance with the API.

Hi @Alexander, after studying up on the API and your tutorials for the past couple days, I too am having trouble running a bracket order. Even using your template, I am getting the same 404. I have a feeling it might have something to do with the string format the send function is receiving, but I’m still trying to figure it out.

Here is the console error:

d: ""
i: 1
s: 404

index.js:7 

Uncaught (in promise) 
FAILED:
	operation 'orderStrategy/startOrderStrategy'
	query 
	body {
  "symbol": "NQH2",
  "accountId": ******,
  "action": "Buy",
  "orderStrategyTypeId": 2,
  "params": "{\"entryVersion\":{\"orderId\":0,\"orderQty\":1,\"orderType\":\"Market\",\"timeInForce\":\"Day\"},\"brackets\":[{\"qty\":1,\"profitTarget\":75,\"stopLoss\":-33,\"trailingStop\":false}]}"
}
	reason '""'
1 Like

This is the exact message that Tradovate sends (with my annotations) when you use the Trader application to start a bracket order:

orderStrategy/startorderstrategy <-- operation line
21                               <-- operation id number
                                 <-- blank query line
{"accountId":25519,"symbol":"ESH2","orderStrategyTypeId":2,"action":"Sell","params":"{\"entryVersion\":{\"orderId\":0,\"orderQty\":1,\"orderType\":\"Market\",\"timeInForce\":\"Day\"},\"brackets\":[{\"qty\":1,\"profitTarget\":-3.75,\"stopLoss\":2.25,\"trailingStop\":false}]}"} <-- body line

I’ve been comparing these messages, I can’t find a difference. I have re-run my examples and they succeed for me. You have set up your credentials in the example code for ‘start-an-order-strategy’ correct?

Yes, I set up the credentials before running the code, and just to be sure, I recloned the project just a moment ago and re-ran everything, in both Chrome and Safari, and am getting the same error.


Edit (appending other posts to the end of this one to reduce quantity):

@Alexander First of all, thank you for your attention in addressing this. I’m trying to figure my way through this issue (it looks like I’m not the only one), and your posts and examples have been extremely helpful.

Not sure if this adds any more context, but here is the error I am getting in the console from my code. It refers to bundle.js, which is causing me to think that maybe this has something to do with the way the app is being bundled on my machine. I tried cleaning everything up and re-running yarn install to no avail. Do you think there would be an issue with how the packages are being run on my machine, or if there are any version or package incongruences?

Uncaught (in promise) 
bundle.js:26503 

asyncGeneratorStep	@	bundle.js:26503
_throw			    @	bundle.js:26505
Promise.then (async)		
asyncGeneratorStep	@	bundle.js:26503
_next			    @	bundle.js:26505
(anonymous)		    @	bundle.js:26505
(anonymous)		    @	bundle.js:26505

And here are the two lines of code it is referring to in the library file:

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

For further context, here is the side-by-side comparison of the string you specified along with what I am sending the socket send function:

Sorry for badgering you about this, but I don’t know where else to turn, and if we can figure this out, I think it would be extremely helpful to the community.


Edit 2 (2022-0103-14:52):

After poking around some more, I am suspecting the issue has something to do with how the account id is being sent to or read by the server. I noticed that I get the same error even when I use dummy account ids like 99999:
image

@Alexander Let me know if you have any thoughts on this. I can provide you with my actual account id via DM, if needed.