Skip to content

Mathematical Functions

Functions for numeric casting, rounding, aggregation, statistical analysis, and financial risk conversions. Functions marked vectorized operate element-wise on arrays.

from everysk.sdk.engines import Expression
expression_engine = Expression()


Casting & Cleaning

cast_float

cast_float(value, default=None)

Vectorized. Attempts to cast value to a float. Returns default if the cast fails (non-numeric strings, None, NaN, inf).

expression_engine.solve('cast_float("1.5")')
# 1.5

expression_engine.solve('cast_float("invalid")')
# None

expression_engine.solve('cast_float("abc", 0.0)')
# 0.0

drop_nan

drop_nan(arr)

Removes all non-finite values from arrNaN, inf, and None are discarded. All elements are first cast to float.

import numpy as np

expression_engine.solve('drop_nan(arr)', {'arr': np.array([1.0, float('nan'), None, 2.0, float('inf')])})
# [1., 2.]


Rounding

round

round(value, precision=0)

Vectorized. Rounds value to precision decimal places. Returns None if value or precision is None.

expression_engine.solve('round(5.123, 2)')
# 5.12

expression_engine.solve('round(-5.567)')
# -6.0

floor

floor(value, precision=0)

Vectorized. Rounds value down (toward negative infinity) to precision decimal places.

expression_engine.solve('floor(5.789, 1)')
# 5.7

expression_engine.solve('floor(-5.567, 2)')
# -5.57

ceil

ceil(value, precision=0)

Vectorized. Rounds value up (toward positive infinity) to precision decimal places.

expression_engine.solve('ceil(1.111, 2)')
# 1.12

expression_engine.solve('ceil(-1.9)')
# -1.0

fix

fix(value, precision=0)

Vectorized. Rounds value toward zero to precision decimal places (truncation).

expression_engine.solve('fix(1.789, 1)')
# 1.7

expression_engine.solve('fix(-1.789, 1)')
# -1.7

rint

rint(value)

Vectorized. Rounds value to the nearest integer. When exactly halfway between two integers, rounds to the nearest even one (banker's rounding).

expression_engine.solve('rint(2.5)')
# 2.0

expression_engine.solve('rint(3.5)')
# 4.0

clip

clip(value, min_value=None, max_value=None)

Vectorized. Clamps each element to the range [min_value, max_value]. Pass None to leave a bound open. At least one bound must be provided.

expression_engine.solve('clip(value, 1.0, 4.0)', {'value': 5.0})
# 4.0

expression_engine.solve('clip(value, 1.0, 4.0)', {'value': 0.5})
# 1.0

import numpy as np
expression_engine.solve('clip(values, 0.0, None)', {'values': np.array([-1.0, 0.5, 2.0])})
# [0.0, 0.5, 2.0]


Aggregation

sum

sum(value)

Returns the sum of all elements. NaN and None are treated as 0.

import numpy as np

expression_engine.solve('sum(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 6.0

expression_engine.solve('sum(values)', {'values': np.array([1.0, float('nan'), None, 3.0])})
# 4.0

prod

prod(value)

Returns the product of all elements. NaN and None are treated as 1.

import numpy as np

expression_engine.solve('prod(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 6.0

max

max(value, default=0.0)

Returns the maximum value. Returns default if value is empty.

import numpy as np

expression_engine.solve('max(values)', {'values': np.array([1.0, 3.0, 2.0])})
# 3.0

min

min(value, default=0.0)

Returns the minimum value. Returns default if value is empty.

import numpy as np

expression_engine.solve('min(values)', {'values': np.array([1.0, 3.0, 2.0])})
# 1.0

absmax

absmax(value, default=0.0)

Returns the element with the largest absolute value. Returns default if value is empty.

import numpy as np

expression_engine.solve('absmax(values)', {'values': np.array([-5.0, 2.0, 3.0])})
# -5.0


Cumulative

cumsum

cumsum(value)

Returns an array of running totals. NaN and None are treated as 0.

import numpy as np

expression_engine.solve('cumsum(values)', {'values': np.array([1.0, 2.0, 3.0])})
# [1., 3., 6.]

cumprod

cumprod(value)

Returns an array of running products. NaN and None are treated as 1.

import numpy as np

expression_engine.solve('cumprod(values)', {'values': np.array([1.0, 2.0, 3.0])})
# [1., 2., 6.]

diff

diff(value)

Returns first differences — each element minus its predecessor. The output has one fewer element than the input.

import numpy as np

expression_engine.solve('diff(values)', {'values': np.array([1.0, 2.0, 4.0, 7.0])})
# [1., 2., 3.]


Statistical

median

median(value)

Returns the median. Returns 0.0 if value is empty.

import numpy as np

expression_engine.solve('median(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 2.0

mean

mean(value)

Returns the arithmetic mean. Returns 0.0 if value is empty.

import numpy as np

expression_engine.solve('mean(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 2.0

average

average(value, weights=None)

Returns the weighted average using weights. If weights is None or sums to 0, returns the simple mean.

import numpy as np

expression_engine.solve('average(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 2.0

expression_engine.solve('average(values, weights)', {
    'values': np.array([1.0, 2.0, 3.0]),
    'weights': np.array([1.0, 2.0, 3.0])
})
# 2.3333333333333335

std

std(value)

Returns the standard deviation. Returns 0.0 if value is empty.

import numpy as np

expression_engine.solve('std(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 0.816496580927726

var

var(value)

Returns the variance. Returns 0.0 if value is empty.

import numpy as np

expression_engine.solve('var(values)', {'values': np.array([1.0, 2.0, 3.0])})
# 0.6666666666666666

percentile

percentile(value, percentile, interpolation='linear')

Returns the value at the given percentile (0–100). interpolation controls behavior when the target falls between two data points: 'linear', 'lower', 'higher', 'midpoint', or 'nearest'. Returns 0.0 if value is empty.

import numpy as np

expression_engine.solve('percentile(values, 50.0)', {'values': np.array([1.0, 2.0, 3.0, 4.0, 5.0])})
# 3.0

quantile

quantile(value, quantile, interpolation='linear')

Like percentile but accepts a quantile in the range 0–1 instead of 0–100. Returns 0.0 if value is empty.

import numpy as np

expression_engine.solve('quantile(values, 0.5)', {'values': np.array([1.0, 2.0, 3.0])})
# 2.0

correlate

correlate(arr_x, arr_y, mode='valid')

Computes the discrete, linear cross-correlation of arr_x with arr_y. Both arrays are cast to float (defaulting to 0). mode can be 'valid', 'full', or 'same'.

import numpy as np

expression_engine.solve('correlate(x, y)', {
    'x': np.array([1.0, 2.0, 3.0]),
    'y': np.array([1.0, 2.0, 3.0])
})
# [14.]

ma

ma(arr, window)

Computes the rolling (moving) average of arr over window periods. Elements are cast to float (defaulting to 0.0). The output has len(arr) - window + 1 elements.

import numpy as np

expression_engine.solve('ma(arr, 2)', {'arr': np.array([1.0, 2.0, 3.0, 4.0])})
# [1.5, 2.5, 3.5]

return

return(arr, window)

Computes the period return: the difference between each value and the value window steps earlier. The vacated front positions are treated as 0.

import numpy as np

expression_engine.solve('return(arr, 1)', {'arr': np.array([1.0, 2.0, 3.0])})
# [0., 1., 1.]


Transformations

exp

exp(value)

Vectorized. Returns \(e^{\text{value}}\). Returns None if value is None.

expression_engine.solve('exp(1.0)')
# 2.718281828459045

log

log(value)

Vectorized. Returns the natural logarithm of value. Returns None if value is None.

expression_engine.solve('log(2.718281828459045)')
# 1.0

log2

log2(value)

Vectorized. Returns the base-2 logarithm of value. Returns None if value is None.

expression_engine.solve('log2(8.0)')
# 3.0

log10

log10(value)

Vectorized. Returns the base-10 logarithm of value. Returns None if value is None.

expression_engine.solve('log10(100.0)')
# 2.0

power

power(value, exponent)

Vectorized. Returns value raised to exponent. Returns None if value is None.

expression_engine.solve('power(2.0, 3.0)')
# 8.0

square

square(value)

Vectorized. Returns value squared. Shorthand for power(value, 2). Returns None if value is None.

expression_engine.solve('square(5.0)')
# 25.0

sqrt

sqrt(value)

Vectorized. Returns the square root of value. Returns None if value is None.

expression_engine.solve('sqrt(9.0)')
# 3.0

cbrt

cbrt(value)

Vectorized. Returns the cube root of value. Returns None if value is None.

expression_engine.solve('cbrt(27.0)')
# 3.0

abs

abs(value)

Vectorized. Returns the absolute value. Returns None if value is None.

expression_engine.solve('abs(-5.0)')
# 5.0

sign

sign(value)

Vectorized. Returns the sign of value: -1.0 for negative, 0.0 for zero, 1.0 for positive. Returns None if value is None.

expression_engine.solve('sign(-3.0)')
# -1.0

expression_engine.solve('sign(0.0)')
# 0.0

scale

scale(value, lower_limit=-1.0, upper_limit=1.0)

Linearly rescales the elements of value so that the minimum maps to lower_limit and the maximum maps to upper_limit. Elements are cast to float (defaulting to 0.0).

import numpy as np

expression_engine.solve('scale(values, 0.0, 1.0)', {'values': np.array([0.0, 50.0, 100.0])})
# [0.0, 0.5, 1.0]


Risk Metrics

annualize

annualize(value, horizon=5.0, year_base=252.0)

Annualizes a periodic value using the square-root-of-time rule scaled by horizon and year_base (trading days per year, defaults to 252). Returns None if value is None.

expression_engine.solve('annualize(0.1, 5.0, 252.0)')
# 0.709929573971954

vol_to_var

vol_to_var(value, confidence="0.95")

Converts a volatility figure to Value at Risk (VaR) at the given confidence level, assuming normality. Returns None if value is None.

expression_engine.solve('vol_to_var(0.1, "0.95")')
# -0.16448536269514724

vol_to_cvar

vol_to_cvar(value, confidence="0.95")

Converts a volatility figure to Conditional Value at Risk (CVaR) at the given confidence level. Returns None if value is None.

expression_engine.solve('vol_to_cvar(0.1, "0.95")')
# -0.20627128075074264

var_to_vol

var_to_vol(value, confidence="0.95")

Inverts vol_to_var: converts a VaR figure back to an implied volatility. Returns None if value is None.

expression_engine.solve('var_to_vol(0.1, "0.95")')
# -0.06079568319117692