Back to Blog

How to Implement Position and Exposure Limits in SaaS Trading APIs: India 2026 Guide

Pre-trade exposure checks look simple until concurrent orders expose a check-then-act race condition that lets two orders jointly blow through a limit neither breaches alone. This guide covers the tiered limit architecture, the database locking fix, and SEBI's April 2026 algo trading framework for India.

Viprasol Tech Team
17 min read
Updated 2026

How to Implement Position and Exposure Limits in SaaS Trading APIs: India 2026 Guide

TLDR

Position and exposure limits in a SaaS trading API are automated pre-trade checks that reject or flag an order before it reaches the market if it would push an account, a symbol, or a whole tenant past a configured risk threshold. The architecture question is straightforward — check monetary exposure, position count, and per-symbol concentration before every order is accepted. The hard engineering problem is concurrency: two orders arriving within milliseconds of each other can both pass a naive "check current exposure, then allow" test and jointly blow through the limit, because the check and the update are not atomic. For platforms operating in India, SEBI's algo trading framework — effective April 1, 2026 — adds a second, non-negotiable layer: every algo order needs a broker-assigned Algo-ID, and any SaaS platform providing algo access must operate as an agent of a registered broker, not connect to exchanges directly.

What Position and Exposure Limits Actually Enforce

A position limit caps the size or count of open positions an account or tenant can hold — maximum lots, maximum number of concurrent open trades, or maximum position in a single symbol. An exposure limit caps the monetary risk across all open positions combined, typically expressed as a percentage of account equity or a fixed monetary ceiling. Both are pre-trade checks: they run before an order is accepted, not after, because rejecting an order that would breach a limit is far cheaper than unwinding one that already executed.

Per QuestDB's explanation of pre-trade risk checks, these controls validate orders against position limits, order size, price bands, and credit thresholds before the order reaches the market — and in institutional systems, this validation typically adds only microseconds to order processing time, because the checks run inline with order submission rather than as a separate downstream step.

If you are building this into a trading platform from the ground up, Viprasol builds custom risk management systems and trading API integrations for SaaS platforms.

Why This Is Harder in a Multi-Tenant SaaS Than a Single Account

A single-account EA only ever needs to check its own exposure. A SaaS trading API serving multiple tenants has to check limits at several levels simultaneously, and get the hierarchy right:

  • Per-order: Does this single order exceed the maximum position size allowed?

  • Per-symbol, per-tenant: Does accepting this order push the tenant's total exposure in this symbol past its limit?

  • Per-tenant, aggregate: Does it push the tenant's total exposure across all symbols past their account-level limit?

  • Platform-wide: Does it push the platform's aggregate exposure to a broker or liquidity provider past a limit the platform itself is bound by?

Institutional pre-trade risk systems handle this with a tiered structure. As Pico's pre-trade risk documentation describes it, absolute limits can be set globally or per-client, with clients able to further tighten their own limits within that global ceiling — a hierarchy where a tenant can be more conservative than the platform default, but never less.

Types of Limits to Implement

Limit Type

What It Checks

Typical Enforcement Point

Monetary exposure

Total open risk as % of equity or fixed ceiling

Pre-trade, before order acceptance

Position count

Maximum number of concurrent open positions

Pre-trade, before order acceptance

Per-symbol concentration

Maximum exposure to any single instrument

Pre-trade, aggregated across tenant's open orders

Price band / order size

Order is not a fat-finger error relative to market price

Pre-trade, single-order validation

Platform-wide aggregate

Total exposure the platform itself is willing to carry

Cross-tenant aggregation, checked continuously

The Race Condition Problem

This is the part that actually breaks in production and rarely shows up in testing with low concurrency. A naive implementation checks current exposure, compares it to the limit, and if it passes, allows the order — as three separate steps. If two orders for the same tenant arrive within milliseconds of each other, both can read the same "current exposure" value before either has written its update, both pass the check independently, and both get accepted — jointly exceeding the limit that was supposed to block exactly this.

This is a textbook check-then-act race condition, and the fix is standard database concurrency control, applied specifically to the exposure check:

-- Pessimistic locking: lock the tenant's exposure row for the
-- duration of the check-and-update, so a second concurrent order
-- physically cannot read a stale value.

BEGIN;

SELECT current_exposure, exposure_limit FROM tenant_risk_state WHERE tenant_id = $1 FOR UPDATE; -- blocks any other transaction from reading this row -- until this transaction commits or rolls back

-- application code checks: current_exposure + new_order_risk <= exposure_limit

UPDATE tenant_risk_state SET current_exposure = current_exposure + $2 WHERE tenant_id = $1;

COMMIT; -- lock released, next queued order can now proceed

Per Vlad Mihalcea's analysis of locking strategies, pessimistic locking is the right tool specifically when conflicts are likely and correctness matters more than raw throughput — which describes exposure checking exactly, since two orders for the same tenant arriving close together is common, not a rare edge case, on any active trading platform. Optimistic locking (a version column, checked at commit time with a retry on conflict) is a reasonable alternative for lower-contention resources, but for a shared exposure counter under real concurrent load, the row lock is the simpler correct answer.

The row lock should be held for the shortest possible window — read, check, update, commit — never held across a slower operation like calling out to an external pricing API, or the lock itself becomes a throughput bottleneck under load.

When a Single Database Lock Isn't Enough: Multi-Server Deployments

The row-lock pattern above assumes every order-processing instance talks to the same database, which handles the common case. It breaks down once the platform scales to multiple application servers behind a load balancer, if any code path checks and updates exposure in application memory or a local cache before the database write — two servers can each hold a stale in-memory view even though the underlying database row is correctly locked. For that scenario, the lock needs to live at the layer shared by every server, not inside any one of them.

Redis-based distributed locking, and specifically the Redlock algorithm, addresses this by requiring a quorum of independent Redis nodes to agree on a lock before it is considered held — a client acquires the lock only if a majority of nodes confirm it, which keeps the lock valid even if one node fails or a replica has not yet caught up after a failover. The practical guidance from production deployments is to treat Redlock as the fast-path coordination mechanism, paired with a database-level constraint (a check constraint or a unique-key conflict) as a safety net — the distributed lock handles the common case efficiently, and the database constraint catches whatever the lock coordination misses during a network partition or node failure.

For most single-database SaaS platforms, the pessimistic row lock alone is sufficient and simpler to reason about. Distributed locking becomes worth the added operational complexity specifically once exposure state is read or cached across multiple independent server processes that do not all share one database transaction.

Why This Isn't Theoretical: The Knight Capital Precedent

The clearest real-world illustration of what happens when pre-trade risk checks fail is not a SaaS platform but the single most expensive software deployment error in trading history. On August 1, 2012, Knight Capital Group — then one of the largest market makers in U.S. equities — deployed new trading code to eight production servers, but the deployment only reached seven; the eighth retained dormant code from a 2003 feature. Over the next 45 minutes, the malfunctioning server accumulated unintended positions totaling 397 million shares and $7.65 billion in exposure, and Knight lost approximately $440 million before the system could be shut down.

The root cause most relevant to exposure-limit architecture specifically: Knight's order-routing system accepted and executed orders regardless of whether the firm actually had the capital or risk capacity to support them, because pre-trade risk controls were not enforced at that layer. The exchange itself had no way to know Knight lacked the capacity, since checking that is explicitly the broker's own responsibility, not the exchange's. U.S. regulators subsequently required Rule 15c3-5 — the Market Access Rule — mandating that broker-dealers maintain pre-trade risk controls sufficient to prevent exactly this kind of erroneous, uncontrolled order flow.

The lesson for a SaaS trading API is direct: a pre-trade exposure check is not a nice-to-have feature bolted onto order routing — it is the control that stands between a software bug and a catastrophic, irreversible loss, and it needs to be enforced at the layer that cannot be bypassed by a partial deployment, a stale server, or a routing path that skips the check under load.

Worked Example: How the Race Actually Happens

The failure mode is easier to see with a timeline. A tenant has a $10,000 exposure limit and is currently sitting at $9,000 of open exposure:

Time

Without Locking

With Row Locking

T+0ms

Order A ($800) reads exposure: $9,000

Order A acquires lock, reads exposure: $9,000

T+2ms

Order B ($800) reads exposure: $9,000 (stale)

Order B blocks, waiting for Order A's lock

T+3ms

Order A checks: $9,000 + $800 = $9,800 ≤ $10,000. Passes.

Order A checks, updates to $9,800, commits, releases lock

T+4ms

Order B checks against its own stale read: $9,000 + $800 = $9,800 ≤ $10,000. Also passes.

Order B acquires lock, reads correct current value: $9,800

Result

Both orders accepted. Actual exposure: $10,600 — $600 over the limit.

Order B correctly checks $9,800 + $800 = $10,600 > $10,000. Rejected as intended.

Neither order individually exceeds the limit — the limit is only breached by the two of them together, which is exactly the scenario a per-order check without locking cannot catch. This is not a rare edge case on an active platform; any tenant running more than one strategy, or any retail user with a browser tab and a mobile app both submitting orders, can trigger it.

Practical Example: Tiered Limits Across Tenants

A concrete tier structure for a small multi-tenant platform:

Level

Limit

Who Can Change It

Platform default

$50,000 aggregate exposure per tenant

Platform operator only

Tenant override

Tenant sets $10,000 (tighter than default)

Tenant, only tighter than platform default

Per-symbol sub-limit

Max $3,000 in any single symbol

Tenant, within their own aggregate limit

Platform-wide aggregate

$2,000,000 across all tenants combined

Platform operator, bound by broker relationship capacity

The enforcement order matters: a new order is checked against its own per-symbol sub-limit first, then the tenant's aggregate limit, then the platform-wide aggregate — rejecting at the first level that fails, without needing to evaluate the others. This ordering also keeps the common case fast, since most orders never come close to the platform-wide ceiling and that check can often be a cheap read against a cached aggregate rather than a fresh cross-tenant query on every single order.

India-Specific Considerations: SEBI's Algo Trading Framework

This is not legal advice. SEBI's algo trading rules should be reviewed with a compliance professional before launching a SaaS trading platform in India. See Viprasol's important disclaimers for more context.

SEBI's new algo trading framework, effective April 1, 2026, materially changes what a SaaS trading API can do architecturally. Every order placed by an algorithm now carries an exchange-assigned Algo-ID, allowing exchanges to trace every automated order back to its source. Structurally, the framework establishes a principal-agent relationship: the stock broker is the principal, and any algo provider — including a SaaS platform — is treated as the broker's agent. This means a SaaS trading API cannot connect directly to exchanges in India; it must operate through a partnership with a SEBI-registered broker, who becomes legally responsible for every algo order that runs through the platform.

There is a materiality threshold that matters for smaller platforms: strategies placing fewer than 10 orders per second generally do not require separate SEBI or exchange registration, with the broker handling Strategy ID tagging instead of the platform needing its own formal algo registration. This Orders-Per-Second threshold is a meaningful design input — a SaaS platform's rate-limiting and exposure-check architecture should be aware of where its tenants sit relative to this threshold, since crossing it changes the platform's regulatory obligations.

The framework also mandates specific API security requirements: static IP whitelisting is now mandatory for API access, OAuth-based authentication is the only permitted authentication method, and two-factor authentication is required for every API session. These are not optional hardening measures for an India-facing trading SaaS — they are the baseline compliance requirement, and should be built into the platform's authentication layer from the start rather than retrofitted later.

The framework also mandates a kill switch: brokers, and by extension the platforms operating as their agents, must be able to instantly terminate all active orders and running algo scripts for a tenant or strategy, alongside order throttling and comprehensive audit trails for every algo trade. This is a distinct control from the exposure limits described above — an exposure limit prevents a single order or accumulation of orders from breaching a threshold, while a kill switch is the emergency stop for a strategy that is behaving unexpectedly regardless of whether any individual order has technically breached a limit yet. A production-grade SaaS platform needs both: pre-trade exposure checks to prevent gradual limit breaches, and a kill switch reachable by the broker (and ideally the tenant) to halt a runaway strategy immediately, independent of the exposure-check logic.

Common Mistakes When Implementing Exposure Limits

Check-then-act without a lock. This is the mistake that causes real losses — it passes every test written with sequential, low-concurrency requests and only fails under genuine concurrent load, which is exactly when the limit matters most.

Checking exposure only at order placement, not on fills. A partial fill, a slipped fill, or a fill at a worse price than expected can push realized exposure past what was checked at order-placement time. Exposure needs to be reconciled against actual fills, not just intended order size.

Holding a database lock across a slow external call. Locking the exposure row and then calling out to a pricing API or broker before releasing it turns a microsecond-scale check into a bottleneck that serializes all of a tenant's order flow behind the slowest external dependency.

No platform-wide aggregate check. Per-tenant limits can all individually pass while the platform's combined exposure to a single broker or liquidity provider exceeds what that relationship can actually support.

Treating the SEBI OPS threshold as a one-time check. A tenant's order rate can grow over time. The platform needs to monitor where each tenant sits relative to the 10 orders/second threshold on an ongoing basis, not just at onboarding.

No kill switch independent of the exposure-check logic. If the only way to stop a malfunctioning strategy is through the same exposure-limit code path that might itself be the source of the bug, there is no true emergency stop — a kill switch needs to be a separate, simpler control that does not depend on the risk-check system behaving correctly.

Assuming in-memory caching is safe across multiple servers. A local cache of exposure state on one application server can silently diverge from the source of truth once the platform scales horizontally — this is a variant of the same check-then-act race condition, one layer up, and is why distributed locking or a single authoritative database becomes necessary at scale.

Build vs Buy: When to Get a Developer

Use a broker's existing risk engine if your SaaS platform is thin — routing orders through a single registered broker's infrastructure that already enforces its own limits — and you do not need custom per-tenant risk tiers.

Build a custom pre-trade risk layer if you are running a genuine multi-tenant platform with tenant-specific limits, need the tiered hierarchy described above, or are integrating multiple brokers or liquidity sources behind a single API. See how Viprasol approaches trading API integration for platforms with this level of complexity.

Related Glossary Terms

For more definitions, visit the AI and software glossary.

Pre-Trade Risk Check: An automated validation that runs before an order reaches the market, checking it against position limits, exposure limits, and price bands.

Pessimistic Locking: A database concurrency control that locks a row for the duration of a transaction, preventing any other transaction from reading or modifying it until the lock is released.

Optimistic Locking: A concurrency control using a version column, checked at commit time, that rolls back and retries on conflict rather than locking upfront.

Algo-ID: An exchange-assigned identifier, mandatory in India from April 2026, that traces every algorithmic order back to the specific algorithm and provider that generated it.

Orders Per Second (OPS) Threshold: The SEBI-defined rate — 10 orders per second — below which a trading strategy generally does not require separate algo registration.

Kill Switch: A mandated control, distinct from pre-trade exposure limits, that can instantly terminate all active orders and running algo scripts for a strategy or tenant regardless of whether any exposure threshold has been breached.

Redlock: A distributed locking algorithm for Redis that requires a quorum of independent nodes to agree on a lock before it is considered held, used to coordinate exposure checks safely across multiple application servers.

FAQ

What is the difference between a position limit and an exposure limit?

A position limit caps the size or count of open positions — maximum lots or maximum concurrent trades. An exposure limit caps the total monetary risk across all open positions combined, usually as a percentage of account equity. Production systems typically enforce both together.

How do I prevent two simultaneous orders from both exceeding the limit?

Use database-level concurrency control — pessimistic row locking (SELECT ... FOR UPDATE) for the check-and-update sequence, or optimistic locking with a version column and retry-on-conflict for lower-contention cases. A naive check-then-act without locking will pass testing and fail under real concurrent load.

Does my SaaS trading platform need to register as an algo provider in India?

Under SEBI's framework effective April 1, 2026, algo providers must operate as agents of a SEBI-registered broker rather than connecting to exchanges directly. Strategies below 10 orders per second generally do not require separate formal registration, with the broker handling Strategy ID tagging instead — but this is not legal advice, and the correct classification should be confirmed with a compliance professional.

What API security is mandatory for a trading platform operating in India?

SEBI's 2026 framework mandates static IP whitelisting, OAuth-based authentication as the only permitted method, and two-factor authentication for every API session. These should be built into the platform from the start.

Should exposure be checked at order placement or at fill?

Both. Checking only at order placement misses exposure changes from partial fills or slippage between the checked price and the executed price. A production system reconciles exposure against actual fills, not just the intended order size.

What is a trading platform kill switch, and how is it different from an exposure limit?

An exposure limit is a pre-trade check that rejects individual orders once a threshold would be breached. A kill switch is an emergency stop, mandated under SEBI's 2026 framework, that can instantly terminate all active orders and running algo scripts for a strategy or tenant — it needs to work even if the exposure-check logic itself is malfunctioning, which is why it should be implemented as an independent control rather than folded into the same code path.

Do I need Redis or a distributed lock, or is a database row lock enough?

A pessimistic database row lock is sufficient for most single-database SaaS platforms and is simpler to operate correctly. A distributed lock like Redlock becomes necessary once exposure state is checked or cached across multiple independent application servers that do not share one database transaction — without it, two servers can each act on a stale local view even while the database itself is correctly locked.

What actually happened in the Knight Capital incident, and how does it apply to a SaaS platform?

A partial code deployment left one production server running dormant legacy logic that accepted and executed orders without checking whether the firm had the capital or risk capacity to support them — the pre-trade risk control that should have caught this was effectively absent at that layer, and $440 million was lost in 45 minutes. For a SaaS trading API, the lesson is that the exposure check needs to be enforced at a layer that cannot be silently bypassed by a partial deployment, a stale server, or a code path that skips it under load.


Building a multi-tenant trading platform and need the exposure and risk architecture done right the first time? Book a free 30-minute consultation to discuss your platform's risk requirements.

exposure limitssaas trading apipre-trade risk checksrace condition database lockingsebi algo trading rulesmulti tenant architecture
Share this article:

About the Author

V

Viprasol Tech Team

Custom Software Development Specialists

The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 1000+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement.

MT4/MT5 EA DevelopmentAI Agent SystemsSaaS DevelopmentAlgorithmic Trading

Ready to Automate Your Trading?

Get a custom Expert Advisor built by professionals with verified MyFXBook results.

Free consultation • No commitment • Response within 24 hours

Viprasol · Trading Software

Need a custom EA or trading bot built?

We specialise in MT4/MT5 Expert Advisor development — prop-firm compliant, forward-tested before live, MyFXBook verifiable. 5.0★ Upwork, 100% Job Success, 1000+ projects shipped.