Skip to main content
Version: Python

emstd_tick

emstd_tick creates a tick-based (row-based) EMSTD (exponential moving standard deviation) for an update_by table operation. The formula for the tick-based EMSTD of a column XX is:

a=e1τa = e^{\frac{-1}{\tau}}

s02=0s^2_0 = 0

si2=a(si12+(1a)(xixˉi1)2)s^2_i = a*(s^2_{i-1} + (1-a)*(x_i - \bar{x}_{i-1})^2)

si=si2s_i = \sqrt{s^2_i}

Where:

  • τ\tau is decay_ticks, an input parameter to the method.
  • xˉi\bar{x}_i is the exponential moving average of XX at step ii
  • sis_i is the exponential moving standard deviation of XX at step ii.
  • xix_i is the current value.
  • ii denotes the time step, ranging from i=1i=1 to i=n1i = n-1, where nn is the number of elements in XX.
note

In the above formula, s02=0s^2_0 = 0 yields the correct results for subsequent calculations. However, sample variance for fewer than two data points is undefined, so the first element of an EMSTD calculation will always be NaN.

Syntax

emstd_tick(
decay_ticks: int,
cols: list[str],
op_control: OperationControl = None,
) -> UpdateByOperation

Parameters

ParameterTypeDescription
decay_ticksint

The decay rate in ticks (rows).

colslist[str]

The columns to be operated on. These can include expressions to rename the output (e.g., NewCol = Col). If None, EMSTD is calculated for all columns.

op_control optionalOperationControl

Defines how special cases should behave. The default value is None, which uses default OperationControl settings.

Returns

An UpdateByOperation to be used in an update_by table operation.

Examples

One column, no groups

The following example calculates the tick-based (row-based) EMSTD of the X column, renaming the resultant column to EmStdX. The decay rate, decay_ticks, is set to 2. No grouping columns are specified, so the EMSTD is calculated over all rows.

from deephaven.updateby import emstd_tick
from deephaven import empty_table

source = empty_table(10).update(["Letter = (i % 2 == 0) ? `A` : `B`", "X = i"])

result = source.update_by(ops=emstd_tick(decay_ticks=2, cols=["EmStdX = X"]))

One EMSTD column, one grouping column

The following example builds on the previous by specifying Letter as the key column. Thus, the EMSTD is calculated on a per-letter basis.

from deephaven.updateby import emstd_tick
from deephaven import empty_table

source = empty_table(10).update(["Letter = (i % 2 == 0) ? `A` : `B`", "X = i"])

result = source.update_by(
ops=emstd_tick(decay_ticks=2, cols=["EmStdX = X"]), by=["Letter"]
)

Multiple EMSTD columns, multiple grouping columns

The following example builds on the previous by calculating the EMSTD of multiple columns in the same UpdateByOperation. Also, the groups are defined by unique combinations of letter and boolean in the Letter and Truth columns, respectively.

from deephaven.updateby import emstd_tick
from deephaven import empty_table

source = empty_table(20).update(
[
"Letter = (i % 2 == 0) ? `A` : `B`",
"Truth = randomBool()",
"X = i",
"Y = randomInt(5, 10)",
]
)

result = source.update_by(
ops=emstd_tick(decay_ticks=2, cols=["EmStdX = X", "EmStdY = Y"]),
by=["Letter", "Truth"],
)

Multiple UpdateByOperations, multiple grouping columns

The following example builds on the previous by calculating the EMSTD of multiple columns, each with its own UpdateByOperation. This allows each EMSTD to have its own decay rate. The different decay rates are reflected in the renamed resultant column names.

from deephaven.updateby import emstd_tick
from deephaven import empty_table

source = empty_table(20).update(
[
"Letter = (i % 2 == 0) ? `A` : `B`",
"Truth = randomBool()",
"X = i",
"Y = randomInt(5, 10)",
]
)

emstd_x = emstd_tick(decay_ticks=2, cols=["EmStdX2rows = X"])
emstd_y = emstd_tick(decay_ticks=4, cols=["EmStdY5rows = Y"])

result = source.update_by(ops=[emstd_x, emstd_y], by=["Letter", "Truth"])