CLI & Plugins¶
CLI¶
cli
¶
Command-line interface for qufin.
Provides subcommands for portfolio optimization, option pricing, risk analysis, and benchmarking.
Uses argparse (stdlib) as the primary parser. When click is
installed the CLI gains automatic shell completion via
click's built-in support; otherwise argparse is fully functional.
Usage¶
::
qufin optimize --universe sp500 --method qaoa --cardinality 20
qufin price --type european --s 100 --k 105 --method iqae
qufin risk --portfolio portfolio.csv --method quantum_var --alpha 0.99
qufin benchmark --problem 15 --algorithms qaoa,vqe,mvo --output results.json
CLIResult
dataclass
¶
write_output(result, output_path, fmt='json')
¶
Serialize a CLIResult and optionally write to disk.
Parameters¶
result : CLIResult
The result to serialize.
output_path : str | None
File path to write. If None, returns the serialized string
without writing.
fmt : str
Output format: "json", "csv", or "parquet".
Returns¶
str The serialized output (for json/csv) or the path written (for parquet).
Raises¶
ValueError If fmt is not supported.
handle_optimize(args)
¶
Handle the optimize subcommand.
handle_price(args)
¶
Handle the price subcommand.
handle_risk(args)
¶
Handle the risk subcommand.
handle_benchmark(args)
¶
Handle the benchmark subcommand.
build_parser()
¶
install_completion(shell='bash')
¶
Plugins¶
plugins
¶
Plugin system for qufin: backend discovery, strategy registration, data sources.
Provides entry-point-based backend discovery, decorator-based strategy registration, and a pluggable data source interface.
Entry Points¶
Third-party packages can register backends via the qufin.backends
entry-point group in their pyproject.toml::
[project.entry-points."qufin.backends"]
my_backend = "my_package.backend:MyBackend"
The backend class must inherit from :class:qufin.backends.base.Backend.
Strategy Plugins¶
Custom optimization or pricing strategies can be registered with the
:func:register_strategy decorator::
from qufin.plugins import register_strategy
@register_strategy("my_optimizer", category="portfolio")
def my_optimizer(returns, cov, **kwargs):
# custom optimization logic
return weights
Data Source Plugins¶
Custom data sources implement :class:DataSourcePlugin::
from qufin.plugins import DataSourcePlugin, register_data_source
class MyDataSource(DataSourcePlugin):
name = "my_source"
def fetch(self, tickers, start, end, **kwargs):
# return pandas DataFrame
...
def validate(self):
return True # check credentials, connectivity, etc.
register_data_source(MyDataSource())
PluginInfo
dataclass
¶
Metadata describing a discovered plugin.
Attributes¶
name : str
Plugin name (entry-point name or registration name).
module : str
Dotted module path where the plugin is defined.
plugin_type : str
One of "backend", "strategy", "data_source".
loaded : bool
Whether the plugin object has been successfully loaded.
error : str | None
Error message if loading failed.
metadata : dict[str, Any]
Arbitrary extra metadata.
DataSourcePlugin
¶
Bases: ABC
Abstract base class for data source plugins.
Subclasses must set a name attribute and implement fetch
and validate methods.
Examples¶
class CSVSource(DataSourcePlugin): ... name = "csv" ... def fetch(self, tickers, start, end, **kwargs): ... import pandas as pd ... return pd.read_csv(kwargs["path"]) ... def validate(self): ... return True
fetch(tickers, start, end, **kwargs)
abstractmethod
¶
PluginError
¶
Bases: Exception
Raised when a plugin cannot be loaded or validated.
discover_backends()
¶
Discover backends registered via the qufin.backends entry-point group.
Returns¶
dict[str, PluginInfo] Mapping of backend name to plugin info.
load_backend(name)
¶
register_strategy(name, category='general', description='')
¶
Decorator to register a custom strategy function.
Parameters¶
name : str
Unique name for the strategy.
category : str
Category (e.g. "portfolio", "pricing", "risk").
description : str
Human-readable description of the strategy.
Returns¶
Callable Decorator that registers the function and returns it unchanged.
Examples¶
@register_strategy("momentum_qaoa", category="portfolio", ... description="QAOA with momentum overlay") ... def momentum_qaoa(returns, cov, **kwargs): ... pass
get_strategy(name)
¶
list_strategies(category=None)
¶
unregister_strategy(name)
¶
clear_strategies()
¶
Remove all registered strategies.
register_data_source(source)
¶
get_data_source(name)
¶
unregister_data_source(name)
¶
Remove a data source from the registry.
clear_data_sources()
¶
Remove all registered data sources.