Function reference

Every function that the Calculator and the Sheet accept: its arguments, an example and the example's result.

Every function on this page works in the Calculator and in a Sheet cell. Each entry lists the call, its return value, its arguments, an example and the example's result. The example results use data saved on one date. The same data function typed today returns the latest close.

A data function such as iv30("SPY") returns the latest value for a symbol. Its .series form, such as iv30.series("SPY"), returns the daily history as a series. Series functions take a history and return a number or a new series.

When a call fails, the result line shows an error code and a message. The error reference lists every code and its fix.

Formula syntax

The Calculator treats its whole input as a formula. A Sheet cell is a formula when its content starts with =. Names are not case-sensitive: MEAN and mean are the same function. A dotted name such as iv30.series is a single name.

Operators, from lowest to highest precedence:

Level Operators
Comparison, giving 1 or 0 == != <= >= < >
Add and subtract + -
Multiply, divide, modulo * / %
Power ^
Sign - + before a term
Percent % after a term

Every binary level groups from the left, ^ included. The sign has higher precedence than ^. A percent on the right of + or - is that percent of the left side:

2^3^2 => 64
-2^2 => 4
50+10% => 55
7 % 3 => 1

Multiplication must be explicit: type 2*(3+4). 2(3+4) is an error. Trigonometric functions use degrees unless the Calculator angle button shows rad. A Sheet always uses degrees. Division by zero returns Infinity or NaN, with no error.

On a series or a matrix, +, -, *, / and ^ apply point by point. A plain number applies to every point. * on two matrices is element-wise; use mmul for the matrix product. Two series need the same dates: cut both to the shared dates with align first. A null point on either side gives null at that point.

Data functions

A data function such as vrp("SPY") loads the site's data for a symbol before the formula runs. Its arguments must be typed values, not formulas. The symbol is not case-sensitive. A data function with a tenor, delta or strike uses the nearest point in the data and does not interpolate. A tie goes to the smaller point. A tenor snaps only when the nearest tenor is within 20% of the requested days or 5 days, whichever is larger. A farther tenor gives E_NO_DATA. A delta or a strike snaps at any distance. When the data has not loaded, a data function shows E_NO_DATA, or #N/A in a Sheet. The data loads again on the next run of the formula.

Numbers, logic and math

abs(x)

The absolute value of a number: its size with the sign dropped.

x
any number
abs(-2.5)

Result: 2.5

acos(x)

The angle whose cosine is x, in degrees (in radians when the Calculator's angle button shows rad; the Sheet always uses degrees, where Excel uses radians).

x
a number from -1 to 1
acos(0.5)

Result: 60

asin(x)

The angle whose sine is x, in degrees (in radians when the Calculator's angle button shows rad; the Sheet always uses degrees, where Excel uses radians).

x
a number from -1 to 1
asin(0.5)

Result: 30

atan(x)

The angle whose tangent is x, in degrees (in radians when the Calculator's angle button shows rad; the Sheet always uses degrees, where Excel uses radians).

x
any number
atan(1)

Result: 45

ceil(x)

Rounds a number up to the next whole number.

x
any number
ceil(2.1)

Result: 3

Up means toward plus infinity: ceil(-2.5) is -2.

cos(x)

The cosine of an angle given in degrees (in radians when the Calculator's angle button shows rad; the Sheet always uses degrees, where Excel uses radians).

x
an angle
cos(60)

Result: 0.5

e

Euler's number, 2.71828, the base of ln and exp; type it without parentheses.

e

Result: 2.71828

exp(x)

e raised to the power x; exp(r * t) is the growth of 1 at continuous rate r over t years.

x
any number
exp(0.05)

Result: 1.05127

floor(x)

Rounds a number down to the next lower whole number.

x
any number
floor(-2.5)

Result: -3

Down means toward minus infinity, so negative numbers move away from zero.

ln(x)

The natural logarithm (base e).

x
a positive number
ln(2)

Result: 0.693147

log(x)

The base 10 logarithm.

x
a positive number
log(1000)

Result: 3

Use ln for the natural logarithm.

pi

The number pi, 3.14159; type it without parentheses.

pi

Result: 3.14159

round(x)

Rounds to the nearest whole number; halves round up.

x
any number
round(2.5)

Result: 3

Up means toward plus infinity: round(-2.5) is -2.

sin(x)

The sine of an angle given in degrees (in radians when the Calculator's angle button shows rad; the Sheet always uses degrees, where Excel uses radians).

x
an angle
sin(30)

Result: 0.5

sqrt(x)

The square root of x.

x
a number, 0 or more
sqrt(252)

Result: 15.8745

sqrt(252), about 15.87, turns a daily volatility into an annual one.

tan(x)

The tangent of an angle given in degrees (in radians when the Calculator's angle button shows rad; the Sheet always uses degrees, where Excel uses radians).

x
an angle
tan(45)

Result: 1

Data functions

dist(symbol, tenor, field)

One number from the options-implied price distribution of a symbol at expiry, at the previous trading day's close.

symbol
ticker, e.g. "SPY"
tenor
days to expiry; the nearest listed expiry is used
field
field name as text, e.g. "price_p50", "implied_stdev", "tail_prob_down_10", "ci68_pct_low"
dist("SPY", 30, "price_p50")

Result: 766.58

Price fields are dollars, tail_prob fields are probabilities from 0 to 1, and _pct fields are percent (-8.4 means -8.4%).

dist.pdf(symbol, tenor)

The options-implied probability density of the price at expiry, as a series over strike prices in dollars.

symbol
ticker, e.g. "SPY"
tenor
days to expiry; the nearest listed expiry is used
dist.pdf("SPY", 30)

Result: a series of 149 points, last 2.62981e-7

Density is per dollar of price, so the values are small; x is the strike, not a date.

fred(name)

The latest value of a FRED series, in the series' own units (SOFR is in percent: 3.63 means 3.63%).

name
series name, e.g. "SOFR", "EFFR", "IORB"
fred("SOFR")

Result: 3.63

FRED publishes a day late, so the latest date is usually one trading day older than the options data.

fred.series(name)

The daily history of a FRED series, in the series' own units, dated by observation date.

name
series name, e.g. "SOFR", "EFFR", "IORB"
fred.series("SOFR")

Result: a series of 2094 points, last 3.63

fwd(symbol, dte)

The forward price of a symbol in dollars for the expiry nearest the days you give, at the previous close.

symbol
ticker, e.g. "SPY"
dte
days to expiry; snaps to the nearest listed expiry, never interpolated
fwd("SPY", 30)

Result: 767.421

A tie goes to the shorter expiry.

fwd.curve(symbol)

The forward curve of a symbol: forward prices in dollars as a series over days to expiry.

symbol
ticker, e.g. "SPY"
fwd.curve("SPY")

Result: a series of 26 points, last 785.811

x is days to expiry, not a date, so at() does not apply.

greek(symbol, greek, tenor, strike)

Dealer exposure to one greek at the strike nearest the one you give: minus the greek times open interest.

symbol
ticker, e.g. "SPY"
greek
"gamma", "vanna" or "charm"
tenor
days to expiry; the nearest listed expiry is used
strike
strike in dollars; snaps to the nearest listed strike
greek("SPY", "vanna", 30, 765)

Result: -664.521

Assumes customers are long the open interest, so dealers hold the other side. Per share greek times contracts, with no 100 multiplier.

greek.strikes(symbol, greek, tenor)

Dealer exposure to one greek at every strike for one expiry, as a series over strike prices.

symbol
ticker, e.g. "SPY"
greek
"gamma", "vanna" or "charm"
tenor
days to expiry; the nearest listed expiry is used
greek.strikes("SPY", "vanna", 30)

Result: a series of 151 points, last -0.0658177

greeksum(symbol, tenor, field)

One total from a symbol's greek summary, for the expiry nearest the days you give.

symbol
ticker, e.g. "SPY"
tenor
days to expiry; snaps to the nearest listed expiry within 20% or 5 days, whichever is larger, else E_NO_DATA
field
field name as text, e.g. "net_gamma_exposure", "net_vanna_exposure", "total_put_oi"
greeksum("SPY", 30, "net_gamma_exposure")

Result: -734.06

Exposure fields sum minus the greek times open interest over all strikes, the same sign rule as greek.

hv30(symbol)

A symbol's 30-day historical (realized) volatility at the previous trading day's close, annualized, as a decimal (0.12 means 12%).

symbol
ticker, e.g. "SPY"
hv30("SPY")

Result: 0.1233

hv30.series(symbol)

The daily history of a symbol's 30-day historical volatility, as decimals, through the previous close.

symbol
ticker, e.g. "SPY"
hv30.series("SPY")

Result: a series of 1163 points, last 0.1233

hvpctile(symbol)

Where the latest 30-day historical volatility ranks in the symbol's full history: the percent of days with a lower value, 0 to 100.

symbol
ticker, e.g. "SPY"
hvpctile("SPY")

Result: 38.4351

hvpctile.series(symbol)

The daily history of the historical volatility rank, 0 to 100, each day ranked against the days up to it.

symbol
ticker, e.g. "SPY"
hvpctile.series("SPY")

Result: a series of 1163 points, last 38.4351

iv30(symbol)

A symbol's 30-day implied volatility at the previous trading day's close, as a decimal (0.124 means 12.4%).

symbol
ticker, e.g. "SPY"
iv30("SPY")

Result: 0.124

iv30.series(symbol)

The daily history of a symbol's 30-day implied volatility, as decimals, through the previous close.

symbol
ticker, e.g. "SPY"
iv30.series("SPY")

Result: a series of 1163 points, last 0.124

ivpctile(symbol)

Where the latest 30-day implied volatility ranks in the symbol's full history: the percent of days with a lower value, 0 to 100.

symbol
ticker, e.g. "SPY"
ivpctile("SPY")

Result: 26.9132

This counts days strictly below; pctile counts days at or below, so the two differ slightly.

ivpctile.series(symbol)

The daily history of the implied volatility rank, 0 to 100, each day ranked against the days up to it.

symbol
ticker, e.g. "SPY"
ivpctile.series("SPY")

Result: a series of 1163 points, last 26.9132

ivsurf(symbol, tenor, delta)

Implied volatility from a symbol's surface at the nearest tenor and delta you give, as a decimal, at the previous close.

symbol
ticker, e.g. "SPY"
tenor
days, e.g. 7, 30, 90, 365; snaps to the nearest tenor on the surface within 20% or 5 days, whichever is larger, else E_NO_DATA
delta
signed: positive for calls (0.25 is the 25 delta call), negative for puts; 0.5 and -0.5 are at the money
ivsurf("SPY", 30, -0.25)

Result: 0.155063

The 25 delta put reads higher than the 25 delta call (ivsurf("SPY", 30, 0.25) is 0.1087788221), the usual equity skew.

ivsurf.smile(symbol, tenor)

The volatility smile at one tenor: implied volatility as a series over delta, from -0.5 (puts) to 0.5 (calls).

symbol
ticker, e.g. "SPY"
tenor
days; snaps to the nearest tenor on the surface within 20% or 5 days, whichever is larger, else E_NO_DATA
ivsurf.smile("SPY", 30)

Result: a series of 16 points, last 0.125379

ivsurf.term(symbol, delta)

The volatility term structure at one delta: implied volatility as a series over days to expiry.

symbol
ticker, e.g. "SPY"
delta
signed delta, e.g. 0.5 for at the money, -0.25 for the 25 delta put
ivsurf.term("SPY", 0.5)

Result: a series of 8 points, last 0.161037

straddle(symbol)

The price of a symbol's at the money straddle near 30 days, as a fraction of the stock price, at the previous close (0.028 means 2.8%).

symbol
ticker, e.g. "SPY"
straddle("SPY")

Result: 0.0278514

Uses the listed expiry nearest 30 days, within 15 days.

straddle.series(symbol)

The daily history of the 30-day at the money straddle price, as a fraction of the stock price.

symbol
ticker, e.g. "SPY"
straddle.series("SPY")

Result: a series of 1167 points, last 0.0278514

strangle(symbol)

The price of a symbol's 25 delta strangle near 30 days, as a fraction of the stock price, at the previous close.

symbol
ticker, e.g. "SPY"
strangle("SPY")

Result: 0.0113391

Uses the same expiry as straddle.

strangle.series(symbol)

The daily history of the 30-day 25 delta strangle price, as a fraction of the stock price.

symbol
ticker, e.g. "SPY"
strangle.series("SPY")

Result: a series of 1167 points, last 0.0113391

vix30(symbol)

A 30-day volatility index for a symbol, worked out from its options the way the CBOE VIX is, at the previous close, in percent.

symbol
ticker, e.g. "SPY"
vix30("SPY")

Result: 15.3785

Percent, not a decimal: 15.4 means 15.4%, unlike iv30.

vix30.series(symbol)

The daily history of a symbol's 30-day volatility index, in percent.

symbol
ticker, e.g. "SPY"
vix30.series("SPY")

Result: a series of 1167 points, last 15.3785

vix3m(symbol)

A 91-day volatility index for a symbol, worked out from its options the way the CBOE VIX is, at the previous close, in percent.

symbol
ticker, e.g. "SPY"
vix3m("SPY")

Result: 18.4454

vix30 minus vix3m below 0 means the near term is cheaper than three months out.

vix3m.series(symbol)

The daily history of a symbol's 91-day volatility index, in percent.

symbol
ticker, e.g. "SPY"
vix3m.series("SPY")

Result: a series of 1167 points, last 18.4454

volofvol(symbol)

How much a symbol's 30-day implied volatility moves day to day: the standard deviation of its daily changes over 20 trading days.

symbol
ticker, e.g. "SPY"
volofvol("SPY")

Result: 0.0086393

In the same decimal units as iv30: 0.0086 means daily moves of about 0.86 volatility points.

volofvol.series(symbol)

The daily history of the 20-day standard deviation of daily implied volatility changes, as decimals.

symbol
ticker, e.g. "SPY"
volofvol.series("SPY")

Result: a series of 1163 points, last 0.0086393

The first 20 points are null: the standard deviation needs 20 daily changes.

vrp(symbol)

A symbol's volatility risk premium at the previous close: 30-day implied over 30-day historical volatility, minus 1.

symbol
ticker, e.g. "SPY"
vrp("SPY")

Result: 0.00567721

A ratio, not volatility points: 0.05 means implied volatility is 5% above historical.

vrp.series(symbol)

The daily history of the volatility risk premium, implied over historical volatility minus 1.

symbol
ticker, e.g. "SPY"
vrp.series("SPY")

Result: a series of 1163 points, last 0.00567721

vrpz(symbol)

How unusual the latest volatility risk premium is: its z-score against the last 20 trading days.

symbol
ticker, e.g. "SPY"
vrpz("SPY")

Result: -0.136264

vrpz.series(symbol)

The daily history of the volatility risk premium z-score, each against its own trailing 20 trading days.

symbol
ticker, e.g. "SPY"
vrpz.series("SPY")

Result: a series of 1163 points, last -0.136264

The first 19 points are null: a z-score needs 20 days of history.

Series

align(a, b, ...)

Series a, cut down to the dates every other series also has, so the series can be combined with operators.

a
the series whose values are kept
b, ...
one or more series whose dates a must share
align(iv30.series("SPY"), fred.series("SOFR"))

Result: a series of 1155 points, last 0.1301

a keeps its own values, empty points included. To subtract two series, cut both: align(a, b) - align(b, a).

at(series, date)

The value of a series on a date, or the latest value before it when that date has none.

series
a dated series
date
the date as text, "YYYY-MM-DD"
at(iv30.series("SPY"), "2026-08-01")

Result: 0.1259

It never looks past the date you ask for: a Saturday returns the Friday close, and empty points are skipped.

max(x, more, ...)

The largest of several numbers, or the largest value in a series, ignoring empty points.

x
a number, a series, or roll(...) for a rolling maximum
more, ...
further numbers (numbers only)
max(vix30.series("SPY"))

Result: 52.88

mean(series)

The average of a series, ignoring empty points; over roll(...) it gives a rolling average series.

series
a series or roll(...)
mean(iv30.series("SPY"))

Result: 0.160834

median(series)

The middle value of a series, ignoring empty points.

series
a series or roll(...)
median(vix30.series("SPY"))

Result: 17.7833

min(x, more, ...)

The smallest of several numbers, or the smallest value in a series, ignoring empty points.

x
a number, a series, or roll(...) for a rolling minimum
more, ...
further numbers (numbers only)
min(iv30.series("SPY"))

Result: 0.0922482

pctile(s, n)

Where the latest value ranks in the last n points of a series: the percent of them at or below it, 0 to 100.

s
a series, or roll(...) for the rank on every date
n
window in points; leave out when s is roll(...)
pctile(iv30.series("SPY"), 252)

Result: 17.8571

The latest point counts itself, so the lowest possible rank is 100 / the number of points with a value, not 0.

roll(s, n)

A trailing window of n points over a series, for mean, sum, std, median, min, max, zscore or pctile to run over.

s
a series
n
window length in points
mean(roll(iv30.series("SPY"), 20))

Result: a series of 1163 points, last 0.128415

The result keeps every date: the first n - 1 points are empty.

std(s, n)

The standard deviation of a series, ignoring empty points, dividing by N; with n, over the last n points only.

s
a series, or roll(...) for a rolling series
n
window in points (optional)
std(iv30.series("SPY"), 20)

Result: 0.0117613

The divisor is N, not N - 1.

sum(series)

The total of a series, ignoring empty points; over roll(...) it gives a rolling total series.

series
a series or roll(...)
sum(plot(x, x, 1, 10, 10))

Result: 55

zscore(s, n)

How many standard deviations the latest value sits from the mean (dividing by N); with n, over the last n points only.

s
a series, or roll(...) for the z-score on every date
n
window in points (optional)
zscore(iv30.series("SPY"), 252)

Result: -0.767269

Matrices and regression

col(m, j)

Column j of a matrix, as a column vector.

m
a matrix
j
column position from 0; negative counts from the last column (-1 is the last)
col(mat(2, 2, 1, 2, 3, 4), 0)

Result: a 2x1 matrix [[1], [3]]

corr(a, b, ...)

The correlation of two series, one number from -1 to 1, using only the dates both have.

a
a series, or one matrix whose columns are the variables
b, ...
more series (optional with a matrix)
corr(iv30.series("SPY"), hv30.series("SPY"))

Result: 0.71179

Three or more series, or one matrix, return the full correlation matrix. A date counts only when every series has a value on it.

cov(a, b, ...)

The covariance matrix of two or more series over the dates all of them have, dividing by N.

a
a series, or one matrix whose columns are the variables
b, ...
more series (optional with a matrix)
cov(iv30.series("SPY"), hv30.series("SPY"))

Result: a 2x2 matrix [[0.00259331, 0.00252871], [0.00252871, 0.00486678]]

The diagonal holds each variance. The divisor is N, the number of shared dates, not N - 1.

det(m)

The determinant of a square matrix.

m
a square matrix
det(mat(2, 2, 4, 7, 2, 6))

Result: 10

A singular matrix gives 0.

diag(m)

The diagonal of a square matrix as a column vector, or a diagonal matrix built from a vector.

m
a square matrix or a vector
diag(mat(2, 2, 4, 1, 1, 9))

Result: a 2x1 matrix [[4], [9]]

eigvals(m)

The eigenvalues of a symmetric matrix, as a column vector from largest to smallest.

m
a symmetric matrix, e.g. a covariance matrix
eigvals(mat(2, 2, 2, 1, 1, 2))

Result: a 2x1 matrix [[3], [1]]

A matrix that is not symmetric is an error.

eigvecs(m)

The unit-length eigenvectors of a symmetric matrix, one per column, in the same order as eigvals.

m
a symmetric matrix
eigvecs(mat(2, 2, 2, 1, 1, 2))

Result: a 2x2 matrix [[0.707107, 0.707107], [0.707107, -0.707107]]

Each column's largest entry is made positive, so the signs repeat from run to run.

identity(n)

An n by n identity matrix: ones on the diagonal, zeros elsewhere.

n
size, a whole number from 1 to 256
identity(2)

Result: a 2x2 matrix [[1, 0], [0, 1]]

iloc(s, i, j)

The value at a position in a series, or the cell at row i, column j of a matrix.

s
a series or a matrix
i
series position from 0, negative counts from the end (-1 is the latest); for a matrix, the row from 0
j
matrix column from 0 (matrices only)
iloc(iv30.series("SPY"), -2)

Result: 0.1301

Every position starts at 0, as in row and col: iloc(m, 0, 0) is the top left cell.

mat(rows, cols, values, ...)

Builds a matrix from its size and its values, filled row by row.

rows
number of rows
cols
number of columns
values, ...
rows times cols numbers, row by row
mat(2, 2, 1, 2, 3, 4)

Result: a 2x2 matrix [[1, 2], [3, 4]]

minv(m)

The inverse of a square matrix.

m
a square matrix
minv(mat(2, 2, 4, 7, 2, 6))

Result: a 2x2 matrix [[0.6, -0.7], [-0.2, 0.4]]

A singular matrix is an error. To find x in A x = b, solve is more accurate than minv.

mmul(a, b)

The matrix product of a and b; the * operator multiplies cell by cell instead.

a
a matrix
b
a matrix with as many rows as a has columns
mmul(mat(2, 2, 1, 2, 3, 4), mat(2, 1, 1, 1))

Result: a 2x1 matrix [[3], [7]]

A 1 by 1 result comes back as a plain number, so mmul(transpose(v), v) is a dot product.

norm(m)

The length of a vector, the square root of the sum of squares; for a matrix, the same over every cell.

m
a vector or matrix
norm(mat(2, 1, 3, 4))

Result: 5

ols(y, x, ...)

Least squares regression of y on one or more x series, returned as a column: intercept, then one slope per x.

y
a series or vector to explain
x, ...
one or more series or vectors
ols(iv30.series("SPY"), hv30.series("SPY"))

Result: a 2x1 matrix [[0.0794056], [0.519587]]

Series are matched on the dates where all of them have values.

ols.r2(y, x, ...)

The R squared of the ols regression: the share of y's variance the x series explain, 0 to 1.

y
a series or vector to explain
x, ...
one or more series or vectors
ols.r2(iv30.series("SPY"), hv30.series("SPY"))

Result: 0.506645

ols.se(y, x, ...)

The residual standard error of the ols regression, in y's units, dividing by n - k - 1.

y
a series or vector to explain
x, ...
one or more series or vectors
ols.se(iv30.series("SPY"), hv30.series("SPY"))

Result: 0.0357998

ones(rows, cols)

A matrix of the given size filled with ones.

rows
number of rows
cols
number of columns
ones(2, 3)

Result: a 2x3 matrix [[1, 1, 1], [1, 1, 1]]

row(m, i)

Row i of a matrix, as a row vector.

m
a matrix
i
row position from 0; negative counts from the last row (-1 is the last)
row(mat(2, 2, 1, 2, 3, 4), 1)

Result: a 1x2 matrix [[3, 4]]

solve(A, b)

Solves A x = b for x, given a square matrix A and a column b.

A
a square matrix
b
a matrix with as many rows as A
solve(mat(2, 2, 2, 1, 1, 3), mat(2, 1, 3, 5))

Result: a 2x1 matrix [[0.8], [1.4]]

A singular A is an error.

trace(m)

The sum of the diagonal of a square matrix.

m
a square matrix
trace(mat(2, 2, 1, 2, 3, 4))

Result: 5

transpose(m)

A matrix with its rows and columns swapped.

m
a matrix
transpose(mat(2, 3, 1, 2, 3, 4, 5, 6))

Result: a 3x2 matrix [[1, 4], [2, 5], [3, 6]]

vec(s)

Turns a series into a column vector for matrix work.

s
a series
vec(plot(x^2, x, 1, 3, 3))

Result: a 3x1 matrix [[1], [4], [9]]

An empty point is an error, never 0.

zeros(rows, cols)

A matrix of the given size filled with zeros.

rows
number of rows
cols
number of columns
zeros(2, 2)

Result: a 2x2 matrix [[0, 0], [0, 0]]

Mean reversion

kelly(p, rr)

The Kelly bet size as a fraction of capital: p minus (1 - p) divided by the reward to risk ratio.

p
chance of a win, 0 to 1
rr
average win divided by average loss
kelly(0.6, 1)

Result: 0.2

A negative result means the odds are against the trade.

lag(s, k)

A series shifted k points later: each date gets the value from k points (trading days) before.

s
a series
k
shift, a positive whole number
lag(fred.series("SOFR"), 1)

Result: a series of 2093 points, last 3.62

The result is k points shorter, so cut the original with align(s, lag(s, 1)) before combining the two.

normcdf(x)

The chance that a standard normal value is at or below x.

x
any number, in standard deviations
normcdf(1.96)

Result: 0.975002

ou(s, window)

Fits a mean reverting (Ornstein-Uhlenbeck) model to a daily series and returns a column: kappa, mu, sigma.

s
a daily series, e.g. a rate or a spread
window
points to fit, from the latest back; default 504 (about two years)
ou(fred.series("SOFR"))

Result: a 3x1 matrix [[2.50562], [3.82863], [0.755298]]

A series that does not revert (each day's value does not pull back toward a level) is an error, not a fit.

ou.carry(s, window)

The one-day drift toward the fitted level: kappa x (level - latest) / 252, in the series' units.

s
a daily series
window
points to fit; default 504
ou.carry(fred.series("SOFR"))

Result: 0.00197499

ou.cv(s, window, step, count)

How steady kappa is across rolling refits: the sample standard deviation of kappa over its mean; lower is steadier.

s
a daily series
window
points per refit; default 252
step
points between refits; default 21
count
number of refits; default 20
ou.cv(fred.series("SOFR"))

Result: 0.956396

Uses N - 1, and skips windows that do not revert.

ou.flips(s, window, step, count)

How many times the fitted level mu changes sign from one rolling refit to the next.

s
a daily series
window
points per refit; default 252
step
points between refits; default 21
count
number of refits; default 20
ou.flips(fred.series("SOFR") - 4)

Result: 2

Built for spreads that sit near zero; a level that keeps flipping sign has no stable mean to trade toward.

ou.fpt(s, window, T)

The chance the series touches its fitted level within each of the next T trading days, as a series from 0 to 1.

s
a daily series
window
points to fit; default 504
T
days ahead, 1 to 2001; default 60
ou.fpt(fred.series("SOFR"), 504, 20)

Result: a series of 20 points, last 0.413297

ou.halflife(s, window)

Trading days for half of the gap between the series and its fitted level to close, ln(2) / kappa * 252.

s
a daily series
window
points to fit; default 504
ou.halflife(fred.series("SOFR"))

Result: 69.7126

ou.kappa(s, window)

The speed of mean reversion per year from the fit; a larger kappa pulls the series back faster.

s
a daily series
window
points to fit; default 504
ou.kappa(fred.series("SOFR"))

Result: 2.50562

Assumes 252 trading days a year, one point per trading day.

ou.mu(s, window)

The long run level the fitted model pulls the series toward, in the series' units.

s
a daily series
window
points to fit; default 504
ou.mu(fred.series("SOFR"))

Result: 3.82863

ou.path(s, window, T)

The expected path of the series over the next T trading days from the latest value, as a series over days 1 to T.

s
a daily series
window
points to fit; default 504
T
days ahead, 1 to 2001; default 60
ou.path(fred.series("SOFR"), 504, 20)

Result: a series of 20 points, last 3.66582

ou.pathsd(s, window, T)

The standard deviation around ou.path for each of the next T trading days, in the series' units.

s
a daily series
window
points to fit; default 504
T
days ahead, 1 to 2001; default 60
ou.pathsd(fred.series("SOFR"), 504, 20)

Result: a series of 20 points, last 0.193277

ou.r2(s, window)

The R squared of the fit of each day's value on the day before, 0 to 1.

s
a daily series
window
points to fit; default 504
ou.r2(fred.series("SOFR"))

Result: 0.989845

A slow series scores near 1 whatever its reversion; judge the reversion by kappa and the half-life.

ou.roll(s, window, step, count)

Refits the model on trailing windows stepping back in time: one row per window, newest first, with kappa, mu, sigma and half-life.

s
a daily series
window
points per refit; default 252
step
points between refits; default 21
count
number of refits; default 20
ou.roll(fred.series("SOFR"), 252, 126, 2)

Result: a 2x4 matrix [[5.47756, 3.67625, 0.720592, 31.8889], [2.35644, 3.87713, 0.732045, 74.1259]]

A window that does not revert gives a row of NaN.

ou.sigma(s, window)

The annualized volatility of the series' shocks from the fit, in the series' units per square root of a year.

s
a daily series
window
points to fit; default 504
ou.sigma(fred.series("SOFR"))

Result: 0.755298

ou.sigmastat(s, window)

The long run standard deviation of the series around its fitted level, sigma / sqrt(2 * kappa), in the series' units.

s
a daily series
window
points to fit; default 504
ou.sigmastat(fred.series("SOFR"))

Result: 0.337401

ou.z(s, window)

How far the latest value sits from the fitted level, in long run standard deviations (ou.sigmastat).

s
a daily series
window
points to fit; default 504
ou.z(fred.series("SOFR"))

Result: -0.588713

Time and countdowns

days(n)

Converts days to seconds, for use with until, since and timer.

n
number of days
days(1)

Result: 86400

hours(n)

Converts hours to seconds; hours(6.5) is one regular US stock session.

n
number of hours
hours(6.5)

Result: 23400

mins(n)

Converts minutes to seconds, for use with until, since and timer.

n
number of minutes
mins(5)

Result: 300

now()

The current time as seconds since 1970-01-01 00:00 UTC.

now() - time("14:00")

Result: 1800

The raw value is a very large number; take differences with time() instead.

secs(n)

Seconds, returned unchanged; it reads clearly beside mins, hours and days.

n
number of seconds
secs(90)

Result: 90

since(t)

Seconds since time t; negative while t is still ahead.

t
a time from time(...)
since(time("09:30")) / 3600

Result: 5

time(text)

A clock time as seconds since 1970, from "YYYY-MM-DD HH:MM" or "HH:MM" for today, in your own time zone.

text
the time as text; seconds optional, e.g. "16:00:30"
time("16:00") - time("09:30")

Result: 23400

Times read in the browser's time zone, not New York time.

timer(n)

A countdown from n seconds that stops at 0, counted from the last reset.

n
seconds, e.g. mins(5)
timer(mins(5))

Result: 210

In live mode the countdown starts at the first run of the formula text and restarts when the text changes. In step mode it starts when the clock stops. The reset button restarts it in both modes.

until(t)

Seconds from now until time t; negative once t has passed.

t
a time from time(...)
until(time("16:00")) / 60

Result: 90

Plots

plot(expr, var, lo, hi, n)

Works out an expression at n evenly spaced values of a variable from lo to hi and returns a series to chart.

expr
an expression using the variable
var
a bare variable name, e.g. x
lo
first value
hi
last value
n
number of points, 2 to 2001
plot(normcdf(x), x, -3, 3, 7)

Result: a series of 7 points, last 0.99865

A point where the expression has no finite value stays in place as an empty point.

Sheet references

and(x, ...)

Returns 1 when every argument is non-zero, else 0.

x, ...
one or more numbers or comparisons; 0 counts as false
and(iv30("SPY") > hv30("SPY"), vix30("SPY") < 20)

Result: 1

There is no true or false value: comparisons give 1 or 0.

average(series)

The mean of a series, ignoring empty points; the same as mean.

series
a series, or roll(...) for a rolling average
average(vix30.series("SPY"))

Result: 19.1161

count(series)

How many points of a series hold a number; a single number counts as 1.

series
a series or a number
count(fred.series("SOFR"))

Result: 2094

if(condition, then, else)

Returns the second argument when the condition is non-zero, else the third.

condition
a number or comparison
then
the value when the condition holds
else
the value when it does not
if(iv30("SPY") > hv30("SPY"), 1, -1)

Result: 1

Only the chosen branch is worked out, so if(x > 0, 1 / x, 0) never divides by zero.

not(x)

Returns 1 when x is 0, else 0.

x
a number or comparison
not(vix30("SPY") > 20)

Result: 1

or(x, ...)

Returns 1 when any argument is non-zero, else 0.

x, ...
one or more numbers or comparisons; 0 counts as false
or(vix30("SPY") > 20, ivpctile("SPY") > 80)

Result: 0

sheet(book, ref)

Reads a cell as a number, or a range as a series, from a sheet widget on the same page.

book
the sheet's name as text, e.g. "Book1"
ref
a cell or range as text, e.g. "A1" or "A1:A10"
sum(sheet("Book1", "A1:A10"))

The read refreshes every second while the calculator runs live.

sheet.mat(book, ref)

Reads a range from a sheet widget on the same page as a matrix, keeping its rows and columns.

book
the sheet's name as text, e.g. "Book1"
ref
a range as text, e.g. "A1:B3"
det(sheet.mat("Book1", "A1:B2"))

Every cell must hold a number: an empty cell is an error, never 0.

stdevp(series)

The standard deviation of a series dividing by N (population); the same as std with one argument.

series
a series or roll(...)
stdevp(iv30.series("SPY"))

Result: 0.0509245

There is no stdev (N - 1) function.