Is it possible to place two opposing orders? For example, if a stock is at 73, and I want to go long at 74 or short at 72, is there a way to place each of those orders and then cancel the ‘second’ order once the ‘first’ fills? Thank you!
Unfortunately, there is not a good solution to this type of trade. What you are looking for is a One-Cancels-Other or OCO order type. However, Alpaca currently only supports this with orders being in the same direction (ie both ‘buy’ or both ‘sell’). It cannot be used to create a long and a short order. Additionally, (you probably also noticed this) one cannot create two separate orders, one being a long stop order and the other being a short stop order, and then manually cancel the one that doesn’t fill. Alpaca doesn’t allow two open orders with opposite ‘sides’ (ie one to go long and the other to go short).
The best solution is to monitor the price in an algo and then place a single order when one of the conditions is met. This gives the most flexibility in opening a position. Using this approach, I would recommend placing the order as a bracket order with take-profit and stop-loss legs. One can always go in and modify the limit and stop prices once the initial order fills.
Is there any plan to support OCO for buy/sell to enter a position? or what is the reason it won’t be supported? @Dan_Whitnable_Alpaca
@Vincent There are no plans to support bracket orders which are not entry orders.
The issue revolves around the constraint that one cannot move directly from a long position to a short position (or vice versa). As long as one is placing orders which always increase a position (either more long or more short) then this constraint could never be violated. However, if non-entry orders are allowed, depending upon the sequence in which the orders execute, there could be times a position would switch sides in a single order. That is why bracket orders are required to be entry orders.
I am not sure I understand your point. I am quite new to this so I might get some points wrong.
There are no plans to support OCO orders which are not entry orders.
This is not what the documentation about OCO orders says.
From the documentation,
OCO (One-Cancels-Other) is another type of advanced order type. This is a set of two orders with the same side (buy/buy or sell/sell) and currently only exit order is supported.
The main reason I would like to be able to use OCO orders with buy/sell to enter a position, is that I know the market will move but I don’t know in which direction so I want to be able to send a stop buy order above the current price and a stop sell order below the current price. This way whatever triggers will cancel the other one.
For example: stock price is at 100 and I don’t hold any position for that stock. I want to send an OCO order with stop buy at 105 and stop sell at 95, if market goes above 105, the buy order is filled and the sell order at 95 will cancel and vice versa. Currently, if I try to do this with simple orders, the API rejects the second order saying it is wash trading.
PS: I have tried monitoring the stock price but Alpaca websocket for price monitoring only offers to get the price every minute which is not small enough for what I am looking for
PSS: to clarify my initial question, is it possible to make OCO orders for buy/sell instead of only {buy/buy or sell/sell}? And is it possible to make OCO orders to enter a position (which is currently not the case)? Also do you know any other broker that allows this?
@Vincent Apologies, I was thinking bracket orders.
The reasoning is the same however (just reversed). Since positions cannot move from long to short (or short to long) with a single order. The sequence in which ‘held’ orders execute could result in violating this constraint. OCO orders are generally used to exit a position so ‘exit only’ was chosen to avoid the fill sequence from being an issue. Probably could have been entry only but that’s not the typical use case and creates issues if there is no initial position because one does not know ahead of time if the order will be long or short.
Your specific situation isn’t exactly that because you want an OCO order with opposite sides (currently only the same side is allowed), but it creates the same problem though. One could end up going from long to short (or vice versa) in a single order if one places multiple OCO orders.
What I would do is check the latest_trade endpoint. Poll it every 100ms (or more frequently if you wish). Throw out any trades with excluding trade conditions (though you may want to modify those conditions more to your liking). Submit your buy or sell order whenever the price is above or below your values. Probably even more reliably/correctly you would also fetch the latest_quote. That will give you a good indication of what your order will fill at and/or what price to set any limit orders at. There isn’t any reason to trigger a buy order, for example, if you can’t really buy at that price. This approach is much more robust and flexible than relying on stop orders IMHO.
Would that work for you?
Thanks for the details, I just tried that, and it seems there is a delay/limit when I try to get the latest trades. Here are some custom logs.
14/06/2024 18:32:41 {"trades":{"NVDA":{"c":["@"],"i":7515,"p":132.35,"s":100,"t":"2024-06-14T17:32:40.078290319Z","x":"V","z":"C"}}}
14/06/2024 18:32:44 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:32:46 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:32:49 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:32:53 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:32:56 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:33:01 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:33:04 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:33:07 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:33:09 {"trades":{"NVDA":{"c":["@"],"i":7516,"p":132.32,"s":100,"t":"2024-06-14T17:32:41.317313631Z","x":"V","z":"C"}}}
14/06/2024 18:33:12 {"trades":{"NVDA":{"c":["@"],"i":7520,"p":132.18,"s":100,"t":"2024-06-14T17:33:09.810090576Z","x":"V","z":"C"}}}
14/06/2024 18:33:16 {"trades":{"NVDA":{"c":["@"],"i":7520,"p":132.18,"s":100,"t":"2024-06-14T17:33:09.810090576Z","x":"V","z":"C"}}}
14/06/2024 18:33:19 {"trades":{"NVDA":{"c":["@"],"i":7521,"p":132.33,"s":200,"t":"2024-06-14T17:33:18.211057956Z","x":"V","z":"C"}}}
As you can see, when it is 18:33:09, I still get the latest trade from 18:32:41 which is almost 30sec before, I am pretty sure I didn’t exceed the 200 API call/min allowed in the free plan? Would you know why there is such a difference? Would paying for the algo trader plus member ship fix this issue?
@Vincent The data you show are trades from the IEX exchange only (notice all the exchange codes are V). You must be using the Free data subscription. That subscription only allows fetching full market SIP data older than 15 minutes. You cannot get real time full market data unless you subscribe to the paid market data plan. Since only about 2% of all trades execute on the IEX exchange you are missing many of the most recent trades.
Thanks for the answer, is there a free trial for the paid plan?
@Vincent Send an email to support@alpaca.markets and request a coupon code for a 30 day free trial of market data. They may be able to provide one.