Micro-Language Expression Guide¶
This guide explains how to use micro-language expressions and conditions for data analysis and metrics evaluation in the Nuant Quantitative System.
Overview¶
Micro-expressions are a powerful domain-specific language used to define conditions, calculate values, and create dynamic behaviors in simulation configurations. They allow you to reference protocol metrics, perform calculations, and create complex logical conditions.
Usage in Configuration Files¶
Micro-expressions are primarily used within configuration files to define quantities through formulas or conditions. They provide a powerful way to:
Access protocol metrics - Reference values from the simulation environment
Define conditions - Create triggers for actions based on market conditions
Calculate values - Compute amounts dynamically based on current state
Common use cases include:
Conditional execution of actions - Execute trades only when specific market conditions are met
Dynamic parameter calculation - Set position sizes or price ranges based on current market data
Complex decision logic - Combine multiple conditions with logical operators
For detailed information on how to use micro-expressions in configuration files, see Config file schema.
Examples from Configuration Files¶
Price comparison condition:
condition: common.market_spot:{"WETH/USDC"} < 2000.2 OR common.market_spot:{"DAI/WETH"} < 1 / 2000.6
This condition triggers an action when either ETH price falls below $2000.2 or when the DAI/ETH rate indicates ETH is below $2000.6.
Protocol metric evaluation:
dex_pool.dex_spot > 2 AND max of dex_pool.dex_spot between last_update and t > 2
This expression combines a current value check with a historical maximum check over a time window.
Mathematical formula:
dex_pool.dex_spot / 2 + dex_pool.total_value_locked > 2e9
This expression performs arithmetic operations on protocol metrics to create a complex condition.
Basic Syntax¶
This section covers the fundamental syntax elements of the micro-language.
Metrics Structure¶
Metrics are the core building blocks of micro-expressions, allowing you to access protocol and simulation data.
Metrics can be accessed in two forms:
Basic metric without options:
protocol.metric_name
Metric with options:
protocol.metric_name:{positional_option, named_option="value"}
For example, to access the spot price of a specific token pair:
common.market_spot:{"WETH/USDC"}
Note
Using ‘@’ as a prefix triggers a contextual popup in the Nuant’s IDE for any metric, providing documentation and available options.
For a list of available protocol metrics, see:
Uniswap V3 - Metrics for Uniswap V3 protocol
Expression Types¶
The micro-language supports both numerical and boolean expressions, allowing for complex calculations and conditions.
Numerical Expressions¶
Numerical expressions allow you to perform mathematical operations on metrics and values.
The following operators are supported:
Addition:
+
Subtraction:
-
Multiplication:
*
Division:
/
Exponentiation:
**
or^
Parentheses for grouping:
(expression)
Function calls:
function_name(args...)
Numeric literals (e.g.,
123
,45.67
,1.23e4
)Aggregations:
aggregation of expression on window
Example:
(dex_pool.dex_spot * 2) + sqrt(dex_pool.total_value_locked) / 1e6
Boolean Expressions¶
Boolean expressions evaluate to either true or false and are used for conditions.
Comparison operators:
Equal:
=
Less than:
<
Less than or equal:
<=
Greater than:
>
Greater than or equal:
>=
Logical operators:
AND (
and
orAND
)OR (
or
orOR
)Parentheses for grouping:
(boolean_expression)
Boolean literals:
true
,false
Example:
(dex_pool.dex_spot > 1500) AND (dex_pool.liquidity > 1000000)
Aggregation Operations¶
Aggregation operations allow you to analyze metric values over time windows.
Syntax:
<operator> of <expression> on <window>
Where <window>
can be specified as:
between t1 and t2
- A specific time rangebetween last_update and t
- From the last update to the current timeover last n blocks
- Over the last n blocks
Available aggregation operators:
last_value
- Last observed valuemin
- Minimum valuemax
- Maximum valuemean
- Average valuesharpe_ratio
- Sharpe ratio calculation (risk-adjusted return)sortino_ratio
- Sortino ratio calculation (downside risk-adjusted return)calmar_ratio
- Calmar ratio calculation (drawdown-adjusted return)max_drawdown
- Maximum drawdown (largest peak-to-trough decline)volatility
- Volatility measurement (standard deviation of returns)return
- Return calculationabs_return
- Absolute returnewma
- Exponentially weighted moving averagesum
- Sum of values
Example:
max of dex_pool.dex_spot between last_update and t > 2000
Built-in Functions¶
The micro-language includes a variety of built-in mathematical functions to support complex calculations.
Mathematical functions available:
min(a, b, ...)
- Minimum of argumentsmax(a, b, ...)
- Maximum of argumentsabs(x)
- Absolute valuesqrt(x)
- Square rootexp(x)
- Exponential function (e^x)ln(x)
- Natural logarithmpow(x, y)
- Power function (x^y)log10(x)
- Base-10 logarithmlog(x, base)
- Logarithm with specified baseerf(x)
- Error functionnormal_cdf(x)
- Normal cumulative distribution function
Example:
sqrt(dex_pool.dex_spot) > 30
Custom Functions¶
Warning
Custom function definitions are temporarily disabled in the current version.
You can define your own functions to encapsulate complex logic and calculations.
Define custom functions using the following syntax:
function name(arg1, arg2...) {
statements...
}
Supported statements:
Assignment:
identifier = expression
Conditional:
if condition { statements... } else { statements... }
Return:
return expression
Example:
function risk_adjusted_return(price, tvl) {
volatility = sqrt(price)
if volatility > 0 {
return price / volatility + ln(tvl)
} else {
return 0
}
}
risk_adjusted_return(dex_pool.dex_spot, dex_pool.total_value_locked) > 10
Practical Examples¶
This section provides practical examples of micro-expressions for common use cases in configuration files.
Basic Conditions¶
Simple price threshold:
dex_pool.dex_spot > 2000
This condition is true when the spot price in the DEX pool exceeds 2000.
Time-Based Analysis¶
Analyzing metrics over time windows:
max of dex_pool.dex_spot between last_update and t > 2000
This condition checks if the maximum spot price since the last update exceeds 2000.
Volatility detection:
volatility of dex_pool.dex_spot over last 100 blocks > 0.05
This condition is true when price volatility over the last 100 blocks exceeds 5%.
Combined Conditions¶
Combining multiple conditions with logical operators:
(dex_pool.dex_spot > 2000) AND (dex_pool.liquidity > 1000000)
This condition requires both high price and sufficient liquidity.
Market trend analysis:
(dex_pool.dex_spot > mean of dex_pool.dex_spot over last 200 blocks) AND
(volatility of dex_pool.dex_spot over last 50 blocks < 0.03)
This condition identifies an uptrend with low recent volatility.
Complex Calculations¶
Arithmetic operations:
dex_pool.dex_spot / 2 + dex_pool.total_value_locked > 2e9
This expression combines price and TVL metrics in a calculation.
Risk-adjusted metrics:
function risk_score(price, vol) {
return price / (vol * 100)
}
risk_score(dex_pool.dex_spot, volatility of dex_pool.dex_spot over last 100 blocks) > 5
This example defines and uses a custom risk scoring function.
Real-World Use Cases¶
Dynamic liquidity provision:
condition: volatility of common.market_spot:{"WETH/USDC"} over last 50 blocks < 0.02
action: mint_liquidity with narrow_range
This condition triggers liquidity provision only during low volatility periods.
Stop-loss implementation:
condition: common.market_spot:{"WETH/USDC"} < 1800 OR
(max of common.market_spot:{"WETH/USDC"} over last 100 blocks -
common.market_spot:{"WETH/USDC"}) / max of common.market_spot:{"WETH/USDC"} over last 100 blocks > 0.1
action: swap_all_to_stable
This condition triggers a protective action when price falls below 1800 or drops more than 10% from recent maximum.
Troubleshooting¶
This section helps you diagnose and fix common issues with micro-expressions.
Common Errors¶
Missing Market Price Error
If you encounter:
Undefined key 'common.market_price:{"WETH/USD"}'
This indicates that the required market price entry is missing from the evaluator dictionary. Ensure that:
The token pair is correctly specified (check for typos)
The requested market price is available in your simulation
You’re using the correct metric name (e.g., market_spot vs market_price)
Syntax Errors
For syntax errors like:
Error parsing expression: unexpected token at position 15
Check for:
Missing or mismatched parentheses
Incorrect operator usage
Typos in function names or metrics
Missing quotes around string parameters
Time Window Errors
If time window aggregations aren’t working as expected, verify that:
The specified time window is valid for your simulation
The metric has sufficient historical data for the requested window
The window syntax is correct (e.g., between last_update and t)
Best Practices¶
Start simple: Begin with basic expressions and gradually add complexity
Use parentheses: Explicitly group expressions to ensure correct evaluation order
Test incrementally: Validate each part of a complex expression separately
Check metric availability: Ensure all referenced metrics are available in your simulation
Consider edge cases: Account for potential division by zero or missing data
For more help with specific protocols, refer to the protocol-specific documentation:
Uniswap V3 - Uniswap V3 metrics and examples