Features
Developer tools
Search the API, read source, draw reference graphs, and extend classes with factories
How do you find your way around a library with thousands of classes and functions, and extend it? VBT includes developer tools for API search and Python object inspection: search the package, read any object's source and documentation, and draw what each function depends on.
import inspect
from vectorbtpro.utils.module_ import search_package
from vectorbtpro.utils.source import get_source
def accepts_freq(name, obj):
return inspect.isfunction(obj) and "freq" in inspect.signature(obj).parameters
found = search_package("vectorbtpro", accepts_freq)
names = sorted({f"{func.__module__}.{func.__name__}" for func in found.values()})
len(names)14print("\n".join(names[-6:]))vectorbtpro.utils.datetime_.readable_datetime
vectorbtpro.utils.datetime_.to_freq
vectorbtpro.utils.datetime_.to_offset
vectorbtpro.utils.datetime_.to_timedelta
vectorbtpro.utils.datetime_.to_timedelta64
vectorbtpro.utils.schedule_.waitfrom vectorbtpro.utils.datetime_ import infer_index_freq
print("\n".join(get_source(infer_index_freq).splitlines()[:7]))def infer_index_freq(
index: tp.Index,
freq: tp.Optional[tp.FrequencyLike] = None,
allow_offset: bool = True,
allow_numeric: bool = True,
freq_from_n: tp.Union[None, bool, int] = None,
) -> tp.Union[None, int, float, tp.PandasFrequency]:ref_index = vbt.RefIndex(incl_modules="vectorbtpro")
graph = ref_index.build_graph(infer_index_freq)
print("\n".join(graph.get_dependencies(graph.root, relation="direct")))vectorbtpro._typing.FrequencyLike
vectorbtpro._typing.PandasFrequency
vectorbtpro.utils.checks.is_number
vectorbtpro.utils.datetime_.auto_detect_freq
vectorbtpro.utils.datetime_.freq_depends_on_index
vectorbtpro.utils.datetime_.parse_index_freq
vectorbtpro.utils.datetime_.to_freqfig = graph.plot(interactive=False, showlegend=False)
for trace in fig.data:
if trace.name.endswith("_nodes_hl") and len(trace.x) > 0:
labels = [info[1] or info[0] for info in trace.customdata]
trace.update(mode="markers+text", text=labels, textposition="top center")
fig.show()Fourteen module-level functions accept a freq argument. The graph places infer_index_freq and
the seven names it uses inside the modules that define them, which shows where to look when a
frequency is not what you expected.
Discovery
Most questions about VBT can be answered from Python itself:
| Tool | Answers |
|---|---|
vbt.phelp(obj) | What a function takes and what its docstring says |
vbt.pdir(obj) | Which attributes an object has, their kinds, and where each is defined |
vbt.pprint(obj) | What an object holds, formatted as readable nested text |
vbt.ptable(obj) | What an array, DataFrame, or record array holds, as a table |
get_source(obj) | The source code of any function, class, or module |
vbt.get_api_ref(obj), vbt.open_api_ref(obj) | The API documentation page for an object |
vbt.RefIndex | What an object uses, what uses it, and how modules connect |
vbt.get_capabilities() | How many indicators, data sources, metrics, and engines are installed |
deep_getattr resolves a dotted path of attributes and method calls, such as
pf.deep_getattr("trades.expectancy"). For questions in plain language, the
Knowledge search page covers vbt.find_api and vbt.search.
These tools work together when an unfamiliar object or argument blocks your research. Start with
phelp for the call signature, use pdir to find the relevant property or method, then open the
source or API reference for the details. Configured objects expose their constructor arguments in
config, so you can inspect the settings that created a data instance, indicator, or portfolio.
Formatting and annotations
The formatting engine behind vbt.pprint and vbt.phelp renders configured objects, dictionaries,
arrays, and signatures the same way in a terminal and in a notebook, as the
Formatting engine highlight below shows. Annotations carry meaning in a
function's signature: vbt.Param, vbt.Takeable, and vbt.MergeFunc tell the parameterization and
splitting decorators how to treat each argument, as the Annotations highlight below
shows.
Validation and debugging
- Equality:
vbt.is_deep_equalcompares nested objects, arrays, and their metadata, and every configured object hasequals. - Warnings: VBT warnings share one format, and
vbt.WarningsFiltered()silences them inside awithblock. - Hashing:
vbt.hdictand configured objects can be hashed, which is how VBT caches results by their arguments. - Bounds checks: an invalid array index in a custom Numba callback can return incorrect data or
crash the kernel. Setting
boundscheckundernumbain a configuration file makes compiled functions raise an error instead, and Numba'sNUMBA_DISABLE_JIT=1environment variable disables Numba compilation for Python-level debugging. Set it before importing VBT. - Preparers: simulation methods split argument checking from execution. Pass
return_preparer=Trueto inspect the prepared arguments of a portfolio before it runs, orreturn_prep_result=Trueto get the final arrays the simulator would receive, intarget_args.
Inspect what the simulator will receive
Preparers let you check shapes, defaults, and converted arguments before running a long backtest. Here, two assets have different order values but share the same fee:
close = pd.DataFrame(
{"A": [100.0, 105.0, 103.0], "B": [50.0, 49.0, 52.0]},
index=pd.date_range("2025-01-01", periods=3),
)
prepared = vbt.PF.from_orders(
close,
size=np.array([[100.0, 200.0]]),
size_type="value",
fees=0.001,
return_prep_result=True,
)
print(prepared.pf_args["wrapper"].shape)(3, 2)print(prepared.target_args["size"])[[100. 200.]]print(prepared.target_args["fees"])[[0.001]]The target has three rows and two assets. Order values stay in a single row, and the shared fee stays in a single cell, ready for flexible indexing inside the simulator. This makes it easier to see whether an unexpected result starts with the inputs or with the trading logic. The Backtesting engine page shows how to modify a preparation result and run it.
Runtime checks also validate shapes, indexes, and data types. You can use the same assertion helpers in your own functions, while deep equality checks help compare nested outputs after a refactor. For a callback that behaves unexpectedly, inspect a small input slice first, then use bounds checking or Python-level debugging to follow its decisions.
Extending
VBT is built from the same factories it exposes. vbt.IF builds indicator classes, as the
Custom indicators page shows, and vbt.SignalFactory
builds signal generators. Configured classes get declarative fields, cached properties, and shortcut
methods from decorators, and vbt.evaluate evaluates expressions against a context, which is how
indicator expressions and templates find their inputs.
You can keep a custom calculation as a function, expose it as an indicator with named inputs and parameters, or register a compiled implementation and its chunking rules. This lets custom work participate in the same parameter searches and labeled results as built-in calculations. Compute backends and Parallel execution cover those execution choices. For logic that needs current positions and cash, extend the simulation through Event-driven callbacks.
Utilities
Smaller tools cover everyday tasks: searching and replacing values deep inside nested objects,
reading and writing nested keys by path, matching names with regular expressions, managing files and
folders, and rescaling arrays. They are the same helpers VBT uses internally. To save memory,
vbt.settings.wrapping["max_precision"] = 32 casts results to 32-bit floats when they are wrapped
into pandas, at the cost of precision.
Member pages with Python downloads provide examples in Jupytext format, so you can open them as notebooks and adapt them locally. The tutorials give you complete research workflows to inspect alongside the individual API objects.
✅ When analyzing complex codebases like VBT, it can be challenging to keep track of all the interdependencies between modules, classes, and functions. To address this, VBT now includes a functionality that can index the source code of any codebase for object references and generate reference graphs from any specified entry point. These graphs provide a visual representation of how different components relate to each other, making it easier to understand the overall structure and flow of the code.
ref_index = vbt.RefIndex(container_kinds=["module", "class"], incl_modules="pandas")
ref_graph = ref_index.build_graph("pandas")
ref_graph.plot(
interactive="dash",
to_dash_kwargs=dict(fit_to_window=True),
dash_run_kwargs=dict(jupyter_mode="tab")
)Online explorer
Explore the VBT's reference graph in the API → Reference graph.
✅ When writing a function, you can specify the meaning of each argument using an annotation immediately next to the argument. VBT now provides a rich set of in-house annotations tailored to specific tasks. For example, whether an argument is a parameter can be specified directly in the function instead of in the parameterized decorator.
@vbt.cv_split(
splitter="from_rolling",
splitter_kwargs=dict(length=365, split=0.5, set_labels=["train", "test"]),
parameterized_kwargs=dict(random_subset=100, seed=42),
)
def sma_crossover_cv(
data: vbt.Takeable,
fast_period: vbt.Param(condition="x < slow_period"),
slow_period: vbt.Param,
metric
) -> vbt.MergeFunc("concat"):
fast_sma = data.run("sma", fast_period, hide_params=True)
slow_sma = data.run("sma", slow_period, hide_params=True)
entries = fast_sma.real_crossed_above(slow_sma)
exits = fast_sma.real_crossed_below(slow_sma)
pf = vbt.PF.from_signals(data, entries, exits, direction="both")
return pf.deep_getattr(metric)
sma_crossover_cv(
vbt.YFData.pull("BTC-USD", start="4 years ago"),
np.arange(20, 50),
np.arange(20, 50),
"trades.expectancy"
)split set fast_period slow_period
0 train 25 26 2.822879
test 25 26 4.740533
1 train 22 37 16.967189
test 22 37 -16.101936
2 train 30 41 308.879034
test 30 41 14.445511
3 train 29 49 32.328702
test 29 49 13.546335
4 train 27 48 20.695292
test 27 48 6.539824
5 train 22 46 19.143686
test 22 46 -4.664139
6 train 34 45 5.235739
test 34 45 -2.697966
dtype: float64✅ VBT is a comprehensive library that defines thousands of classes, functions, and objects. When working with these, you may want to "look inside" an object to better understand its attributes and contents. Fortunately, there is a formatting engine that can accurately format any in-house object as a human-readable string. Did you know the API documentation is partly powered by this engine? 😉
data = vbt.YFData.pull("BTC-USD", start="2020", end="2021")
vbt.pprint(data) YFData(
wrapper=ArrayWrapper(...),
data=symbol_dict({
'BTC-USD': <pandas.core.frame.DataFrame object at 0x7f7f1fbc6cd0 with shape (366, 7)>
}),
single_key=True,
classes=symbol_dict(),
fetch_kwargs=symbol_dict({
'BTC-USD': dict(
start='2020',
end='2021'
)
}),
returned_kwargs=symbol_dict({
'BTC-USD': dict()
}),
last_index=symbol_dict({
'BTC-USD': Timestamp('2020-12-31 00:00:00+0000', tz='UTC')
}),
tz_localize=datetime.timezone.utc,
tz_convert='UTC',
missing_index='nan',
missing_columns='raise'
)vbt.pdir(data) type path
attr
align_columns classmethod vectorbtpro.data.base.Data
align_index classmethod vectorbtpro.data.base.Data
build_feature_config_doc classmethod vectorbtpro.data.base.Data
... ... ...
vwap property vectorbtpro.data.base.Data
wrapper property vectorbtpro.base.wrapping.Wrapping
xs function vectorbtpro.base.indexing.PandasIndexervbt.phelp(data.get) YFData.get(
columns=None,
symbols=None,
**kwargs
):
Get one or more columns of one or more symbols of data.Related pages
- Backtesting › Backtesting engineSimulate orders, signals, and callbacks across many assets and parameters at once
- Workflow automationSchedule data updates, send Telegram alerts, run tasks in parallel, and track progress
- Configuration and persistenceSave any research object with compression, reload it fast, and keep settings in files
- Optimization and validation › Parameter optimizationSweep millions of parameter combinations with grids, conditions, and random search
Copyright © 2021–2026 Oleg Polakow. All rights reserved.
Site content and documentation are provided for using and evaluating VectorBT PRO and for educational purposes. Any other use, including building or supporting competing products or services, requires prior written consent.