Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1f48b70
#3 Repaired is_by_currency examples
JustinMShea Jul 23, 2026
665727d
#3 added return values to 21 functions, as specified by CRAN
JustinMShea Jul 23, 2026
97c93ce
#3 roxygenize docs
JustinMShea Jul 23, 2026
d132d05
## removed unexported examples and replaced FinancialInstrument:::.i…
JustinMShea Jul 23, 2026
a0067a2
#3 roxygenize
JustinMShea Jul 23, 2026
a3403d6
Initial plan
Copilot Jul 23, 2026
11573ea
additional issues
JustinMShea Jul 23, 2026
484a39e
Merge cran/resubmission-1.4.0: return values, example fixes, and doc …
Copilot Jul 23, 2026
e302839
CRAN 1.4.1 compliance: verbose Tick2Sec, loadInstruments fix, tests, …
Copilot Jul 23, 2026
9efb513
Add blotter and quantstrat compatibility checks
JustinMShea Jul 23, 2026
fa8ec28
blotter/quantstrat not building
JustinMShea Jul 23, 2026
dc7a111
fix error in YAML syntex
JustinMShea Jul 23, 2026
9d7fd43
Fix test: dir.create needs recursive=TRUE for R CMD check temp path
Copilot Jul 23, 2026
95697a8
Restore rm_by_currency public API
JustinMShea Jul 23, 2026
e3c4e92
#3 added `donttest` wraper back to the example, as run time is just o…
JustinMShea Jul 23, 2026
975f7c6
Fix test: use tempdir() directly, no subdirectory creation needed
Copilot Jul 23, 2026
ea6147c
Restore rm_by_currency public API
JustinMShea Jul 23, 2026
37e16e0
#3 added `donttest` wraper back to the example, as run time is just o…
JustinMShea Jul 23, 2026
bb6c649
Test blotter and quantstrat compatibility
JustinMShea Jul 23, 2026
0ecf96e
Fix reverse dependency resolution
JustinMShea Jul 23, 2026
ee943dc
Strengthen instrument save and load tests
JustinMShea Jul 23, 2026
c521d0f
"Add rm_by_currency compatibility tests"
JustinMShea Jul 23, 2026
33d3a49
Correct CRAN resubmission notes
JustinMShea Jul 23, 2026
e5de3e5
#3 updated paths in examples for allticks2sec and args in related doc…
JustinMShea Jul 23, 2026
daeab47
Add blotter and quantstrat compatibility checks
JustinMShea Jul 23, 2026
35399c9
Simplify reverse dependency checks
JustinMShea Jul 23, 2026
fa181dd
relax verification script
JustinMShea Jul 23, 2026
be0af4d
fix indent
JustinMShea Jul 23, 2026
0e61e7f
quantstrat fails, but likely independent of updates to FinancialIntru…
JustinMShea Jul 23, 2026
e75940f
quanstrat fails identically, regardless of current FinancialInstrumen…
JustinMShea Jul 23, 2026
aa09c00
Merge branch 'cran/resubmission-1.4.0' into review/cran-1.4.1-fixes
JustinMShea Jul 23, 2026
dd65d0e
Merge pull request #6 from JustinMShea/review/cran-1.4.1-fixes
JustinMShea Jul 23, 2026
80fa517
updated CRAN comments summary
JustinMShea Jul 23, 2026
04a2f87
#3 updated cran comments
JustinMShea Jul 24, 2026
307cd35
#3 fixed examples as defined in CRAN email
JustinMShea Jul 24, 2026
a53f627
cleaned up examples and roxygenized
JustinMShea Jul 24, 2026
96ad5c3
#3 remove example from unexportable function, as directed by CRAN com…
JustinMShea Jul 24, 2026
49823f7
#3 fixed open bracket and roxygenized
JustinMShea Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions .github/workflows/reverse-dependency-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
name: Reverse dependency checks

on:
workflow_dispatch:
push:
pull_request:

permissions:
contents: read

concurrency:
group: reverse-deps-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
reverse-dependencies:
name: blotter and quantstrat
runs-on: ubuntu-latest

env:
_R_CHECK_FORCE_SUGGESTS_: false

steps:
- name: Check out FinancialInstrument
uses: actions/checkout@v4

- name: Set up R
uses: r-lib/actions/setup-r@v2
with:
r-version: release
use-public-rspm: true

- name: Install FinancialInstrument dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: |
any::rcmdcheck
any::tinytest
any::testthat
any::PerformanceAnalytics
any::foreach
any::iterators

- name: Install current FinancialInstrument
run: R CMD INSTALL .

- name: Clone downstream packages
run: |
mkdir -p revdeps

git clone --depth 1 \
https://github.com/braverock/blotter.git \
revdeps/blotter

git clone --depth 1 \
https://github.com/braverock/quantstrat.git \
revdeps/quantstrat

- name: Install remaining CRAN dependencies
shell: Rscript {0}
run: |
required <- c(
"quantmod",
"xts",
"zoo",
"TTR",
"PerformanceAnalytics",
"foreach",
"iterators",
"boot",
"tinytest",
"testthat"
)

missing <- required[
!vapply(
required,
requireNamespace,
logical(1),
quietly = TRUE
)
]

if (length(missing)) {
install.packages(missing)
}

- name: Reinstall current FinancialInstrument
run: R CMD INSTALL .

- name: Install blotter
run: R CMD INSTALL revdeps/blotter

- name: Verify FinancialInstrument and blotter
shell: Rscript {0}
run: |
expected_fi <- package_version(
read.dcf(
"DESCRIPTION",
fields = "Version"
)[1, 1]
)

expected_blotter <- package_version(
read.dcf(
"revdeps/blotter/DESCRIPTION",
fields = "Version"
)[1, 1]
)

installed_fi <- packageVersion(
"FinancialInstrument"
)

installed_blotter <- packageVersion(
"blotter"
)

cat(
"FinancialInstrument:",
as.character(installed_fi),
"\n"
)

cat(
"blotter:",
as.character(installed_blotter),
"\n"
)

stopifnot(
installed_fi == expected_fi,
installed_blotter == expected_blotter
)

- name: Check blotter
shell: Rscript {0}
run: |
result <- rcmdcheck::rcmdcheck(
"revdeps/blotter",
args = c(
"--no-manual",
"--no-vignettes"
),
build_args = "--no-build-vignettes",
error_on = "error"
)

print(result)

- name: Reinstall tested dependency chain
run: |
R CMD INSTALL .
R CMD INSTALL revdeps/blotter

- name: Install quantstrat
run: R CMD INSTALL revdeps/quantstrat

- name: Verify quantstrat dependency chain
shell: Rscript {0}
run: |
library(FinancialInstrument)
library(blotter)
library(quantstrat)

cat(
"FinancialInstrument:",
as.character(packageVersion("FinancialInstrument")),
"\n"
)

cat(
"blotter:",
as.character(packageVersion("blotter")),
"\n"
)

cat(
"quantstrat:",
as.character(packageVersion("quantstrat")),
"\n"
)

- name: Check quantstrat
continue-on-error: true
shell: Rscript {0}
run: |
result <- rcmdcheck::rcmdcheck(
"revdeps/quantstrat",
args = c(
"--no-manual",
"--no-vignettes"
),
build_args = "--no-build-vignettes",
check_dir = "quantstrat-check",
error_on = "never"
)

print(result)

- name: Upload quantstrat check results
if: always()
uses: actions/upload-artifact@v4
with:
name: quantstrat-check-results
path: quantstrat-check
if-no-files-found: warn

2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: FinancialInstrument
Type: Package
Title: Financial Instrument Modeling Infrastructure
Version: 1.4.0
Version: 1.4.1
Authors@R: c(person(given = "Peter",
family = "Carl",
role = "aut"),
Expand Down
40 changes: 40 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
# FinancialInstrument 1.4.1

## CRAN Compliance Fixes

* **Console Output:** Added `verbose = FALSE` parameter to `alltick2sec()` at
the end of its signature. The unconditional `cat()` progress call is now
suppressible via `verbose = FALSE` (the default) and uses `message()` for
optional progress reporting, preserving all existing return values.

* **Return-Value Documentation:** Added `@return` tags to all exported functions
that were previously missing `\value` sections, describing return class,
structure, and side-effects where applicable.

* **Examples — Temporary Directories:** Replaced `dir.create("tmpdata")` with
`tempdir()` / `tempfile()` in the `saveInstruments`, `loadInstruments`,
`CompareInstrumentFiles`, `saveSymbols.common`, `saveSymbols.days`, and
`getSymbols.FI` examples. Cleanup is handled via `tryCatch(finally = ...)`.

* **Examples — Internal Registry Access:** Removed `FinancialInstrument:::.instrument`
from all documentation examples and replaced backup/restore patterns with
exported `saveInstruments()` / `reloadInstruments()` calls.

* **Examples — Unmatched Parenthesis:** Fixed the unmatched parenthesis in the
`ls_by_currency()` example.

* **Examples — Commented-Out Code:** Removed commented-out executable
alternatives from examples.

* **`\dontrun{}` vs `\donttest{}`:** Converted examples that can run in a
standard R session from `\dontrun{}` to either runnable or `\donttest{}`
blocks; retained `\dontrun{}` only for genuinely unrunnable code (e.g.,
examples requiring live network access or specific external files).

* **Namespace:** Confirmed `expires()` is exported. Removed examples for
genuinely unexported helpers.

* **`loadInstruments` compatibility:** Updated the header check in
`loadInstruments()` to recognise both the legacy `"#auto"` prefix and the
new `"# Auto"` prefix written by the refactored `saveInstruments()`.

# FinancialInstrument 1.4.0

## New Maintainer
Expand Down
84 changes: 55 additions & 29 deletions R/CompareInstrumentFiles.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,70 @@
#'
#' Compare the .instrument environments of two files
#'
#' This will load two instrument files (created by
#' \code{\link{saveInstruments}}) and find the differences between them. In
#' addition to returning a list of difference that are found, it will produce
#' messages indicating the number of instruments that were added, the number of
#' instruments that were removed, and the number of instruments that are
#' This will load two instrument files (created by
#' \code{\link{saveInstruments}}) and find the differences between them. In
#' addition to returning a list of difference that are found, it will produce
#' messages indicating the number of instruments that were added, the number of
#' instruments that were removed, and the number of instruments that are
#' different.
#'
#' @param file1 A file containing an instrument environment
#' @param file2 Another file containing an instrument environment. If not
#' provided, \code{file1} will be compared against the currently loaded
#' @param file2 Another file containing an instrument environment. If not
#' provided, \code{file1} will be compared against the currently loaded
#' instrument environment.
#' @param ... Arguments to pass to \code{\link{all.equal.instrument}}
#' @return A list that contains the names of all instruments that were added,
#' the names of all instruments that were removed, and the changes to all
#' instruments that were updated (per \code{\link{all.equal.instrument}}).
#' @author Garrett See
#' @seealso \code{\link{saveInstruments}}, \code{\link{all.equal.instrument}}
#' @examples
#' \dontrun{
#' #backup current .instrument environment
#' bak <- as.list(FinancialInstrument:::.instrument, all.names=TRUE)
#' old.wd <- getwd()
#' tmpdir <- tempdir()
#' setwd(tmpdir)
#' rm_instruments(keep=FALSE)
#' # create some instruments and save
#' stock(c("SPY", "DIA", "GLD"), currency("USD"))
#' saveInstruments("MyInstruments1")
#' # make some changes
#' rm_stocks("GLD")
#' stock("QQQ", "USD")
#' instrument_attr("SPY", "description", "S&P ETF")
#' saveInstruments("MyInstruments2")
#' CompareInstrumentFiles("MyInstruments1", "MyInstruments2")
#' #Clean up
#' setwd(old.wd)
#' reloadInstruments(bak)
#' }
#' @examples
#' example_dir <- tempfile("fi-compare-")
#' dir.create(example_dir)
#'
#' backup_name <- "backup.RData"
#' file1_name <- "instruments1.RData"
#' file2_name <- "instruments2.RData"
#'
#' backup_path <- file.path(example_dir, backup_name)
#' file1_path <- file.path(example_dir, file1_name)
#' file2_path <- file.path(example_dir, file2_name)
#'
#' saveInstruments(backup_name, dir = example_dir)
#'
#' tryCatch(
#' {
#' stopifnot(file.exists(backup_path))
#'
#' rm_instruments(keep.currencies = FALSE)
#' currency("USD")
#' stock(c("SPY", "DIA", "GLD"), currency = "USD")
#' saveInstruments(file1_name, dir = example_dir)
#'
#' stopifnot(file.exists(file1_path))
#'
#' rm_stocks("GLD")
#' stock("QQQ", currency = "USD")
#' instrument_attr(
#' "SPY",
#' "description",
#' "S&P 500 ETF"
#' )
#' saveInstruments(file2_name, dir = example_dir)
#'
#' stopifnot(file.exists(file2_path))
#'
#' CompareInstrumentFiles(file1_path, file2_path)
#' },
#' finally = {
#' if (file.exists(backup_path)) {
#' reloadInstruments(backup_name, dir = example_dir)
#' }
#'
#' unlink(example_dir, recursive = TRUE)
#' }
#' )
#'
#' @export
CompareInstrumentFiles <- function(file1, file2, ...) {
force(file1)
Expand Down Expand Up @@ -83,7 +109,7 @@ CompareInstrumentFiles <- function(file1, file2, ...) {
} else {
message(paste(liu, "instruments updated."))
}
out <- c(list(new.instruments=new.instruments,
out <- c(list(new.instruments=new.instruments,
removed.instruments=removed.instruments),
diffs)
out <- Filter(function(x) length(x) > 0L, out)
Expand Down
10 changes: 5 additions & 5 deletions R/FinancialInstrument-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ NULL
#' where and how your market data are stored so that
#' \code{\link[quantmod]{getSymbols}} will work for you.
#'
#' FinancialInstrument's functions build and manipulate objects that are stored
#' in an environment named ".instrument" at the top level of the package
#' (i.e. "FinancialInstrument:::.instrument") rather than the global
#' environment, \code{.GlobalEnv}. Objects may be listed using
#' \code{ls_instruments()} (or many other ls_* functions).
#' FinancialInstrument stores instrument definitions in an internal
#' package-level environment named `.instrument`, rather than in
#' `.GlobalEnv`. Users should access instrument definitions through exported
#' functions such as `getInstrument()`, `ls_instruments()`,
#' `saveInstruments()`, and `loadInstruments()`.
#'
#' We store instruments in their own environment for two reasons. First, it
#' keeps the user's workspace less cluttered and lowers the probability of
Expand Down
Loading
Loading