Greetings, and happy festive seasons!
It would be ideal to receive an OrderUpdateEvent
through/via the UserDataStream
when the activationPrice
for a trailing_stop_market
order is hit, because then users don’t have to waste bandwidth, computing, and rate limit resources, calculating something that they could be receiving from the server. The overall quality of the API would be improved.
Currently, for trailing_stop_market
orders, the sequence of events is as follows:
- The
trailing_stop_market
is placed and an event is received through theUserDataStream
with statusNEW
- The
activationPrice
for thattrailing_stop_market
is hit, and nothing happens. - After some time, the
reboundRate
surpasses thecallbackRate
defined for thetrailing_stop_market
order. At this point, a whole bunch of things happen:
3.1 First, thetrailing_stop_market
is set toEXPIRED
, and anOrderUpdateEvent
is received through theUserDataStream
.
3.2 Then amarket
order is set to buy/sell at the current price, with statusNEW
. AnOrderUpdateEvent
is received.
3.3 Themarket
order partially fills and eventually fills, andOrderUpdateEvent
s are received along the way.
For the most part, I think that works out fine. The thing that I would love to happen is, at number 2.
, when the activationPrice
is hit, I’d love for the API to push an OrderUpdateEvent
through the UserDataStream
, perhaps with status ACTIVATED
.
(As an optional aside, I also think it would be better if, at number 3.1
, the trailing_stop_market
's status was set to something like EXECUTED
or TRIGGERED
instead of EXPIRED
, simply to differentiate it from the case where it legitimately expired because of exiting the position before the trailing_stop_market
could do its thing/perform its functions. However, that’s not the main focus of this feature request.)
Ideally, and just to clarify, I think it would be perfect if the sequence of events was modified just slightly to the following instead, with the changed parts in bold:
- The
trailing_stop_market
is placed and an event is received through theUserDataStream
with statusNEW
- The
activationPrice
for thattrailing_stop_market
is hit, and an event is received through theUserDataStream
with statusACTIVATED
- After some time, the
reboundRate
surpasses thecallbackRate
defined for thetrailing_stop_market
order. At this point, a whole bunch of things happen:
3.1 First, thetrailing_stop_market
is set toEXECUTED
, and anOrderUpdateEvent
is received through theUserDataStream
.
3.2 Then amarket
order is set to buy/sell at the current price, with statusNEW
. AnOrderUpdateEvent
is received.
3.3 Themarket
order partially fills and eventually fills, andOrderUpdateEvent
s are received along the way.
That’s basically it for the feature request, but just to show why it would be good, here are some of the alternative workarounds for determining when the activationPrice
for a trailing_stop_market
order was hit:
-
I could stream the candlesticks for the market/pair that the
trailing_stop_market
order is operating in, using the availableWebSocket
stream endpoints. The issue with this is that now there’s a whole stream alive that gets hit every 250ms, and every time it gets hit it needs to do a whole bunch of calculations to try and infer whether or not theactivationPrice
was crossed. And this needs to happen for every position I enter. Relative to the current state of my operations, this would increase the amount of computational resources I’m consuming insanely much. In addition, I’d need to make sure that the stream is kept alive, do a whole bunch of error handling to keep things stable and robust, etcetc. More threads need to be spawned and that might not always be possible, depending on the architecture you’re using. If I was doing other stuff with the stream, it would’ve made sense, and I might in the future, but for now it’s like killing a spider with a tank. -
I could implement a polling mechanism, and that kind of relieves some of the pull on the resources mentioned above, but now I introduce an inherent latency into the system, which isn’t ideal either. If I poll every 3min, then every 3min I could check all open orders, and for each open position, I could get a snapshot of the candlestick data, and I could just check if one of the
high
values in the candlestick data passed theactivationPrice
. I could automate this with something like acron
job or something. The issue with this is that it wastes rate limit resources, and that kind of inefficiency doesn’t scale well. In addition, now there’s always gonna potentially be a 3minute delay between when the current state of things was last updated on my side, and that’s not good. -
Another alternative is using something like
alpaca.markets
,TradingView
,CoinMarketCap
, or perhaps some other third party application – one that hooks into the Binance data streams and that has this notification feature – and configuring it to send the notification through aWebHook
or something like that. That’s still not the best, though, because the notification isn’t inherently tied to the original order in the way that it would be if I received anOrderUpdateEvent
for thetrailing_stop_market
order that it is intended for. I’d have to match the notification with the order on my side. Maybe if the notification feature supports some kind of message, I could send the order id around and match things that way. Not an issue. The issue with this option is that now I introduce a whole different app/system as a dependency. That’s very far from ideal, because I’d have to rework things if that system falls over somehow. -
I could split up my
trailing_stop_market
orders into, say, 95%trailing_stop_market
and 5%take_profit_market
orders, and rely on when thetake_profit_market
order receivesOrderUpdateEvent
s through theUserDataStream
to try and infer when theActivationPrice
for thetrailing_stop_market
was hit. I could link them up using ahas_one
relationship in my database. The issue with this is that there are a whole bunch of edge cases that might break things. One example is when a pair that I want to enter into can only be traded in integer quantities, and if I can only acquire 1 unit of that pair at the given risk, margin availability and leverage that I want to enter into, then I would not be able to place both thetrailing_stop_market
and thetake_profit_market
orders at any kind of ratio, and the whole thing would fall over.
All of that is messy, and far from ideal. The first is overkill and wasteful, the second introduces a time-delay, the third introduces a dependency, the fourth option isn’t 100% reliable and cuts into profit margins.
Overall, I think the API’s quality and value would be much improved if there was actually a general alert system and set of endpoints that dealt with these types of things. On TradingView
, for example, you can setup sophisticated alerts with a bunch of different conditions, settings, etc.:
You can even make them interact with various indicators like EMA and RSI and all of that, and if we could do that over the API that would be awesome!
However, for the purposes of this feature request, I’d like to keep it scoped to just sending an OrderUpdateEvent
through the UserDataStream
when a trailing_stop_market
order’s activationPrice
is hit.
How can we go about implementing this? How long do we think it’ll take? Do you need me to help out? I’m a dev myself, and actually it would be great if we could onboard me just so that I can work on the API for my own trading purposes, and so that I can help support the growth and evolution of the API in future. Either way, I’d really love for this to happen.
Thanks!