- Package name: finnts
- Purpose: The Microsoft Finance Time Series Forecasting Framework, aka finnts or Finn, is an automated forecasting framework for producing financial forecasts.
- Primary users / workflows: Low code agent based solution for financial forecasting, with a focus on time series data. The package provides tools for data preprocessing, model training, and forecast generation, all designed to be user-friendly and accessible to both beginners and experienced practitioners in the field of financial forecasting.
- Non-goals: The package is not intended for high-frequency trading applications, and it does not include tools for data visualization or advanced statistical analysis beyond what is necessary for forecasting.
Make changes that are testable, documented, and R CMD check–clean. If you can't run tests/checks, say so and explain what would be run.
Prefer the repo's existing dependency workflow:
- If
renv.lockexists:R -q -e 'install.packages("renv"); renv::restore()'
- Otherwise:
R -q -e 'install.packages("devtools"); devtools::install_deps(dependencies = TRUE)'
vip (>= 0.5.0)is a suggested package fromhttps://bgreenwell.r-universe.devand requires R 4.1 or newer.- Feature selection also requires the suggested
Boruta,corrr, andrangerpackages. Keeprangerdeclared directly because Boruta 10.0 no longer installs it as a strong dependency. - Use Boruta's
getImpRfZranger adapter to preserve FinnTS behavior across Boruta 10.0 and later; do not rely on Boruta's changing default importance provider. - FinnTS must install, load, and pass its CRAN-style check without
vip; never move it toImports,Depends, orLinkingTowithout an explicit packaging decision. - Feature selection may require
vipand must fail early with actionable installation guidance when it is unavailable. - Model summaries must retain non-importance sections without
vip; only variable-importance output may be omitted. - Keep both maintained-
vipcompatibility coverage and the explicit CI check without any feature-selection packages.
- Document (roxygen):
R -q -e 'devtools::document()' - Run tests:
R -q -e 'devtools::test()' - Full check:
R -q -e 'devtools::check()'
devtools::test()runs againstpkgload::load_all(), which does not always expose non-exported package helpers to PSOCKforeachworkers like an installed package namespace does.- A test-only
.exportmay therefore be needed even when production code does not need one. Before adding.exportto production for a missing-helper error, install the current source into a temporary library and reproduce the sameforeachcall from the installed namespace.
- The CRAN profile is deterministic and must never call live LLM or foundation-model endpoints, even when credentials are present.
- Simulate CRAN skips with
R -q -e 'withr::with_envvar(c(NOT_CRAN = "false"), devtools::test())'. - Optional runtime gates are
FINNTS_TEST_TIME_LIMIT_SECONDSfor the full suite andFINNTS_TEST_FILE_TIME_LIMIT_SECONDSper file; keep the CRAN profile below ten minutes and use 90 seconds as the per-file budget for the restoredfit_resamples()path. - Non-CRAN runs automatically execute every live Agent, Chronos, TimeGPT/Nixtla, and TimesFM test when that provider's credentials are available; there are no additional opt-in flags.
- Preserve every existing
testthat::skip_on_cran()marker, including deterministic, integration, performance, and credential-security tests. Do not remove one solely because a test was optimized or does not use a network connection. - Live tests must skip on CRAN before checking credentials or invoking a provider. Credentials must never override CRAN skipping.
- The existing R CMD check matrix supplies its configured Agent, Nixtla, and Chronos credentials, so those live tests run automatically. Other provider tests run when their credentials are present in the environment. Fork pull requests cannot receive repository secrets and therefore skip live tests.
- Do not repeat full
prep_data()/prep_models()/train_models()pipelines only to manufacture downstream test input. Prefer deterministic artifacts, one directly finalized fit, or an immutable prepared template copied into an isolated test directory.
- Automatic MARS tuning must exclude
prune_method = "cv"; explicit multistep CV pruning must supply a boundednfoldvalue. - Cover all supported
date_typevalues and assert exact horizon-to-submodel routing, training rows, lag-feature eligibility, and forecast row identity. - The daily multistep matrix is part of the standard test suite and must pass after changing lag generation, feature selection, multistep fitting, or prediction.
- Preserve both daily paths: all six adapters with explicit lags/outlier cleaning and GLMnet with automatic lags/raw data.
- Format:
R -q -e 'if (requireNamespace("styler", quietly=TRUE)) styler::style_pkg()' - Lint:
R -q -e 'if (requireNamespace("lintr", quietly=TRUE)) lintr::lint_package()'
R -q -e 'if (requireNamespace("pkgdown", quietly=TRUE)) pkgdown::build_site()'
R/— implementation (functions, classes, methods)man/— generated.Rddocs (DO NOT hand-edit; generated by roxygen2)tests/testthat/— unit testsvignettes/— long-form docs, tutorials, examplesDESCRIPTION— dependencies, metadata, versionNAMESPACE— generated (DO NOT hand-edit if using roxygen2)NEWS.md— user-facing change log
When adding or changing user-facing behavior:
- Design: state what changes for the user + any API changes (args, return types, errors).
- Implement: update code in
R/(keep diff minimal, avoid unrelated refactors). - Tests: add/extend tests in
tests/testthat/for:- happy path
- 1–2 edge cases
- regression test for the bug/feature request (if applicable)
- Docs:
- update roxygen comments (
@param,@return,@examples) - run
devtools::document()soman/*.Rdstays in sync - update vignettes if the change affects them or if you added a significant new feature that users should know about
- update roxygen comments (
- Quality gates:
devtools::test()devtools::check()- style/lint (if configured for the repo)
- Changelog:
- bump version in
DESCRIPTIONandNEWS.md - if behavior changed, add a bullet to
NEWS.md
- bump version in
- Prefer small, composable functions.
- Keep exported functions stable; introduce breaking changes only as a last resort, ask before adding, with an explicit note in NEWS.
- Agent workflows accept one
llmChat template and create a fresh, empty-history session for every graph that can access the LLM, including EDA, forecast update, each time-series combo, and Q&A. Never mutate the template. For parallel forecasts, letforeachserialize the template and use the publicChat$clone(deep = TRUE)method inside each series workflow after it reaches the worker. A series session may persist across its own iterations but must never be shared across series. Parallel workflows require ellmer 0.4.0 or later in the main process and every worker; do not call internal ellmer constructors or mutate provider credential fields. - Prefer base R and packages already declared in
Depends,Imports, orSuggestsbefore adding a dependency. - A new package dependency is allowed only for a concrete new feature when existing dependencies and a small, maintainable custom implementation are inadequate, unsafe, or would recreate substantial mature functionality.
- Do not add dependencies for bug fixes, documentation, formatting, developer convenience, or trivial helpers. Do not vendor third-party source code.
- A dependency-changing pull request must document the alternatives considered, why the package is necessary, maintenance/security/license implications, why it belongs in
ImportsorSuggests, and any required version constraint. It must also pass a clean-library installation anddevtools::check(). - Comments:
- Use short
# descriptionstyle comments. Do not use decorative separator lines (e.g.# ----------,# =========,# ****). - Keep comments concise and descriptive, matching the existing style throughout the package.
- Use short
- Errors:
- be consistent (class/messages), include actionable messages.
- Use
stop()for user-facing errors,warning()for recoverable issues, andmessage()for informational output. - Performance:
- avoid unnecessary copies in tight loops; vectorize where it improves clarity/perf.
- Do not commit secrets (tokens, keys), local paths, or machine-specific config.
- Do not edit
NAMESPACEorman/*.Rdby hand if roxygen2 is in use. - Do not add package dependencies outside the feature-only dependency policy above.
- Do not silence failing tests by deleting or weakening them; fix the underlying issue.
- Do not create code/functions that delete files.
Before coding, propose:
- 1–2 plausible interpretations,
- the tradeoffs,
- and which files/functions you expect to touch. Then proceed with the most conservative/backward-compatible option unless told otherwise.