PriceSeries

Defined in fynance.core

class PriceSeries(values, index=None, name=None, freq=None)[source]

Bases: object

Thin, numpy-backed financial time-series.

Wraps a 1-D array of values together with a temporal index and light metadata (name, freq). It composes a numpy array rather than subclassing it, which keeps numpy interop (np.asarray(ps) works) without the fragility of ndarray subclassing.

Parameters:
valuesarray-like

1-D sequence of values (coerced to float64).

indexarray-like, optional

Temporal index of the same length. Defaults to 0..n-1 (int64).

namestr, optional

Series name.

freqstr, optional

Sampling frequency tag (e.g. "1d"), purely informational.

Attributes:
valuesnumpy.ndarray

Read-only float64 1-D array of values.

indexnumpy.ndarray

1-D array aligned with values.

namestr or None

Series name.

freqstr or None

Frequency tag.

Examples

>>> ps = PriceSeries([100., 101., 99.], name="px")
>>> len(ps)
3
>>> ps[1]
101.0
apply(func)[source]

Apply an element-wise function to the values.

copy()[source]

Return a copy of this series.

cumulative()[source]

Equity curve of this return series: cumprod(1 + r).

drop_na()[source]

Drop NaN observations (and their index entries).

fillna(value=0.0)[source]

Replace NaN observations by a constant value.

classmethod from_numpy(values, index=None, name=None, freq=None)[source]

Build a PriceSeries from numpy arrays.

classmethod from_polars(data, value_col=None, index_col=None, freq=None)[source]

Build a PriceSeries from a polars Series or DataFrame.

A polars.Series maps directly to the values. For a polars.DataFrame, value_col selects the value column (defaults to the single non-index numeric column) and index_col (or the first temporal column) becomes the index.

pipe(func, *args, **kwargs)[source]

Apply a free function to the values, re-wrapping when possible.

Delegates to the rich transform library without bloating this class: ps.pipe(rsi, window=14) calls rsi(ps.values, window=14). If the result is a 1-D array of the same length it is wrapped back into a PriceSeries (same index); otherwise the raw result is returned.

pnl(positions)[source]

Strategy returns of a position book on this return series.

Causal: the position is shifted forward one step, so the position decided at t-1 earns the return at t (pnl_t = position_{t-1} * r_t). The first observation is NaN (no prior position).

Parameters:
positionsarray-like

Position series aligned with this return series.

Returns:
PriceSeries

Strategy return series.

to_numpy(copy=True)[source]

Return the values as a numpy array (copied by default).

to_prices(base=1.0, kind='pct')[source]

Reconstruct a price path from this return series (inverse of to_returns).

Parameters:
basefloat

Initial price prepended to the path.

kind{“pct”, “log”, “raw”}

Must match the convention the returns were computed with.

Returns:
PriceSeries

Price path of length len(self) + 1.

to_returns(kind='pct', dropna=True)[source]

Convert a price path to a return series.

Parameters:
kind{“pct”, “log”, “raw”}

pct -> p_t / p_{t-1} - 1; log -> ln(p_t / p_{t-1}); raw -> p_t - p_{t-1}.

dropnabool

Drop the (undefined) first observation. If False, a leading NaN is kept so the length is preserved.

Returns:
PriceSeries

The return series (strictly causal: r_t uses only p_t and p_{t-1}).

Examples

>>> PriceSeries([100., 110., 99.]).to_returns("pct").values
array([ 0.1, -0.1])
to_torch(dtype=None, device=None)[source]

Return the values as a torch.Tensor (lazy torch import).