| Title: | Research Workflows for Macro and Cross-Asset Analysis |
| Version: | 0.0.6.2 |
| Author: | Oliver Zhou [aut, cre] |
| Maintainer: | Oliver Zhou <oliver.yxzhou@gmail.com> |
| Description: | Reusable research workflows for macro-financial and cross-asset analysis. The package sits on top of data packages such as 'investdatar' and focuses on transforming existing market and macro data into analysis-ready research tables, factor and indicator constructions, event and regime overlays, sensitivity estimates, scenario comparisons, and research-grade visualization outputs. Portfolio risk-return comparisons use the mean-variance framework of Markowitz (1952) <doi:10.1111/j.1540-6261.1952.tb01525.x>. Research-side volatility simulations include the generalized autoregressive conditional heteroskedasticity model of Bollerslev (1986) <doi:10.1016/0304-4076(86)90063-1>. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/OliverLDS/investlabr |
| BugReports: | https://github.com/OliverLDS/investlabr/issues |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0) |
| Imports: | data.table (≥ 1.12.4), ggplot2 (≥ 3.5.0), ggrepel, grid, gridExtra, jsonlite, patchwork, quadprog, rlang, scales, stats, utils, yaml, Rcpp |
| LinkingTo: | Rcpp |
| Suggests: | svglite, testthat (≥ 3.0.0) |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | yes |
| Packaged: | 2026-10-06 02:45:56 UTC; runner |
| Repository: | CRAN |
| Date/Publication: | 2026-10-15 17:50:02 UTC |
investlabr: Research workflows for macro and cross-asset analysis
Description
'investlabr' provides reusable research workflows that sit on top of data-access packages such as 'investdatar'. The package focuses on turning existing macro and market datasets into analysis-ready tables, factors, event and regime views, sensitivity estimates, scenario comparisons, and research-grade visuals.
Details
Relative to related packages:
- 'investdatar' gets and stores the data - 'strategyr' turns strategy logic into executable trading decisions - 'investlabr' helps explore, visualize, and communicate investment ideas
'investlabr' may include lightweight and simplified backtesting helpers for exploratory research and communication, but it is not intended to be the package that decides live actions or produces broker-ready execution logic.
Intended module families include:
- 'prep_*' for research data preparation - 'factor_*' for macro and cross-asset factor construction - 'event_*' and 'regime_*' for time-based interpretation layers - 'sense_*' for sensitivity and exposure estimation - 'sim_*' for scenario and structural simulations - 'viz_*' and 'brief_*' for publication-ready output
The package does not own raw data downloading, source sync, execution, portfolio accounting, or LLM orchestration.
Author(s)
Maintainer: Oliver Zhou oliver.yxzhou@gmail.com
Authors:
Oliver Zhou oliver.yxzhou@gmail.com
See Also
Useful links:
Report bugs at https://github.com/OliverLDS/investlabr/issues
Calculate a conservative artifact data date
Description
Calculates the minimum of the latest usable observation date for every required input series. This prevents a high-frequency series from making a mixed-frequency artifact appear fresher than its stalest required input.
Usage
brief_data_as_of(series, date_col = "date", completed_before = NULL)
Arguments
series |
Named list of date vectors or data frames containing a date column. Inputs should already exclude observations that were not actually consumed by the artifact. |
date_col |
Date-column name used for data-frame inputs. |
completed_before |
Optional exclusive upper date bound. For Yahoo data, pass the current UTC date to exclude a potentially incomplete current-day bar. |
Value
An ISO date string representing the latest common usable observation.
Examples
data_date <- brief_data_as_of(list(
daily = as.Date(c("2025-01-06", "2025-01-07")),
weekly = as.Date(c("2025-01-01", "2025-01-08"))
))
entry <- brief_plot_registry_entry_v3(
id = "example-board", title = "Illustrative research board", collection = "macro",
asset_class = "Rates", indicator_family = "Yield Curve", region = "United States",
frequency = "Daily", source = "Synthetic data", expected_cadence = "weekly",
rendered_at = "2025-01-09T12:00:00Z", data_as_of = data_date,
metadata_updated_at = "2025-01-01", status = "ready",
plot_image = "plots/example.svg", thumbnail = "thumbnails/example.png", tags = "example"
)
# This example validates metadata without requiring image files.
path <- tempfile(fileext = ".json")
brief_plot_registry_write(list(entry), path, schema_version = "3.0",
generated_at = "2025-01-09T12:01:00Z")
brief_plot_registry_validate(path, require_assets = FALSE)
unlink(path)
Build a deprecated schema 2.0 research-artifact registry entry
Description
This constructor is retained for source compatibility. New code should use
brief_plot_registry_entry_v3(). Legacy dates are never interpreted as
artifact render times or editorial metadata dates.
Usage
brief_plot_registry_entry(
id,
title,
collection = NULL,
asset_class,
indicator_family,
region,
frequency,
source,
last_updated,
status = NULL,
plot_image,
thumbnail,
tags,
subtitle = "",
summary = "",
description_md = "",
section = "",
source_detail = character(),
curation_priority = 0,
plot_html = "",
related_ids = character(),
compliance = list(educational_only = TRUE, not_investment_advice = TRUE),
dashboard = NULL,
published = NULL,
featured = NULL,
sort_priority = NULL,
canonical_slug = NULL,
podcast_topics = NULL,
report_topics = NULL
)
Arguments
id, title, asset_class, indicator_family, region, frequency, source, plot_image, thumbnail, tags |
Core registry fields. |
collection, status |
Nullable schema 2.0 fields. The deprecated
|
last_updated |
Legacy schema 2.0 artifact date. |
subtitle, summary, description_md, section, source_detail, curation_priority, plot_html, related_ids, compliance |
Optional schema 2.0 fields. |
dashboard, published, featured, sort_priority, canonical_slug, podcast_topics, report_topics |
Deprecated schema 1.0 compatibility fields. |
Value
A validated schema 2.0 entry that cannot be emitted as schema 3.0.
Examples
# For existing schema 2 callers only; the constructor warns about deprecation.
entry <- suppressWarnings(brief_plot_registry_entry(
id = "legacy-board", title = "Legacy example", collection = "macro",
asset_class = "Rates", indicator_family = "Yield Curve", region = "United States",
frequency = "Daily", source = "Synthetic data", last_updated = "2025-01-07",
status = "ready", plot_image = "plots/example.svg",
thumbnail = "thumbnails/example.png", tags = "example"
))
entry$last_updated
Build one canonical schema 3.0 research-artifact registry entry
Description
Build one canonical schema 3.0 research-artifact registry entry
Usage
brief_plot_registry_entry_v3(
id,
title,
collection,
asset_class,
indicator_family,
region,
frequency,
source,
rendered_at = NULL,
data_as_of = NULL,
metadata_updated_at,
time_indexed = TRUE,
expected_cadence,
status,
plot_image,
thumbnail,
tags,
subtitle = "",
summary = "",
description_md = "",
section = "",
source_detail = character(),
curation_priority = 0,
plot_html = "",
related_ids = character(),
compliance = list(educational_only = TRUE, not_investment_advice = TRUE)
)
Arguments
id |
Stable machine-safe plot identifier in lowercase kebab-case. |
title |
Reader-facing plot title. |
collection |
High-level research collection. One of |
asset_class |
Asset-class label such as |
indicator_family |
Indicator-family label. |
region |
Region label. |
frequency |
Frequency label. |
source |
Source label. |
rendered_at |
UTC artifact-render timestamp in
|
data_as_of |
Latest observation actually represented by the artifact, as an ISO date. Required for ready time-indexed artifacts. |
metadata_updated_at |
ISO date of the latest material human-authored metadata change. |
time_indexed |
Whether the artifact contains time-indexed data. |
expected_cadence |
Expected update cadence of |
status |
Artifact readiness: |
plot_image |
Relative primary-plot path. |
thumbnail |
Relative thumbnail path. |
tags |
Flat character vector of tags. |
subtitle, summary, description_md, section |
Optional descriptive fields. |
source_detail |
Optional source details. |
curation_priority |
Integer curation priority. |
plot_html |
Optional relative HTML path. |
related_ids |
Related artifact ids. |
compliance |
Named compliance flags. |
Value
A canonical schema 3.0 entry. Writers may project it to schema 2.0.
Examples
data_date <- brief_data_as_of(list(
daily = as.Date(c("2025-01-06", "2025-01-07")),
weekly = as.Date(c("2025-01-01", "2025-01-08"))
))
entry <- brief_plot_registry_entry_v3(
id = "example-board", title = "Illustrative research board", collection = "macro",
asset_class = "Rates", indicator_family = "Yield Curve", region = "United States",
frequency = "Daily", source = "Synthetic data", expected_cadence = "weekly",
rendered_at = "2025-01-09T12:00:00Z", data_as_of = data_date,
metadata_updated_at = "2025-01-01", status = "ready",
plot_image = "plots/example.svg", thumbnail = "thumbnails/example.png", tags = "example"
)
# This example validates metadata without requiring image files.
path <- tempfile(fileext = ".json")
brief_plot_registry_write(list(entry), path, schema_version = "3.0",
generated_at = "2025-01-09T12:01:00Z")
brief_plot_registry_validate(path, require_assets = FALSE)
unlink(path)
Validate a research-artifact plot registry
Description
Validate a research-artifact plot registry
Usage
brief_plot_registry_validate(
registry,
output_root = NULL,
require_assets = TRUE
)
Arguments
registry |
Registry object or JSON path. Schemas 1.0, 2.0, and 3.0 are readable; schema 2.0 remains the default writer output during migration. |
output_root |
Root for relative asset validation. |
require_assets |
Require referenced assets to exist. |
Value
Named validation summary.
Examples
data_date <- brief_data_as_of(list(
daily = as.Date(c("2025-01-06", "2025-01-07")),
weekly = as.Date(c("2025-01-01", "2025-01-08"))
))
entry <- brief_plot_registry_entry_v3(
id = "example-board", title = "Illustrative research board", collection = "macro",
asset_class = "Rates", indicator_family = "Yield Curve", region = "United States",
frequency = "Daily", source = "Synthetic data", expected_cadence = "weekly",
rendered_at = "2025-01-09T12:00:00Z", data_as_of = data_date,
metadata_updated_at = "2025-01-01", status = "ready",
plot_image = "plots/example.svg", thumbnail = "thumbnails/example.png", tags = "example"
)
# This example validates metadata without requiring image files.
path <- tempfile(fileext = ".json")
brief_plot_registry_write(list(entry), path, schema_version = "3.0",
generated_at = "2025-01-09T12:01:00Z")
brief_plot_registry_validate(path, require_assets = FALSE)
unlink(path)
Write a research-artifact plot registry to JSON
Description
Write a research-artifact plot registry to JSON
Usage
brief_plot_registry_write(
plots,
path,
schema_version = "2.0",
generated_at = Sys.time(),
source_system = "investlabr",
base_path_mode = "relative",
ready_only = FALSE,
pretty = TRUE,
published_only = NULL
)
Arguments
plots |
Schema 2.0 entries from |
path |
Explicit output JSON path. No file is written unless a path is
supplied; examples should use a location under |
schema_version |
Output schema. Defaults to compatibility schema 2.0;
use |
generated_at |
Registry-generation timestamp in UTC. |
source_system |
Source-system label. |
base_path_mode |
Must be |
ready_only |
Keep only ready entries. |
pretty |
Write pretty JSON. |
published_only |
Deprecated alias for |
Value
Invisibly returns the registry written to disk.
Examples
data_date <- brief_data_as_of(list(
daily = as.Date(c("2025-01-06", "2025-01-07")),
weekly = as.Date(c("2025-01-01", "2025-01-08"))
))
entry <- brief_plot_registry_entry_v3(
id = "example-board", title = "Illustrative research board", collection = "macro",
asset_class = "Rates", indicator_family = "Yield Curve", region = "United States",
frequency = "Daily", source = "Synthetic data", expected_cadence = "weekly",
rendered_at = "2025-01-09T12:00:00Z", data_as_of = data_date,
metadata_updated_at = "2025-01-01", status = "ready",
plot_image = "plots/example.svg", thumbnail = "thumbnails/example.png", tags = "example"
)
# This example validates metadata without requiring image files.
path <- tempfile(fileext = ".json")
brief_plot_registry_write(list(entry), path, schema_version = "3.0",
generated_at = "2025-01-09T12:01:00Z")
brief_plot_registry_validate(path, require_assets = FALSE)
unlink(path)
Build and write a research-artifact registry from metadata sidecars
Description
Build and write a research-artifact registry from metadata sidecars
Usage
brief_plot_registry_write_from_meta(
meta_dir = file.path("config", "publishing", "plots"),
path,
output_root = dirname(path),
resolved_meta_dir = file.path(output_root, "resolved"),
schema_version = "2.0",
source_system = "investlabr",
base_path_mode = "relative",
ready_only = FALSE,
pretty = TRUE,
published_only = NULL
)
Arguments
meta_dir |
Tracked YAML sidecar directory. |
path |
Explicit output JSON path. No file is written unless a path is
supplied; examples should use a location under |
output_root |
Root for relative asset paths. |
resolved_meta_dir |
Run-local metadata emitted by the renderer. |
schema_version |
Output schema. Defaults to compatibility schema 2.0;
use |
source_system |
Source-system label. |
base_path_mode |
Must be |
ready_only |
Keep only ready entries. |
pretty |
Write pretty JSON. |
published_only |
Deprecated alias for |
Value
Invisibly returns the registry written to disk.
Examples
local({
root <- tempfile("registry-example-")
dir.create(root)
on.exit(unlink(root, recursive = TRUE))
dir.create(file.path(root, "meta"))
dir.create(file.path(root, "resolved"))
# Use actual temporary plot artifacts, with explicit synthetic metadata.
pdf_path <- file.path(root, "example.pdf")
grDevices::pdf(pdf_path)
plot(1:3)
grDevices::dev.off()
tracked <- list(
id = "example-board", title = "Example", collection = "macro",
asset_class = "Rates", indicator_family = "Example", region = "Global",
frequency = "Event", source = "Synthetic data", status = "ready",
metadata_updated_at = "2025-01-01", time_indexed = FALSE,
expected_cadence = "not_time_indexed", plot_image = "example.pdf",
thumbnail = "example.pdf", tags = "example"
)
yaml::write_yaml(tracked, file.path(root, "meta", "example.yaml"))
jsonlite::write_json(list(
id = tracked$id, rendered_at = format(Sys.time(), "%Y-%m-%dT%H:%M:%SZ", tz = "UTC"),
data_as_of = NULL, metadata_updated_at = tracked$metadata_updated_at,
time_indexed = FALSE, expected_cadence = "not_time_indexed",
data_as_of_rule = "not_time_indexed"
), file.path(root, "resolved", "example-board.json"), auto_unbox = TRUE, null = "null")
brief_plot_registry_write_from_meta(
file.path(root, "meta"), file.path(root, "registry.json"), output_root = root,
schema_version = "3.0"
)
})
Format the latest bounded research score
Description
Format the latest bounded research score
Usage
brief_score_label(score, moderate = 40, elevated = 70)
Arguments
score |
Numeric score on a 0 to 100 scale. |
moderate |
Minimum score labeled moderate. |
elevated |
Minimum score labeled elevated. |
Value
A concise reader-facing character label.
Examples
prep_fill_forward(c(NA, 1, NA, 2))
a <- data.frame(date = as.Date("2025-01-01") + c(0, 2),
value = c(4, 4.2), series = "A")
b <- data.frame(date = as.Date("2025-01-01") + c(1, 2),
value = c(3, 3.1), series = "B")
prep_series_wide(list(a, b))
prep_zscore(c(1, 2, 3, 4))
prep_recent_changes(c(4, 4.1, 4.2, 4.15), lookback = 2)
score <- factor_bounded_score(prep_zscore(c(1, 2, 3, 4)))
brief_score_label(tail(score, 1))
Evaluate event performance
Description
Evaluate event performance
Usage
eval_event_performance(
DT,
event_col,
event_score_cols = character(0L),
H = 1L:42L,
pos_hit_threshold = 0.05,
neg_hit_threshold = -0.05
)
Arguments
DT |
data.table with |
event_col |
string; column in |
event_score_cols |
character vector of extra columns to carry per case. |
H |
integer horizons (default |
pos_hit_threshold |
Positive return threshold used to count upside hits. |
neg_hit_threshold |
Negative return threshold used to count downside hits. |
Value
Invisibly: data.table (one row) with summary stats and list-cols performance_by_cases, performance_by_horizons.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:59,
close = 100 * exp(0.001 * (0:59) + 0.01 * sin(0:59)),
event_a = as.integer(seq_len(60) %% 10 == 0),
event_b = as.integer(seq_len(60) %% 12 == 0)
)
attr(prices, "inst_id") <- "Synthetic asset"
a <- eval_event_performance(prices, "event_a", H = 1:5)
b <- eval_event_performance(prices, "event_b", H = 1:5)
gen_plot_event_tsline_cum_ret(a)
gen_plot_comparing_events(a, b, "Event A", "Event B")
Evaluate optimized portfolio performance
Description
Evaluate optimized portfolio performance
Usage
eval_portfolio_performance(bt_res_list, target_return)
Arguments
bt_res_list |
data.table of backtest rows (with list-col |
target_return |
numeric annual target return. |
Value
Invisibly: single-row data.table (portfolio backtest) with metrics and list-col log_ret_dt.
Examples
datetime <- as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:59
results <- data.table::rbindlist(lapply(1:3, function(i) {
equity <- exp(cumsum(0.0005 * i + 0.004 * sin((1:60) * i)))
prep_backtest_result_from_equity(equity, datetime, paste("Asset", i), "Hold")
}))
# Choose a feasible target from the actual synthetic results.
target <- min(results$annual_return)
get_optimal_weights(results, target_return = target)
eval_portfolio_performance(results, target_return = target)
Evaluate strategy performance
Description
Evaluate strategy performance
Usage
eval_strat_performance(
DT,
pos_col_name,
bg_time = as.POSIXct(NA),
ed_time = as.POSIXct(NA),
fee_rate = 7e-04,
funding_rate = 4e-05,
interest_rate = 5e-05,
leverage = 1,
rf_rate = 0,
mode = c("new_open", "last_close"),
fee_sides = 1L,
tz = Sys.timezone()
)
Arguments
DT |
data.table with |
pos_col_name |
string; name of the position column in |
bg_time, ed_time |
POSIXct; inclusive start, exclusive end; may be |
fee_rate |
numeric fee per unit abs(position change). |
funding_rate |
Legacy funding-rate input retained for compatibility. |
interest_rate |
Legacy interest-rate input retained for compatibility. |
leverage |
Legacy leverage input retained for compatibility. |
rf_rate |
numeric annual risk-free rate. |
mode |
one of |
fee_sides |
Number of sides used when applying the simplified fee model. |
tz |
Time zone used when coercing input timestamps. |
Value
Invisibly: data.table (one row) with metrics and list-col log_ret_dt.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:39,
open = 100 + (0:39) / 10,
close = 100 + (0:39) / 10 + sin(0:39),
position = rep(c(0, 1), each = 5, length.out = 40)
)
attr(prices, "inst_id") <- "Synthetic asset"
attr(prices$position, "strat_name") <- "Illustration"
attr(prices$position, "strat_par") <- list(window = 5)
result <- eval_strat_performance(prices, "position", tz = "UTC")
eval_strat_plot_tsline_eq(result)
eval_strat_plot_scatter_maxdd_annret(result)
# An external backtest can instead supply an equity curve.
adapted <- prep_backtest_result_from_equity(
exp(cumsum(0.001 + 0.003 * sin(0:39))), prices$datetime,
"Synthetic asset", "Illustrative equity curve"
)
adapted[, c("asset_name", "annual_return", "max_drawdown")]
Scatter: annual return vs max drawdown
Description
Scatter: annual return vs max drawdown
Usage
eval_strat_plot_scatter_maxdd_annret(
bt_res_list,
plot_title = "",
opt_portfolio_line = FALSE,
style = NULL,
context = NULL
)
Arguments
bt_res_list |
data.table of backtest rows (from |
plot_title |
string. |
opt_portfolio_line |
logical; unused placeholder. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
ggplot object.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:39,
open = 100 + (0:39) / 10,
close = 100 + (0:39) / 10 + sin(0:39),
position = rep(c(0, 1), each = 5, length.out = 40)
)
attr(prices, "inst_id") <- "Synthetic asset"
attr(prices$position, "strat_name") <- "Illustration"
attr(prices$position, "strat_par") <- list(window = 5)
result <- eval_strat_performance(prices, "position", tz = "UTC")
eval_strat_plot_tsline_eq(result)
eval_strat_plot_scatter_maxdd_annret(result)
# An external backtest can instead supply an equity curve.
adapted <- prep_backtest_result_from_equity(
exp(cumsum(0.001 + 0.003 * sin(0:39))), prices$datetime,
"Synthetic asset", "Illustrative equity curve"
)
adapted[, c("asset_name", "annual_return", "max_drawdown")]
Plot equity curve (time series)
Description
Plot equity curve (time series)
Usage
eval_strat_plot_tsline_eq(
bt_res,
benchmark_bt_res = NULL,
bt_res_2 = NULL,
style = NULL,
context = NULL,
caption = NULL,
log_eq = FALSE
)
Arguments
bt_res |
single-row data.table from |
benchmark_bt_res |
Optional benchmark strategy result to compare against the evaluated strategy. |
bt_res_2 |
Optional second evaluated strategy result. Use sparingly; the chart is designed for at most two evaluated strategies plus one benchmark. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
caption |
Optional chart caption placed above the configured compiler footer. |
log_eq |
Logical; if 'TRUE', plot |
Value
ggplot object.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:39,
open = 100 + (0:39) / 10,
close = 100 + (0:39) / 10 + sin(0:39),
position = rep(c(0, 1), each = 5, length.out = 40)
)
attr(prices, "inst_id") <- "Synthetic asset"
attr(prices$position, "strat_name") <- "Illustration"
attr(prices$position, "strat_par") <- list(window = 5)
result <- eval_strat_performance(prices, "position", tz = "UTC")
eval_strat_plot_tsline_eq(result)
eval_strat_plot_scatter_maxdd_annret(result)
# An external backtest can instead supply an equity curve.
adapted <- prep_backtest_result_from_equity(
exp(cumsum(0.001 + 0.003 * sin(0:39))), prices$datetime,
"Synthetic asset", "Illustrative equity curve"
)
adapted[, c("asset_name", "annual_return", "max_drawdown")]
Map standardized pressure into a bounded research score
Description
Map standardized pressure into a bounded research score
Usage
factor_bounded_score(z, center = 0, scale = 1.2)
Arguments
z |
Numeric standardized signal. |
center |
Logistic midpoint. |
scale |
Positive logistic scale. |
Value
Numeric score bounded between 0 and 100.
Examples
prep_fill_forward(c(NA, 1, NA, 2))
a <- data.frame(date = as.Date("2025-01-01") + c(0, 2),
value = c(4, 4.2), series = "A")
b <- data.frame(date = as.Date("2025-01-01") + c(1, 2),
value = c(3, 3.1), series = "B")
prep_series_wide(list(a, b))
prep_zscore(c(1, 2, 3, 4))
prep_recent_changes(c(4, 4.1, 4.2, 4.15), lookback = 2)
score <- factor_bounded_score(prep_zscore(c(1, 2, 3, 4)))
brief_score_label(tail(score, 1))
Generate candlestick plot with support and resistance zones
Description
Generate candlestick plot with support and resistance zones
Usage
gen_candle_plots_with_sr_dts(
DT,
inst_id,
bar,
support_dt = NULL,
resistance_dt = NULL,
near_frac = 0.01,
label_digits = 2,
show_ema_lines = FALSE,
style = NULL,
context = NULL,
show_compiler = TRUE
)
Arguments
DT |
A data.table containing OHLC data with columns |
inst_id |
Instrument label used in the chart title. |
bar |
Bar interval label used in the chart title. |
support_dt |
data.table of support zones with |
resistance_dt |
data.table of resistance zones with |
near_frac |
Fraction of the displayed price range used to detect nearby support/resistance labels that should be vertically separated. |
label_digits |
Number of decimals used in support/resistance labels. |
show_ema_lines |
Whether to draw EMA columns when |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
show_compiler |
Whether to append the configured plot compiler name to the plot caption. |
Value
A ggplot2 object showing candlesticks with support/resistance zones.
Examples
bars <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:9,
open = 100 + (0:9), close = 100 + (0:9) + sin(0:9)
)
bars[, high := pmax(open, close) + 1]
bars[, low := pmin(open, close) - 1]
bars[, `:=`(atr_logr_12 = 0.025 + 0.002 * sin(0:9),
atr_q_10_12_300 = 0.015, atr_q_20_12_300 = 0.020,
atr_q_80_12_300 = 0.030, atr_q_90_12_300 = 0.035)]
viz_candle_base(bars, show_compiler = FALSE)
gen_candle_plots_with_sr_lines(bars, support_pts = 99, resistance_pts = 110)
support <- data.table::data.table(zone_low = 98, zone_high = 100,
zone_center = 99, score = 1)
resistance <- data.table::data.table(zone_low = 109, zone_high = 111,
zone_center = 110, score = 1)
gen_candle_plots_with_sr_dts(bars, "Synthetic asset", "1D",
support_dt = support, resistance_dt = resistance,
show_compiler = FALSE)
denominator <- data.table::copy(bars)
denominator[, c("open", "high", "low", "close") := lapply(.SD, function(x) x / 2),
.SDcols = c("open", "high", "low", "close")]
head(prep_ratio_ohlc(bars, denominator, "A/B"))
Generate candlestick plot with support and resistance lines
Description
Generate candlestick plot with support and resistance lines
Usage
gen_candle_plots_with_sr_lines(
DT,
support_pts,
resistance_pts,
near_frac = 0.01,
label_digits = 2,
show_ema_lines = FALSE,
style = NULL,
context = NULL
)
Arguments
DT |
A data.table containing OHLC data with columns |
support_pts |
Numeric vector of support price levels. |
resistance_pts |
Numeric vector of resistance price levels. |
near_frac |
Fraction of the displayed price range used to detect nearby support/resistance labels that should be vertically separated. |
label_digits |
Number of decimals used in support/resistance labels. |
show_ema_lines |
Whether to draw EMA columns when |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A ggplot2 object showing candlestick chart with support and resistance lines.
Examples
bars <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:9,
open = 100 + (0:9), close = 100 + (0:9) + sin(0:9)
)
bars[, high := pmax(open, close) + 1]
bars[, low := pmin(open, close) - 1]
bars[, `:=`(atr_logr_12 = 0.025 + 0.002 * sin(0:9),
atr_q_10_12_300 = 0.015, atr_q_20_12_300 = 0.020,
atr_q_80_12_300 = 0.030, atr_q_90_12_300 = 0.035)]
viz_candle_base(bars, show_compiler = FALSE)
gen_candle_plots_with_sr_lines(bars, support_pts = 99, resistance_pts = 110)
support <- data.table::data.table(zone_low = 98, zone_high = 100,
zone_center = 99, score = 1)
resistance <- data.table::data.table(zone_low = 109, zone_high = 111,
zone_center = 110, score = 1)
gen_candle_plots_with_sr_dts(bars, "Synthetic asset", "1D",
support_dt = support, resistance_dt = resistance,
show_compiler = FALSE)
denominator <- data.table::copy(bars)
denominator[, c("open", "high", "low", "close") := lapply(.SD, function(x) x / 2),
.SDcols = c("open", "high", "low", "close")]
head(prep_ratio_ohlc(bars, denominator, "A/B"))
Plot multiple time-series columns as facets
Description
Plot multiple time-series columns as facets
Usage
gen_facet_plot_from_multicol_ts(
DT,
id_vars,
measure_vars,
measure_labels,
style = NULL,
context = NULL,
show_compiler = TRUE
)
Arguments
DT |
A data.table or data.frame containing id and measure columns. |
id_vars |
Character vector of identifier columns preserved during reshaping. |
measure_vars |
Character vector of numeric measure columns to plot. |
measure_labels |
Optional named character vector used to relabel
|
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
show_compiler |
Whether to append the configured plot compiler name to the plot caption. |
Value
A faceted ggplot object.
Examples
data <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:9,
first = 1:10, second = 10:1
)
p <- ggplot2::ggplot(data, ggplot2::aes(datetime, first)) + ggplot2::geom_line()
board <- gen_grid_of_plots_with_labels(list(p, p), n_rows = 1, n_cols = 2,
title = "Two views", show_compiler = FALSE)
grid::grid.newpage()
grid::grid.draw(board)
gen_facet_plot_from_multicol_ts(data, "datetime", c("first", "second"),
c("First", "Second"), show_compiler = FALSE)
Arrange plots in a labeled grid layout
Description
Arrange plots in a labeled grid layout
Usage
gen_grid_of_plots_with_labels(
plots,
n_rows,
n_cols,
row_labs = NULL,
col_labs = NULL,
title = NULL,
bottom = NULL,
row_label_width_cm = 2.2,
col_header_height_cm = 1.2,
row_label_gp = NULL,
col_label_gp = NULL,
title_gp = NULL,
bottom_gp = NULL,
style = NULL,
context = NULL,
show_compiler = TRUE
)
Arguments
plots |
List of ggplot objects or grobs. |
n_rows |
Number of plot rows. |
n_cols |
Number of plot columns. |
row_labs |
Optional row labels. |
col_labs |
Optional column labels. |
title |
Optional overall title. |
bottom |
Optional overall footer text. |
row_label_width_cm |
Width allocated to row labels. |
col_header_height_cm |
Height allocated to column headers. |
row_label_gp |
Optional 'grid::gpar()' for row labels. |
col_label_gp |
Optional 'grid::gpar()' for column labels. |
title_gp |
Optional 'grid::gpar()' for the title. |
bottom_gp |
Optional 'grid::gpar()' for the footer. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
show_compiler |
Whether to append the configured plot compiler name to the footer. |
Value
A 'gtable' object returned by 'gridExtra::arrangeGrob()'.
Examples
data <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:9,
first = 1:10, second = 10:1
)
p <- ggplot2::ggplot(data, ggplot2::aes(datetime, first)) + ggplot2::geom_line()
board <- gen_grid_of_plots_with_labels(list(p, p), n_rows = 1, n_cols = 2,
title = "Two views", show_compiler = FALSE)
grid::grid.newpage()
grid::grid.draw(board)
gen_facet_plot_from_multicol_ts(data, "datetime", c("first", "second"),
c("First", "Second"), show_compiler = FALSE)
Compare two event-study average paths
Description
Compare two event-study average paths
Usage
gen_plot_comparing_events(
first_event_res,
second_event_res,
first_event_label,
second_event_label,
first_event_color = NULL,
second_event_color = NULL,
style = NULL,
context = NULL
)
Arguments
first_event_res, second_event_res |
Event-performance results returned by
|
first_event_label, second_event_label |
Labels used in the comparison legend. |
first_event_color, second_event_color |
Optional line colors. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A ggplot object.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:59,
close = 100 * exp(0.001 * (0:59) + 0.01 * sin(0:59)),
event_a = as.integer(seq_len(60) %% 10 == 0),
event_b = as.integer(seq_len(60) %% 12 == 0)
)
attr(prices, "inst_id") <- "Synthetic asset"
a <- eval_event_performance(prices, "event_a", H = 1:5)
b <- eval_event_performance(prices, "event_b", H = 1:5)
gen_plot_event_tsline_cum_ret(a)
gen_plot_comparing_events(a, b, "Event A", "Event B")
Plot cumulative event-study return paths
Description
Plot cumulative event-study return paths
Usage
gen_plot_event_tsline_cum_ret(
res,
threshold = 0.02,
style = NULL,
context = NULL
)
Arguments
res |
Event-performance result returned by
|
threshold |
Positive and negative horizontal reference threshold. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A ggplot object.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:59,
close = 100 * exp(0.001 * (0:59) + 0.01 * sin(0:59)),
event_a = as.integer(seq_len(60) %% 10 == 0),
event_b = as.integer(seq_len(60) %% 12 == 0)
)
attr(prices, "inst_id") <- "Synthetic asset"
a <- eval_event_performance(prices, "event_a", H = 1:5)
b <- eval_event_performance(prices, "event_b", H = 1:5)
gen_plot_event_tsline_cum_ret(a)
gen_plot_comparing_events(a, b, "Event A", "Event B")
Generate rolling monthly strategy statistics
Description
Generate rolling monthly strategy statistics
Usage
gen_rolling_monthly_stats(transaction_dt, N_rolling = 6L, debug_mode = FALSE)
Arguments
transaction_dt |
data.table of strategy transactions or per-bar returns. |
N_rolling |
Number of months in the rolling window. |
debug_mode |
Whether to retain additional diagnostic columns. |
Value
A data.table of rolling monthly performance statistics.
Examples
transactions <- data.table::data.table(
datetime = as.POSIXct(c("2025-01-15", "2025-02-15", "2025-03-15"), tz = "UTC"),
action = "close", pre_fee_log_ret = c(0.02, -0.01, 0.03),
is_win = c(TRUE, FALSE, TRUE)
)
gen_rolling_monthly_stats(transactions, N_rolling = 2)
Generate U.S. Treasury yield curve plot
Description
Generate U.S. Treasury yield curve plot
Usage
gen_yield_curve_plot(
DT,
selected_windows = c("Now", "One week ago", "One month ago"),
style = NULL,
context = NULL
)
Arguments
DT |
A data.table returned from |
selected_windows |
Character vector specifying which yield curves to display (e.g., |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A ggplot2 object visualizing selected yield curves.
Examples
series <- lapply(seq_len(11), function(i) {
data.table::data.table(date = as.Date(c("2025-01-01", "2025-02-01")),
value = c(4 + i / 20, 3.8 + i / 20))
})
curves <- get_yield_data_DT(series, list(
Now = as.Date("2025-02-01"), Previous = as.Date("2025-01-01")
))
gen_yield_curve_plot(curves, selected_windows = c("Now", "Previous"))
gen_yield_curve_plot_grid(curves, selected_windows = c("Now", "Previous"))
Generate yield curve comparison grid
Description
Generate yield curve comparison grid
Usage
gen_yield_curve_plot_grid(
DT,
selected_windows = c("Now", "One week ago", "One month ago", "Six months ago",
"One year ago"),
style = NULL,
context = NULL
)
Arguments
DT |
A data.table returned from |
selected_windows |
Character vector specifying yield curve snapshots for comparison. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A faceted ggplot2 object comparing yield curves across multiple time windows.
Examples
series <- lapply(seq_len(11), function(i) {
data.table::data.table(date = as.Date(c("2025-01-01", "2025-02-01")),
value = c(4 + i / 20, 3.8 + i / 20))
})
curves <- get_yield_data_DT(series, list(
Now = as.Date("2025-02-01"), Previous = as.Date("2025-01-01")
))
gen_yield_curve_plot(curves, selected_windows = c("Now", "Previous"))
gen_yield_curve_plot_grid(curves, selected_windows = c("Now", "Previous"))
Compute optimal strategy weights
Description
Compute optimal strategy weights
Usage
get_optimal_weights(bt_res_list, target_return = 0.1)
Arguments
bt_res_list |
data.table of backtest rows (from |
target_return |
numeric annual target return (e.g., 0.10). |
Value
List with optimal_weights (named numeric) and optimal_weights_table (data.frame of nonzero weights).
Examples
datetime <- as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:59
results <- data.table::rbindlist(lapply(1:3, function(i) {
equity <- exp(cumsum(0.0005 * i + 0.004 * sin((1:60) * i)))
prep_backtest_result_from_equity(equity, datetime, paste("Asset", i), "Hold")
}))
# Choose a feasible target from the actual synthetic results.
target <- min(results$annual_return)
get_optimal_weights(results, target_return = target)
eval_portfolio_performance(results, target_return = target)
Get yield data for given dates
Description
Get yield data for given dates
Usage
get_yield_data_DT(yield_dt_list, yield_dates)
Arguments
yield_dt_list |
A list of data.tables, each containing a yield series with columns |
yield_dates |
A vector of dates for which yields should be retrieved. |
Value
A data.table containing yield data across maturities and dates.
Examples
series <- lapply(seq_len(11), function(i) {
data.table::data.table(date = as.Date(c("2025-01-01", "2025-02-01")),
value = c(4 + i / 20, 3.8 + i / 20))
})
curves <- get_yield_data_DT(series, list(
Now = as.Date("2025-02-01"), Previous = as.Date("2025-01-01")
))
gen_yield_curve_plot(curves, selected_windows = c("Now", "Previous"))
gen_yield_curve_plot_grid(curves, selected_windows = c("Now", "Previous"))
Build A Backtest Result Row From An Equity Curve
Description
Converts an externally generated equity curve into the compact backtest result shape used by investlabr plotting helpers.
Usage
prep_backtest_result_from_equity(equity, datetime, asset_name, strat_label)
Arguments
equity |
Numeric equity curve. |
datetime |
POSIXct-compatible vector aligned with 'equity'. |
asset_name |
Character asset label. |
strat_label |
Character strategy label. |
Value
A one-row 'data.table' with summary metrics and a 'log_ret_dt' list-column.
Examples
prices <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:39,
open = 100 + (0:39) / 10,
close = 100 + (0:39) / 10 + sin(0:39),
position = rep(c(0, 1), each = 5, length.out = 40)
)
attr(prices, "inst_id") <- "Synthetic asset"
attr(prices$position, "strat_name") <- "Illustration"
attr(prices$position, "strat_par") <- list(window = 5)
result <- eval_strat_performance(prices, "position", tz = "UTC")
eval_strat_plot_tsline_eq(result)
eval_strat_plot_scatter_maxdd_annret(result)
# An external backtest can instead supply an equity curve.
adapted <- prep_backtest_result_from_equity(
exp(cumsum(0.001 + 0.003 * sin(0:39))), prices$datetime,
"Synthetic asset", "Illustrative equity curve"
)
adapted[, c("asset_name", "annual_return", "max_drawdown")]
Carry the latest observed value forward
Description
Carry the latest observed value forward
Usage
prep_fill_forward(x)
Arguments
x |
Vector containing values and missing observations. |
Value
A vector with missing values filled from the latest prior observation.
Examples
prep_fill_forward(c(NA, 1, NA, 2))
a <- data.frame(date = as.Date("2025-01-01") + c(0, 2),
value = c(4, 4.2), series = "A")
b <- data.frame(date = as.Date("2025-01-01") + c(1, 2),
value = c(3, 3.1), series = "B")
prep_series_wide(list(a, b))
prep_zscore(c(1, 2, 3, 4))
prep_recent_changes(c(4, 4.1, 4.2, 4.15), lookback = 2)
score <- factor_bounded_score(prep_zscore(c(1, 2, 3, 4)))
brief_score_label(tail(score, 1))
Build Synthetic OHLC For A Price Ratio
Description
Builds a close-aligned OHLC proxy for a ratio between two OHLC series. This is intended for research-side spread or curve proxy visualization, not production execution.
Usage
prep_ratio_ohlc(numerator_dt, denominator_dt, ratio_symbol)
Arguments
numerator_dt, denominator_dt |
'data.table'-like OHLC inputs containing 'datetime', 'open', 'high', 'low', 'close', and optionally 'volume'. |
ratio_symbol |
Character label for the synthetic ratio. |
Value
A 'data.table' with OHLC columns for the synthetic ratio.
Examples
bars <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:9,
open = 100 + (0:9), close = 100 + (0:9) + sin(0:9)
)
bars[, high := pmax(open, close) + 1]
bars[, low := pmin(open, close) - 1]
bars[, `:=`(atr_logr_12 = 0.025 + 0.002 * sin(0:9),
atr_q_10_12_300 = 0.015, atr_q_20_12_300 = 0.020,
atr_q_80_12_300 = 0.030, atr_q_90_12_300 = 0.035)]
viz_candle_base(bars, show_compiler = FALSE)
gen_candle_plots_with_sr_lines(bars, support_pts = 99, resistance_pts = 110)
support <- data.table::data.table(zone_low = 98, zone_high = 100,
zone_center = 99, score = 1)
resistance <- data.table::data.table(zone_low = 109, zone_high = 111,
zone_center = 110, score = 1)
gen_candle_plots_with_sr_dts(bars, "Synthetic asset", "1D",
support_dt = support, resistance_dt = resistance,
show_compiler = FALSE)
denominator <- data.table::copy(bars)
denominator[, c("open", "high", "low", "close") := lapply(.SD, function(x) x / 2),
.SDcols = c("open", "high", "low", "close")]
head(prep_ratio_ohlc(bars, denominator, "A/B"))
Extract recent finite first differences
Description
Extract recent finite first differences
Usage
prep_recent_changes(x, lookback = 252L)
Arguments
x |
Numeric level series. |
lookback |
Maximum number of recent changes to return. |
Value
Numeric vector of recent finite first differences.
Examples
prep_fill_forward(c(NA, 1, NA, 2))
a <- data.frame(date = as.Date("2025-01-01") + c(0, 2),
value = c(4, 4.2), series = "A")
b <- data.frame(date = as.Date("2025-01-01") + c(1, 2),
value = c(3, 3.1), series = "B")
prep_series_wide(list(a, b))
prep_zscore(c(1, 2, 3, 4))
prep_recent_changes(c(4, 4.1, 4.2, 4.15), lookback = 2)
score <- factor_bounded_score(prep_zscore(c(1, 2, 3, 4)))
brief_score_label(tail(score, 1))
Combine labeled time series into a research-ready wide table
Description
Combine labeled time series into a research-ready wide table
Usage
prep_series_wide(series_list, fill_forward = TRUE)
Arguments
series_list |
List of data frames or data.tables containing |
fill_forward |
Whether to carry each series forward after reshaping. |
Value
A data.table with one row per date and one column per series.
Examples
prep_fill_forward(c(NA, 1, NA, 2))
a <- data.frame(date = as.Date("2025-01-01") + c(0, 2),
value = c(4, 4.2), series = "A")
b <- data.frame(date = as.Date("2025-01-01") + c(1, 2),
value = c(3, 3.1), series = "B")
prep_series_wide(list(a, b))
prep_zscore(c(1, 2, 3, 4))
prep_recent_changes(c(4, 4.1, 4.2, 4.15), lookback = 2)
score <- factor_bounded_score(prep_zscore(c(1, 2, 3, 4)))
brief_score_label(tail(score, 1))
Standardize a numeric series
Description
Standardize a numeric series
Usage
prep_zscore(x)
Arguments
x |
Numeric vector. |
Value
Numeric z-scores. Returns all NA when dispersion is zero or
unavailable.
Examples
prep_fill_forward(c(NA, 1, NA, 2))
a <- data.frame(date = as.Date("2025-01-01") + c(0, 2),
value = c(4, 4.2), series = "A")
b <- data.frame(date = as.Date("2025-01-01") + c(1, 2),
value = c(3, 3.1), series = "B")
prep_series_wide(list(a, b))
prep_zscore(c(1, 2, 3, 4))
prep_recent_changes(c(4, 4.1, 4.2, 4.15), lookback = 2)
score <- factor_bounded_score(prep_zscore(c(1, 2, 3, 4)))
brief_score_label(tail(score, 1))
Simulate an AR(1) data-generating process
Description
Simulate an AR(1) data-generating process
Usage
sim_ar1_dgp(
n,
a1,
y_lag1 = 0,
burn = 50,
sigma = 1,
drift = 0,
trend_slope = 0,
seed = NULL
)
Arguments
n |
Number of observations returned after burn-in. |
a1 |
AR(1) coefficient. |
y_lag1 |
Initial lagged value. |
burn |
Number of burn-in observations discarded before returning the sample. |
sigma |
Innovation standard deviation. |
drift |
Constant drift term added each step. |
trend_slope |
Linear trend slope applied to the running time index. |
seed |
Optional integer seed for reproducibility. |
Value
'data.table' with columns 't', 'value', and 'innovation'.
Examples
head(sim_ar1_dgp(30, a1 = 0.7, seed = 1))
head(sim_ar2_dgp(30, a1 = 0.5, a2 = 0.2, seed = 1))
head(sim_ar3_dgp(30, a1 = 0.4, a2 = 0.2, a3 = 0.1, seed = 1))
head(sim_ma1_dgp(30, b1 = 0.5, seed = 1))
head(sim_arch1_dgp(30, alpha0 = 0.1, alpha1 = 0.4, seed = 1))
head(sim_garch11_dgp(30, alpha0 = 0.1, alpha1 = 0.1, beta1 = 0.8, seed = 1))
Simulate an AR(2) data-generating process
Description
Simulate an AR(2) data-generating process
Usage
sim_ar2_dgp(
n,
a1,
a2,
y_lag1 = 0,
y_lag2 = 0,
burn = 50,
sigma = 1,
drift = 0,
trend_slope = 0,
seed = NULL
)
Arguments
n |
Number of observations returned after burn-in. |
a1 |
AR(1) coefficient. |
a2 |
AR(2) coefficient. |
y_lag1 |
Initial lagged value. |
y_lag2 |
Second initial lagged value. |
burn |
Number of burn-in observations discarded before returning the sample. |
sigma |
Innovation standard deviation. |
drift |
Constant drift term added each step. |
trend_slope |
Linear trend slope applied to the running time index. |
seed |
Optional integer seed for reproducibility. |
Value
'data.table' with columns 't', 'value', and 'innovation'.
Examples
head(sim_ar1_dgp(30, a1 = 0.7, seed = 1))
head(sim_ar2_dgp(30, a1 = 0.5, a2 = 0.2, seed = 1))
head(sim_ar3_dgp(30, a1 = 0.4, a2 = 0.2, a3 = 0.1, seed = 1))
head(sim_ma1_dgp(30, b1 = 0.5, seed = 1))
head(sim_arch1_dgp(30, alpha0 = 0.1, alpha1 = 0.4, seed = 1))
head(sim_garch11_dgp(30, alpha0 = 0.1, alpha1 = 0.1, beta1 = 0.8, seed = 1))
Simulate an AR(3) data-generating process
Description
Simulate an AR(3) data-generating process
Usage
sim_ar3_dgp(
n,
a1,
a2,
a3,
y_lag1 = 0,
y_lag2 = 0,
y_lag3 = 0,
burn = 50,
sigma = 1,
drift = 0,
trend_slope = 0,
seed = NULL
)
Arguments
n |
Number of observations returned after burn-in. |
a1 |
AR(1) coefficient. |
a2 |
AR(2) coefficient. |
a3 |
AR(3) coefficient. |
y_lag1 |
Initial lagged value. |
y_lag2 |
Second initial lagged value. |
y_lag3 |
Third initial lagged value. |
burn |
Number of burn-in observations discarded before returning the sample. |
sigma |
Innovation standard deviation. |
drift |
Constant drift term added each step. |
trend_slope |
Linear trend slope applied to the running time index. |
seed |
Optional integer seed for reproducibility. |
Value
'data.table' with columns 't', 'value', and 'innovation'.
Examples
head(sim_ar1_dgp(30, a1 = 0.7, seed = 1))
head(sim_ar2_dgp(30, a1 = 0.5, a2 = 0.2, seed = 1))
head(sim_ar3_dgp(30, a1 = 0.4, a2 = 0.2, a3 = 0.1, seed = 1))
head(sim_ma1_dgp(30, b1 = 0.5, seed = 1))
head(sim_arch1_dgp(30, alpha0 = 0.1, alpha1 = 0.4, seed = 1))
head(sim_garch11_dgp(30, alpha0 = 0.1, alpha1 = 0.1, beta1 = 0.8, seed = 1))
Simulate an ARCH(1) data-generating process
Description
Simulate an ARCH(1) data-generating process
Usage
sim_arch1_dgp(n, alpha0, alpha1, e_lag1_sq = 0, burn = 50, seed = NULL)
Arguments
n |
Number of observations returned after burn-in. |
alpha0 |
Constant term in the conditional variance recursion. |
alpha1 |
ARCH coefficient on the lagged squared innovation. |
e_lag1_sq |
Initial lagged squared innovation. |
burn |
Number of burn-in observations discarded before returning the sample. |
seed |
Optional integer seed for reproducibility. |
Value
'data.table' with columns 't', 'value', 'innovation', and 'sigma2'.
Examples
head(sim_ar1_dgp(30, a1 = 0.7, seed = 1))
head(sim_ar2_dgp(30, a1 = 0.5, a2 = 0.2, seed = 1))
head(sim_ar3_dgp(30, a1 = 0.4, a2 = 0.2, a3 = 0.1, seed = 1))
head(sim_ma1_dgp(30, b1 = 0.5, seed = 1))
head(sim_arch1_dgp(30, alpha0 = 0.1, alpha1 = 0.4, seed = 1))
head(sim_garch11_dgp(30, alpha0 = 0.1, alpha1 = 0.1, beta1 = 0.8, seed = 1))
Simulate a forward percentile fan from historical changes
Description
Simulate a forward percentile fan from historical changes
Usage
sim_forward_fan(
start_value,
changes,
horizons = c(1L, 5L, 10L, 20L, 60L),
n_paths = 600L,
seed = 1L
)
Arguments
start_value |
Current level from which paths begin. |
changes |
Historical one-period changes sampled with replacement. |
horizons |
Positive integer horizons included in the returned fan. |
n_paths |
Number of simulated paths. |
seed |
Optional reproducibility seed. |
Value
A data.table containing p10, p25, p50, p75, and p90 levels by horizon, including horizon zero.
Examples
# Fully synthetic inputs; no data service or local cache is needed.
changes <- seq(-0.10, 0.10, length.out = 40)
fan <- sim_forward_fan(4, changes, horizons = c(1, 5, 10),
n_paths = 100, seed = 7)
viz_forward_fan(fan, "Illustrative yield paths", "Historical-change bootstrap",
"Yield (%)", show_compiler = FALSE)
paths <- sim_scenario_path(4, c(Easing = -0.25, Hold = 0, Tightening = 0.25),
horizon_months = 3, start_date = as.Date("2025-01-01"))
viz_series_lines(paths, "date", "value", color = "scenario",
title = "Policy scenarios", subtitle = "Explicit monthly assumptions",
y_label = "Rate (%)", show_compiler = FALSE)
Simulate a GARCH(1,1) data-generating process
Description
Simulate a GARCH(1,1) data-generating process
Usage
sim_garch11_dgp(
n,
alpha0,
alpha1,
beta1,
sigma2_0 = NULL,
burn = 50,
z_dist = c("norm", "stdt"),
df = 8,
seed = NULL
)
Arguments
n |
Number of observations returned after burn-in. |
alpha0 |
Constant term in the conditional variance recursion. |
alpha1 |
Coefficient on the lagged squared innovation. |
beta1 |
Coefficient on the lagged conditional variance. |
sigma2_0 |
Optional initial conditional variance. If 'NULL', the unconditional variance is used. |
burn |
Number of burn-in observations discarded before returning the sample. |
z_dist |
Innovation distribution: '"norm"' or '"stdt"'. |
df |
Degrees of freedom for the standardized Student t innovations. |
seed |
Optional integer seed for reproducibility. |
Value
'data.table' with columns 't', 'value', 'innovation', and 'sigma2'.
Examples
head(sim_ar1_dgp(30, a1 = 0.7, seed = 1))
head(sim_ar2_dgp(30, a1 = 0.5, a2 = 0.2, seed = 1))
head(sim_ar3_dgp(30, a1 = 0.4, a2 = 0.2, a3 = 0.1, seed = 1))
head(sim_ma1_dgp(30, b1 = 0.5, seed = 1))
head(sim_arch1_dgp(30, alpha0 = 0.1, alpha1 = 0.4, seed = 1))
head(sim_garch11_dgp(30, alpha0 = 0.1, alpha1 = 0.1, beta1 = 0.8, seed = 1))
Simulate an MA(1) data-generating process
Description
Simulate an MA(1) data-generating process
Usage
sim_ma1_dgp(n, b1, e_lag1 = 0, burn = 50, sigma = 1, seed = NULL)
Arguments
n |
Number of observations returned after burn-in. |
b1 |
MA(1) coefficient. |
e_lag1 |
Initial lagged innovation. |
burn |
Number of burn-in observations discarded before returning the sample. |
sigma |
Innovation standard deviation. |
seed |
Optional integer seed for reproducibility. |
Value
'data.table' with columns 't', 'value', and 'innovation'.
Examples
head(sim_ar1_dgp(30, a1 = 0.7, seed = 1))
head(sim_ar2_dgp(30, a1 = 0.5, a2 = 0.2, seed = 1))
head(sim_ar3_dgp(30, a1 = 0.4, a2 = 0.2, a3 = 0.1, seed = 1))
head(sim_ma1_dgp(30, b1 = 0.5, seed = 1))
head(sim_arch1_dgp(30, alpha0 = 0.1, alpha1 = 0.4, seed = 1))
head(sim_garch11_dgp(30, alpha0 = 0.1, alpha1 = 0.1, beta1 = 0.8, seed = 1))
Construct deterministic scenario paths
Description
Construct deterministic scenario paths
Usage
sim_scenario_path(
start_value,
scenario_changes,
horizon_months = 6L,
start_date = Sys.Date()
)
Arguments
start_value |
Current level. |
scenario_changes |
Named numeric vector or list of per-period changes. |
horizon_months |
Number of forward monthly steps. |
start_date |
First scenario date. |
Value
Long-form data.table with date, scenario, and
value columns.
Examples
# Fully synthetic inputs; no data service or local cache is needed.
changes <- seq(-0.10, 0.10, length.out = 40)
fan <- sim_forward_fan(4, changes, horizons = c(1, 5, 10),
n_paths = 100, seed = 7)
viz_forward_fan(fan, "Illustrative yield paths", "Historical-change bootstrap",
"Yield (%)", show_compiler = FALSE)
paths <- sim_scenario_path(4, c(Easing = -0.25, Hold = 0, Tightening = 0.25),
horizon_months = 3, start_date = as.Date("2025-01-01"))
viz_series_lines(paths, "date", "value", color = "scenario",
title = "Policy scenarios", subtitle = "Explicit monthly assumptions",
y_label = "Rate (%)", show_compiler = FALSE)
Add event-line annotations to a plot
Description
Add event-line annotations to a plot
Usage
viz_annotate_event_lines(
plot,
event_dt,
x_col = "datetime",
label_col = NULL,
color = NULL,
linetype = "dashed",
alpha = 0.45,
style = NULL,
context = NULL
)
Arguments
plot |
A 'ggplot' object. |
event_dt |
Data with at least an x-position column. |
x_col |
Name of the x-position column. |
label_col |
Optional label column. |
color |
Optional line and label color. |
linetype |
Line type for event markers. |
alpha |
Alpha applied to event lines. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A 'ggplot' object with event annotations.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Add a direct label for the last observation in a series
Description
Add a direct label for the last observation in a series
Usage
viz_annotate_last_value(
plot,
data,
x,
y,
label = NULL,
prefix = "",
digits = 2,
color = NULL,
style = NULL,
context = NULL
)
Arguments
plot |
A 'ggplot' object. |
data |
A data.frame or data.table containing the plotted series. |
x |
Name of the x column. |
y |
Name of the y column. |
label |
Optional name of a label column. If 'NULL', the formatted 'y' value is used. |
prefix |
Optional prefix prepended to the label text. |
digits |
Number of digits used when formatting numeric labels. |
color |
Optional label color. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A 'ggplot' object with a last-value annotation.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Add regime-band annotations to a plot
Description
Add regime-band annotations to a plot
Usage
viz_annotate_regime_bands(
plot,
regime_dt,
xmin_col = "start",
xmax_col = "end",
fill = NULL,
alpha = 0.12,
style = NULL,
context = NULL
)
Arguments
plot |
A 'ggplot' object. |
regime_dt |
Data with start and end columns. |
xmin_col |
Name of the regime start column. |
xmax_col |
Name of the regime end column. |
fill |
Optional fill color. |
alpha |
Optional fill alpha. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
A 'ggplot' object with shaded regime bands.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Append a standardized source caption to a plot
Description
Append a standardized source caption to a plot
Usage
viz_annotate_source_caption(plot, source_text, note = NULL)
Arguments
plot |
A 'ggplot' object. |
source_text |
Source text. |
note |
Optional note appended after the source. |
Value
A 'ggplot' object with an updated caption.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Generate a base candlestick plot
Description
Generate a base candlestick plot
Usage
viz_candle_base(DT, style = NULL, context = NULL, show_compiler = TRUE)
Arguments
DT |
A data.table containing OHLC data with columns |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
show_compiler |
Whether to append the configured plot compiler name to the plot caption. |
Value
A ggplot2 object showing an OHLC candlestick chart.
Examples
bars <- data.table::data.table(
datetime = as.POSIXct("2025-01-01", tz = "UTC") + 86400 * 0:9,
open = 100 + (0:9), close = 100 + (0:9) + sin(0:9)
)
bars[, high := pmax(open, close) + 1]
bars[, low := pmin(open, close) - 1]
bars[, `:=`(atr_logr_12 = 0.025 + 0.002 * sin(0:9),
atr_q_10_12_300 = 0.015, atr_q_20_12_300 = 0.020,
atr_q_80_12_300 = 0.030, atr_q_90_12_300 = 0.035)]
viz_candle_base(bars, show_compiler = FALSE)
gen_candle_plots_with_sr_lines(bars, support_pts = 99, resistance_pts = 110)
support <- data.table::data.table(zone_low = 98, zone_high = 100,
zone_center = 99, score = 1)
resistance <- data.table::data.table(zone_low = 109, zone_high = 111,
zone_center = 110, score = 1)
gen_candle_plots_with_sr_dts(bars, "Synthetic asset", "1D",
support_dt = support, resistance_dt = resistance,
show_compiler = FALSE)
denominator <- data.table::copy(bars)
denominator[, c("open", "high", "low", "close") := lapply(.SD, function(x) x / 2),
.SDcols = c("open", "high", "low", "close")]
head(prep_ratio_ohlc(bars, denominator, "A/B"))
Plot a forward percentile fan
Description
Plot a forward percentile fan
Usage
viz_forward_fan(
fan_dt,
title,
subtitle,
y_label,
accent = NULL,
style = NULL,
context = NULL,
show_compiler = TRUE
)
Arguments
fan_dt |
Data frame containing |
title |
Plot title. |
subtitle |
Plot subtitle. |
y_label |
Y-axis label. |
accent |
Optional fan color. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
show_compiler |
Whether to append the configured compiler footer. |
Value
A ggplot object.
Examples
# Fully synthetic inputs; no data service or local cache is needed.
changes <- seq(-0.10, 0.10, length.out = 40)
fan <- sim_forward_fan(4, changes, horizons = c(1, 5, 10),
n_paths = 100, seed = 7)
viz_forward_fan(fan, "Illustrative yield paths", "Historical-change bootstrap",
"Yield (%)", show_compiler = FALSE)
paths <- sim_scenario_path(4, c(Easing = -0.25, Hold = 0, Tightening = 0.25),
horizon_months = 3, start_date = as.Date("2025-01-01"))
viz_series_lines(paths, "date", "value", color = "scenario",
title = "Policy scenarios", subtitle = "Explicit monthly assumptions",
y_label = "Rate (%)", show_compiler = FALSE)
Get visualization palette values
Description
Get visualization palette values
Usage
viz_palette_get(
style = NULL,
context = NULL,
palette = c("discrete", "sequential")
)
Arguments
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
palette |
One of '"discrete"' or '"sequential"'. |
Value
Character vector of colors.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Plot one or more research series
Description
Plot one or more research series
Usage
viz_series_lines(
data,
x,
y,
color = "series",
title,
subtitle,
y_label,
colors = NULL,
style = NULL,
context = NULL,
legend_position = "bottom",
show_compiler = TRUE
)
Arguments
data |
Data frame containing the plotted columns. |
x, y, color |
Column names mapped to x, y, and color. |
title |
Plot title. |
subtitle |
Plot subtitle. |
y_label |
Y-axis label. |
colors |
Optional named manual color vector. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
legend_position |
Legend position. |
show_compiler |
Whether to append the configured compiler footer. |
Value
A ggplot object.
Examples
# Fully synthetic inputs; no data service or local cache is needed.
changes <- seq(-0.10, 0.10, length.out = 40)
fan <- sim_forward_fan(4, changes, horizons = c(1, 5, 10),
n_paths = 100, seed = 7)
viz_forward_fan(fan, "Illustrative yield paths", "Historical-change bootstrap",
"Yield (%)", show_compiler = FALSE)
paths <- sim_scenario_path(4, c(Easing = -0.25, Hold = 0, Tightening = 0.25),
horizon_months = 3, start_date = as.Date("2025-01-01"))
viz_series_lines(paths, "date", "value", color = "scenario",
title = "Policy scenarios", subtitle = "Explicit monthly assumptions",
y_label = "Rate (%)", show_compiler = FALSE)
Get resolved visualization style
Description
Get resolved visualization style
Usage
viz_style_get(style = NULL, context = NULL)
Arguments
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
Value
Named list describing colors, sizing, and theme settings.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Set default visualization style and context
Description
Set default visualization style and context
Usage
viz_style_set(style = "research_note", context = "report")
Arguments
style |
Named style family. |
context |
Output context such as '"report"', '"slide"', or '"dashboard"'. |
Value
Invisibly returns the resolved style object.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")
Apply a standardized investlabr plot theme
Description
Apply a standardized investlabr plot theme
Usage
viz_theme_apply(
plot,
style = NULL,
context = NULL,
legend_position = NULL,
base_family = NULL,
show_compiler = TRUE
)
Arguments
plot |
A 'ggplot' object. |
style |
Named style family or 'NULL' to use the package default. |
context |
Output context or 'NULL' to use the package default. |
legend_position |
Optional legend position override. |
base_family |
Optional font family override. |
show_compiler |
Whether to append the configured plot compiler name to the caption. |
Value
A styled 'ggplot' object.
Examples
viz_style_get("policy_memo", "report")
viz_palette_get("institutional_blue")
local({
old <- options(investlabr.viz.style = "research_note", investlabr.viz.context = "report")
on.exit(options(old))
viz_style_set("research_note", "report")
})
data <- data.frame(date = as.Date("2025-01-01") + 0:9, value = 1:10)
p <- ggplot2::ggplot(data, ggplot2::aes(date, value)) + ggplot2::geom_line()
p <- viz_theme_apply(p, style = "policy_memo", show_compiler = FALSE)
p <- viz_annotate_last_value(p, data, "date", "value")
p <- viz_annotate_event_lines(p, data.frame(datetime = as.Date("2025-01-05")))
p <- viz_annotate_regime_bands(p, data.frame(
start = as.Date("2025-01-02"), end = as.Date("2025-01-04")
))
viz_annotate_source_caption(p, "Synthetic data", "Illustration only")