Skip to main content

Overview

Dynamic rules let you make optimization config values change automatically based on time (cron schedules) and conditions (expressions evaluated against portfolio context). Instead of manually updating configs when market conditions change or calendar events occur, you define rules that activate automatically. Common use cases:
  • Increase tax-loss harvesting aggressiveness in December
  • Adjust position weight limits based on AUM
  • Change optimization mode based on portfolio characteristics
  • Apply different parameters for accounts meeting specific criteria

Rule Structure

Dynamic rules are attached to a config (organization, portfolio, or account level) via the dynamic_rules array. Each entry targets a specific config field and contains one or more rules:

Fields

Rule Entry Fields

A rule matches when both its cron schedule and condition are satisfied. An empty cron or condition field is treated as always matching, but at least one of the two must be provided.

Rule Resolution

For each dynamic rule field (e.g. max_weight), the system follows a three-step resolution path:

Step 1: Collect rules from all config levels

Rules from every config level are gathered and given a priority offset so that higher-level configs always take precedence:

Step 2: Find first static value and prune

Walk the config chain from most specific to least. The first level that sets a static value for the field becomes the default. Rules from levels below that level are pruned — rules at the same level still apply.

Step 3: Evaluate remaining rules

Remaining rules are sorted by priority ascending. First matching rule wins — the first rule whose cron and condition both evaluate to true is used. If no rule matches, the default value from step 2 is used. Key concepts:
  • Priority offsets: Account rules keep their raw priority, portfolio rules add 10,000, and org rules add 20,000. This means account-level rules are always evaluated before lower levels.
  • Static value pruning: When a static value is found at a config level, rules from levels below are pruned. Rules at the same level as the static value still apply. This prevents lower-level dynamic rules from overriding an explicit static value set at a higher level.
  • First match wins: Rules are evaluated in ascending priority order. The first rule whose cron and condition both match is used.
  • Fallback: If no rule matches, the static default value from step 2 is used.

Supported Fields

Config Fields

Dynamic rules can target any config field, including:
  • max_weight, min_weight — position weight limits
  • optimization_mode — optimization strategy
  • tax_gamma — tax-loss harvesting aggressiveness
  • cash_buffer, cash_buffer_usd, cash_buffer_cad — cash reserves
  • round_lot_size — trade rounding

Tax Preference Fields

Use the tax_preferences. prefix for tax preference fields:
  • tax_preferences.tax_gamma
  • tax_preferences.short_term_rate
  • tax_preferences.long_term_rate
Use the Get Dynamic Rules Schema endpoint to discover all supported fields, available context variables, functions, and operators for your organization.

Context Variables

Conditions in dynamic rules are evaluated against context variables that describe the portfolio and account at optimization time.

Portfolio-Level Variables

Variables like aum, cash_balance, and position_count describe the current state of the portfolio being optimized.

Account-Level Variables

Variables like organization_name and client_external_id describe the account and organization.

Fundamental Per-Ticker Variables

Variables like market_cap and pe_ratio provide fundamental data for individual securities. These are available when rules are evaluated at the ticker level.

Enrichment Columns

Custom enrichment data columns uploaded to your organization are also available as context variables.
The exact set of available variables depends on your organization’s configuration. Use the schema endpoint to discover what’s available.

Workflow

Step 1: Explore the Schema

Discover available fields, variables, operators, and functions:
View API Reference → The response includes:
  • fields: Config fields that support dynamic rules
  • variables: Context variables available in conditions
  • functions: Functions you can use in expressions (e.g. abs(), max())
  • operators: Supported operators (>, <, ==, and, or, etc.)
  • examples: Example expressions

Step 2: Validate Expressions

Before deploying rules, validate that your condition expressions are syntactically correct:
View API Reference → You can also pass a sample_context to test evaluation:

Step 3: Attach Rules to a Config

Add dynamic rules when creating or updating a config at any level. For example, to add rules to a portfolio config:

Step 4: Simulate Rule Evaluation

Test how rules resolve for a specific account and date without running an optimization:
View API Reference → The response shows:
  • resolved_values: The final config values after rule evaluation
  • context: The context variables used during evaluation
  • rule_evaluations: Which rules matched and which didn’t, with details
You can also pass dynamic_rules directly to simulate rules that haven’t been saved yet.

Step 5: Preview Optimization Impact

See how dynamic rules affect actual optimization results by comparing scenarios. Preview runs asynchronously — you submit a job, then poll for results.

Submit a preview job

POST your scenarios to create a preview job. Each scenario requires a label and context_overrides (e.g. to vary aum or trade_date). You can optionally include as_of_datetime, fundamentals_overrides, and config_overrides.
The endpoint returns 202 Accepted with a job object:
View API Reference →

Poll for results

Use the job ID to check status and retrieve results:
Poll every 2–5 seconds. Most preview jobs complete within 30 seconds.
View API Reference →

List previous jobs

Browse your organization’s preview job history:
View API Reference →

Examples

Year-End Tax-Loss Harvesting

Increase the tax-loss harvesting aggressiveness during December:
Resolution in December (e.g. trade date 2025-12-15):
Resolution outside December (e.g. trade date 2025-06-15):

AUM-Based Weight Limits

Tighten position concentration limits for larger portfolios:
Resolution for a portfolio with 2M AUM:
Resolution for a portfolio with 10M AUM:
Both portfolios match the first rule. If you want different behavior for larger portfolios, put the more specific condition at a lower priority number so it matches first:
Now a 10M AUM portfolio matches priority 0 first and gets 0.05, while a 2M AUM portfolio skips priority 0 and matches priority 1 for 0.08.

Multi-Level Rules with Static Value Pruning

This example shows how rules accumulate across config levels and how a static value prunes lower-level rules. Config state for max_weight:
Step 1 — Collect and offset rules:
Step 2 — Find static value and prune:
Step 3 — Evaluate remaining rules: In December:
In June:
The portfolio’s static max_weight = 0.05 serves two purposes: it becomes the fallback default, and it prunes both the portfolio-level and org-level dynamic rules. Only the account-level rule (which has higher precedence) survives.

Best Practices

  • Simulate before deploying — Always use the simulate endpoint to verify rule behavior before saving rules to a config. Check that the right rules match and produce expected values.
  • Start priorities at 0 — Use sequential integers starting from 0 (0, 1, 2, …). You can leave gaps if you anticipate inserting rules later.
  • Understand static blocking — Be intentional about static values at higher config levels, as they suppress dynamic rules from lower levels for that field.
  • Use the schema endpoint — Discover available fields and variables programmatically rather than hardcoding. The available set may expand over time.
  • Keep conditions simple — Prefer clear, readable expressions. Use the validate endpoint to catch syntax errors early.