quantlab.factor.view.FactorView#

class quantlab.factor.view.FactorView(config)[source]#

Bases: Factor

Root class of the views of config.factor.

Every store query is the wrapped factor’s, through the view:

store_path

None: a view has no store of its own

store_uses()

the wrapped factor’s store, this view its handle

store_range()

the wrapped factor’s

calendar

the wrapped factor’s (its output bars, ADR 0051)

bar_before

the wrapped factor’s

bar_after

the wrapped factor’s

owns_store()

False: a view has no store of its own

stored_symbols()

the wrapped factor’s, cut by _kept_symbols

output_symbols()

the wrapped factor’s, cut by _kept_symbols

read, compute

the wrapped factor’s, cut, then _view_panel

writes

refused: build, extend, write_rows, append_rows, extendable_range; the guard refuse_unless_owner always raises

The outputs are the wrapped factor’s names, dataset is the wrapped factor’s, and cell_bytes and keep_compiled are the wrapped factor’s, since a view computes nothing of its own beside it. A subclass overrides _kept_symbols to keep some symbols only and _view_panel to change the panel. A view has no store of its own and writes none: the store is built and extended with its owner, chunk by chunk when it would not fit in memory (quantlab.factor.chunking).

Parameters:
configFactorViewConfig

The wrapped factor and the subclass’s own fields.

Raises:
ValueError

If warmup_bars is not 0, file_path or resample_freq is set, or factor_names are not the wrapped factor’s.

Examples

With owner a factor that built its store of c and m5 on symbols 1..5 and roster a dataset on symbols 2, 3 and 4:

>>> view = RosterFactor(RosterConfig(factor=owner, roster=roster))
>>> view.store_path, view.store_uses()[0].path == owner.store_path, view.owns_store()
(None, True, False)
>>> view.stored_symbols()
['2', '3', '4']
append_rows(rows, end)[source]#

Refused: a view has no store; append the rows with the store’s owner.

Examples

>>> view.append_rows(owner.compute("2024-02-01", "2024-02-10"), "2024-02-10")
Traceback (most recent call last):
ValueError: RosterFactor.extend(): a view has no store of its own; ...
bar_after(date, n)[source]#

Return the bar n bars after date on the wrapped factor’s calendar.

See Factor.bar_after for the rules.

Examples

>>> view.bar_after("2024-01-05", 1) == view.config.factor.bar_after("2024-01-05", 1)
True
bar_before(date, n)[source]#

Return the bar n bars before date on the wrapped factor’s calendar.

See Factor.bar_before for the rules and errors.

Examples

>>> view.bar_before("2024-01-08", 1) == view.config.factor.bar_before("2024-01-08", 1)
True
build(start, end)[source]#

Refused: a view has no store; build the wrapped store with its owner.

Examples

>>> view.build("2024-01-01", "2024-01-30")
Traceback (most recent call last):
ValueError: RosterFactor.build(): a view has no store of its own; ...
calendar(start, end)[source]#

Return the wrapped factor’s bars from start to end, both inclusive.

A view’s panel is on the wrapped factor’s bars, so its calendar is the wrapped factor’s (Factor.calendar), not its dataset’s: a view of a resampled factor answers with the resampled bars.

Examples

With daily a momentum on one-minute bars (two days of four bars each from 2024-01-02) resampled to "1d", a roster over it answers in days while its own dataset still answers in minutes:

>>> view = RosterFactor(RosterConfig(factor=daily, roster=roster))
>>> view.calendar("2024-01-02", "2024-01-03")
DatetimeIndex(['2024-01-02', '2024-01-03'], dtype='datetime64[ns]', freq=None)
>>> view.config.dataset.calendar("2024-01-02", "2024-01-03")
DatetimeIndex(['2024-01-02 00:00:00', '2024-01-02 00:01:00',
               '2024-01-02 00:02:00', '2024-01-02 00:03:00',
               '2024-01-03 00:00:00', '2024-01-03 00:01:00',
               '2024-01-03 00:02:00', '2024-01-03 00:03:00'],
              dtype='datetime64[ns]', freq=None)
cell_bytes()[source]#

Return the wrapped factor’s cell_bytes; the view computes through it.

compute(start, end)[source]#

Compute the wrapped factor on its whole dataset, keep the view’s symbols, then view it.

A cross-sectional factor standardizes over its whole dataset, so the wrapped factor is never computed on the kept symbols alone.

Parameters:
start, endstr, datetime.date or pd.Timestamp

The range to compute, both inclusive.

Examples

>>> view.compute("2024-01-05", "2024-01-10")["symbol"].values.tolist()
['2', '3', '4']
property config#

The factor’s normalised config: name and factor_names filled in.

Examples

>>> factor.config is config
False
>>> factor.config.name, config.name
('quantlab.factor.predefined.momentum.Momentum', None)
config_cls#

The config class from_config rebuilds this factor with.

alias of FactorViewConfig

extend(end)[source]#

Refused: a view has no store; extend the wrapped store with its owner.

Examples

>>> view.extend("2024-02-10")
Traceback (most recent call last):
ValueError: RosterFactor.extend(): a view has no store of its own; ...
extendable_range(end)[source]#

Refused: a view has no store to extend; ask the store’s owner.

Examples

>>> view.extendable_range("2024-02-10")
Traceback (most recent call last):
ValueError: RosterFactor.extend(): a view has no store of its own; ...
keep_compiled()[source]#

Keep the wrapped factor’s compiled graph inside the block.

output_symbols()[source]#

Return the symbols compute outputs: the wrapped factor’s, those the view keeps.

Examples

>>> view.output_symbols()
['2', '3', '4']
owns_store()[source]#

Return False: a view has no store of its own, so it writes none (ADR 0029).

Examples

>>> view.owns_store()
False
read(start, end, symbols=None)[source]#

Return the wrapped factor’s store from start to end, as the view gives it.

A view that keeps some symbols only reads the wrapped factor on those; otherwise symbols is passed on unchanged.

Parameters:
start, endstr, datetime.date or pd.Timestamp

The range to return, both inclusive.

symbolssequence, optional

The symbols to read, among stored_symbols(); None reads them all.

Raises:
ValueError

If symbols names a symbol the view does not keep, or the wrapped factor’s read refuses the request.

Examples

>>> view.read("2024-01-05", "2024-01-10")["symbol"].values.tolist()
['2', '3', '4']
refuse_unless_owner(method)[source]#

Raise: a view never owns a store, so every write is refused (ADR 0029).

A chunked build (quantlab.factor.chunking.ChunkedBuilder) asks this when it is handed a factor, so a view is refused before anything is computed.

Parameters:
methodstr

The write being refused, named in the message.

Raises:
ValueError

Always.

Examples

>>> view.refuse_unless_owner("build")
Traceback (most recent call last):
ValueError: RosterFactor.build(): a view has no store of its own; ...
rewind(end)[source]#

Refused: a view has no store; rewind the wrapped store with its owner.

Examples

>>> view.rewind("2024-01-15")
Traceback (most recent call last):
ValueError: RosterFactor.rewind(): a view has no store of its own; ...
property store_path#

Return None: a view keeps no store of its own (ADR 0029).

The store read reads is the wrapped factor’s, declared by store_uses.

Examples

>>> view.store_path is None
True
store_range()[source]#

Return the wrapped factor’s recorded store range.

Examples

>>> view.store_range() == view.config.factor.store_range()
True
store_uses()[source]#

Return the wrapped factor’s store, read with this view as its handle.

A view reads the store its wrapped factor declares ("reads", with the view’s store_range()); it never owns it. The wrapped factor declares the store itself as well; see Component.store_uses.

Examples

>>> [(use.path == owner.store_path, use.relation) for use in view.store_uses()]
[(True, 'reads')]
stored_symbols()[source]#

Return the symbols read can return: the wrapped factor’s, those the view keeps.

Examples

>>> view.stored_symbols()
['2', '3', '4']
write_rows(rows, start, end)[source]#

Refused: a view has no store; write the rows with the store’s owner.

Examples

>>> view.write_rows(owner.compute("2024-01-01", "2024-01-30"), "2024-01-01", "2024-01-30")
Traceback (most recent call last):
ValueError: RosterFactor.build(): a view has no store of its own; ...