Changelog
Every change you can see, newest first. Additive changes never break a client that ignores unknown fields; breaking ones are announced before they ship.
- Additive
internal: trigger exit follow-up records
No change for users (not in the API). After a trigger fires, cirrus-oms keeps a follow-up record in Redis (
oms:trigger_exit:follow_up:<trigger id>:<hit>, due times in the sorted setoms:trigger_exit:follow_ups, expiring after 2 days): a Cirrus exit is watched until it fills, a broker mirror until the broker's own exit is seen. Only cirrus-oms reads it (triggers-workers-py does not). Its samples are in (exit,mirror) are frozen inwire_enums.json. Pods on the previous version do not read these records; a follow-up written during a rollout is taken by a new pod once the rollout completes. - Additive
webhook deliveries recorded as goldens
No change to any payload. The exact delivery of every webhook event (
order_update,trade,account_alert,positions,ping: body and header formats) is now recorded indocs/api/examples/webhooks/and every push is checked against it. - Additive
stored-record fixtures and frozen enum values
No change for users. Samples of every record kind the service stores (orders, protections, triggers, positions, events, webhooks, API keys, signal URLs) and the wire values of stored enums are recorded, so a change that leaves old records unreadable, or that old pods cannot read during a deploy, fails before it is pushed.
- Additive
internal: new order-leg role `square_off`
No change for users (not in the API). Order legs in portfolio snapshots can now carry
square_off(b9b7aa6). Pods on the previous version skip a row that carries it until they are replaced: deploy the engine and the api together, and expect order views to settle once the rollout completes. - Additive
list_gtts example instrument
No change to the API. The
list_gttsfrom_brokerexample now shows a test instrument (CT:TEST:GTT_RELIANCE) instead of a real one that only existed in one developer's Redis, so the example is the same everywhere. - Additive
market protection refuses stray prices; clearer refusals
Changes in behaviour, no change to response shapes, codes or fields:
- A protected MARKET order is refused (
reason: stale_quote) when the best bid (SELL) or ask (BUY) is further from the last price than 2 protection bands or 2 ticks, instead of trading at that price (#21). Options and futures are also held within their circuit limits. - The refusal message says to place a LIMIT order: "Not placed: no live price for X right now (the market may be closed), so it cannot be sent at market. Place a LIMIT order instead." (#24).
market_protection:falseis no longer suggested. POST /v1/positions/exitrefuses (503service_unavailable) a Pocketful position whose size is ambiguous (the same contract under two products in the broker's two lists) instead of possibly exiting twice (#22).- A broker cover / bracket stop measured from the expected fill is moved to where the rules put it once the entry fills; the protection list shows what the broker holds (#23).
- A protected MARKET order is refused (
- Additive
ended protections, protection statuses, refusal reasons
GET /v1/triggerstakes an optionalstatusfilter (400 on an unknown one) and lists ended protections for 7 days, withended_reasonandpaired_trigger_idon each protection.POST /v1/triggersmay answer 504 when the broker's answer did not arrive in time.- New error codes
gtt_refusedandorder_not_open(error codes are open: handle unknown ones by their HTTP status). - A protected MARKET order refused because the best bid / ask is too far from the last price answers
reason/ errorcodestale_quote(as every unpriced market order does; the message says which). Thebook_far_from_lastvalue that briefly replaced it was never announced and is gone.
- Additive
exits priced from the order book depth
No change to request or response shapes. An exit (
POST /v1/positions/exit, trigger exits, signal square-offs) with market protection is priced from the order book level that covers its whole quantity, a small band past it (#36). A stale last trade no longer refuses an exit while the book is live (09:15-15:40 IST); with neither, or with the book level more than five protection bands from the last price, it is refused withstale_quoteand the message says which.