Using the same api endpoint if the payload is an array of orders this will be a bulk order We will allow this API call only if the jwt user role is bot.
Bulk order must return an array of UUID.
Available as an additional option to Limit or Conditional Limit Orders, Post-Only Orders serve to strictly ensure that your Limit Orders will be placed into the order book and therefore receive a maker rebate then it is ultimately executed. By selecting this option, the system will automatically cancel the Limit Order, if it detects that it will be executed immediately upon the order placement.
https://help.bybit.com/hc/en-us/articles/360025011233-Post-Only-Orders
Limit api speed for all regular traders to:
50 orders per 10 second
200 orders per minute
100,000 orders per 24hrs
Limit api speed for all bot traders to:
20,000 orders per 10 second
100,000 orders per minute
100,000,000 orders per 24hrs
Api rate limit will be a pub-sub architecture with a AMQP Queue, This AMQP Queue is a C&C system (Command and Control, read about it on botnet / virus architecture)
Each api listen to a "finex.api.command" queue and execute actions Here is the api-rate limit actions:
limit:U1254546:10
limit:U1254546:60
limit:U1254546:86400
When recieving this action, api must return HTTP code "429 Too Many Requests" to the user orders / cancels during the time duration.
We calculate api rates using array in the order gateway before send to the matching If rate is reached we have to make two actions :
It's very important that we can get rid of Ranger in v2.5 The api daemons must be able to support ws upgrade using: https://github.com/fasthttp/websocket
I suggest sending the event "order_canceled" as an example Send on queue: "finex.api.event"
Ability to send orders and cancels using WS Send all events using ws server
Support FIX protocol 4.4 and 5.0 https://github.com/quickfixgo/quickfix
This will be another daemon
Example Real markets are : BTCUSD XYZBTC
We can create a synthetic orderbook: XYZYSD
curl -i -X POST -H "Content-Type: application/json" \
-d '{"market": "btcusd", "type": "limit", "side": "sell", "price": "8000.0", "amount": "0.1"}' \
http://localhost:8080/market/orders
hey -n 100000 -c 200 -m POST -H "Content-Type: application/json" \
-d '{"market": "btcusd", "type": "limit", "side": "sell", "price": "8000.0", "amount": "0.1"}' \
http://localhost:8080/market/orders
There are two risks - first is balance inconsistense, when "actual" balance is lower than the balance gateway relies on. It can be caused by:
Buffered balance decreasing. Finex can get next order before balance in database will be decreased. Though, tracking spent amount can help here.
Out-of-finex balance manipulation. Main example - withdraw. This problem arrives if we decide to cache balance. Though, withdraws and other possible balance decreases should force cache invalidation.
Combining these two creates another problem - we cannot invalidate spent amount easily, because we may have buffered changes. But if we don't, user will be restricted to trade, though he some money.
Relying on api rate limiting is actually considering exchange is running slow enough to avoid problems. Sounds wrong if we consider finex a fast engine.
Gateway-level limiting is easier to scale.
Api rate limiter is still good to avoid spamming.
Api rate limiter is still good to slowdown exchange on high load.It is better to tell users we are not able to process their orders than tell 201, ok, and user does not get websocket confirmation.
The idea is that every trader should have internal finex session to be able to create orders. Session can store user limits, balances.
Session destroy can be also used to collect all session's statistic.
Session is an approach serving two main purposes:
Security - track spent amount and block trading on sensitive events (Withdraw). Session invalidation should result in temporary blocking, which should be enough for buffer flushing.
Speed - decrease amount of sql selects with balance cache. The simpliest approach is to decrease balance on order creation and refetch when balance is not enough to create an order, which should refetch order cancelations, trades and deposits.
The idea is to limit user in actions, not in orders. Why? because actions can be weighted.
Example:
Action | Points |
---|---|
Order creation | 1 point |
Order cancelation | 1 point |
Cancel all my orders | 5 points |
Refetch balance from database | 10 points |
This way heavyweight (for finex) operations will exhaust user action limit faster.