What Is VaR Limit Checking in CloddsBot?

CloddsBot enforces a VaR (Value-at-Risk) limit by calculating the portfolio's potential loss before executing any trade and aborting orders that would push risk beyond the threshold defined in config.yaml.

VaR limit checking in CloddsBot acts as a circuit breaker for the automated trading strategy. Located in the scripts/lighter-bridge/bridge.py file of the alsk1992/CloddsBot repository, this safeguard ensures that high-risk orders never reach the Lighter exchange, protecting capital from excessive drawdowns.

How the VaR Limit Check Works

The risk validation pipeline runs synchronously before every order placement. When the bot receives a command to open or modify a position, it executes three discrete steps:

  1. Calculate Current VaR – The bot retrieves live market data via lighter.get_tickers() and computes the current portfolio Value-at-Risk using historical simulation or Monte-Carlo methods in _calculate_var().
  2. Project Post-Trade Risk – The system simulates the portfolio state after the proposed order fills to determine the projected VaR.
  3. Enforce the Limit – The _check_var_limit() function compares the projected risk against the var_limit value loaded from config.yaml. If the projected VaR exceeds the limit, the order aborts immediately.

Implementation Details in the Lighter Bridge

The core logic resides in scripts/lighter-bridge/bridge.py, which serves as the integration layer between the bot's command interface and the Lighter exchange API.

The Limit Checking Function

The private helper _check_var_limit() performs the actual enforcement. It is invoked by both _place_limit_order() and _place_market_order() before any network request is sent to the exchange. This ensures that risk evaluation happens client-side, eliminating latency costs for rejected orders.


# scripts/lighter-bridge/bridge.py

async def _check_var_limit(lighter, proposed_order):
    current_var = await _calculate_var(lighter)
    projected_var = await _project_var(lighter, proposed_order)
    
    var_limit = lighter.config.get("var_limit", 0.05)  # Default 5%

    
    if projected_var > var_limit:
        lighter.log.warning(
            f"VaR limit breached: {projected_var:.2%} > {var_limit:.2%}"
        )
        return False
    return True

If the function returns False, the parent order method returns a rejection dictionary rather than proceeding to lighter.api.place_limit_order().

Order Placement Flow

Before executing a trade, the bridge validates risk:


# scripts/lighter-bridge/bridge.py

async def _place_limit_order(lighter, req):
    # Risk gate

    if not await _check_var_limit(lighter, req):
        return {"status": "rejected", "reason": "VaR limit exceeded"}
    
    # Safe to proceed

    return await lighter.api.place_limit_order(req)

Identical logic protects _place_market_order(), ensuring no market order can bypass the risk check.

Configuring the VaR Threshold

The risk tolerance is user-configurable via the bot's central configuration file. At startup, main.py loads config.yaml and injects the parameters into the bridge instance.

Example config.yaml:


# Risk management settings

var_limit: 0.07  # Maximum 7% portfolio VaR allowed

The default fallback of 0.05 (5%) protects users who omit the key, but production deployments should explicitly set this value based on their capital allocation strategy.

Practical Usage Example

When a user or automated strategy attempts to place an order that breaches the limit, the bot surfaces the rejection transparently:

@bot.command(name="limitbuy")
async def limit_buy(ctx, price: float, amount: float):
    result = await bot.lighter._place_limit_order(
        bot.lighter, 
        {"side": "buy", "price": price, "amount": amount}
    )
    
    if result["status"] == "rejected":
        await ctx.send(f"🚫 Order blocked: {result['reason']}")
        return
    
    await ctx.send("✅ Limit order placed")

This pattern ensures that Discord or CLI users receive immediate feedback when risk constraints prevent execution.

Summary

  • VaR limit checking prevents order execution when projected portfolio risk exceeds a configurable threshold.
  • Location: Primary logic lives in scripts/lighter-bridge/bridge.py within the _check_var_limit() function.
  • Configuration: Set the var_limit key in config.yaml (default 5%).
  • Protection: Both limit and market orders validate against the limit before calling the Lighter API.
  • Entry Point: main.py loads configuration and initializes the bridge with these risk parameters.

Frequently Asked Questions

How is the VaR calculated in CloddsBot?

The _calculate_var() function in scripts/lighter-bridge/bridge.py computes Value-at-Risk by analyzing current positions against recent price volatility. It uses either historical simulation of returns or a Monte-Carlo approach to estimate the potential loss at a given confidence interval over the configured time horizon.

What happens if I don't specify a var_limit in config.yaml?

If the configuration key is missing, the code defaults to 0.05 (5% VaR) as a conservative safety net. However, explicit configuration is recommended to align the bot's risk profile with your trading strategy.

Can the VaR limit check be bypassed for emergency trades?

No. The _check_var_limit() call is hardcoded into both _place_limit_order() and _place_market_order() without an override flag. To execute a trade exceeding current risk limits, you must temporarily raise the var_limit value in config.yaml and restart the bot so main.py reloads the configuration.

Where does the bot get market data for VaR calculations?

The bridge component calls lighter.get_tickers() to fetch real-time price data from the Lighter exchange API. This data feeds the _calculate_var() function to ensure risk projections reflect current market conditions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →