Question:
What are the best practices to go about setting a "global" financial calendar using load_rmetrics_calenders()
,
ie a singular run of a function in golem?
Background:
This question is asked prior to finding a possible solution. I am using a function that I made which uses the {bizdays}
package to determine certain financial dates. I need to use the function load_rmetrics_calenders()
to initiate/set the calenders for a subsequent call in bizdayz::adjust.previous(..., cal = "Rmetrics/NYSE)
. I understand I could also use a globl setting to set the calneder but that has given me issues in the past.
I would like the to run load_rmetrics_calenders()
once at the beginning of a golem instance -- rather than having to call the function directly in the function, which slows it down a fair bit.
Reprex:
my_function<- function(stock = NULL, from = NULL, to = NULL, ...){
# Set Biz Calender
# bizdays::load_rmetrics_calendars(year = c(1950:2030), financial = TRUE)
# DEFENSIVES ---------------------------------------------------------------------------------------------------
# Assign `to` --> yesterdays close, will reset when close data comes in, 12am
to <- bizdays::adjust.previous(Sys.Date() - 1, cal = "Rmetrics/NYSE")
I would like to omit setting the calendar every time I call this function, or its called in the golemApp
instance while running online.
Possible answers:
load_rmetrics_calenders()
within golem::runApp()
--> once when launchedload_rmetrics_calenders()
within the server of a golem
module that acts as a homepage for the website/app#1: Current implementation
# Just running the function within the `runApp()`
run_app <- function(
onStart = NULL,
options = list(),
enableBookmarking = NULL,
...
) {
#Configure financial calender
golem::cat_dev("Loading NYSE calender from Quantlib \n")
bizdays::load_quantlib_calendars(ql_calendars = "UnitedStates/NYSE", from = "1950-01-01", to = "2030-01-01")
golem::cat_dev("Done loading calender. \n")
# Configure global polished settings
polished_config()
reactlog::reactlog_enable()
with_golem_options(
app = brochureApp(
# Putting the resources here
golem_add_external_resources(),
# Add pages
welcomePage(),
# login(),
dashboard(),
# logout(),
terms(),
onStart = onStart,
options = options,
enableBookmarking = enableBookmarking,
wrapped = shiny::tagList
),
golem_opts = list(...)
)
}
#2: Writing it in a script to run instead of calling runApp()
ie from Docker
# .R file to be called instead of running run_app() explicitly
#Configure financial calender
golem::cat_dev("Loading NYSE calender from Quantlib \n")
bizdays::load_quantlib_calendars(ql_calendars = "UnitedStates/NYSE", from = "1950-01-01", to = "2030-01-01")
golem::cat_dev("Done loading calender. \n")
# Configure global polished settings
polished_config(...)
reactlog::reactlog_enable()
# Run app with the calendar loaded
run_app()
You can run the function before the run_app()
function is launched and pass the result as an argument to the run_app()
fun.
For example: https://github.com/inrae/diades.atlas/blob/main/app.R#L30, here, I build a series of elements and they are passed to run_app(), so it's run less often (here, every time a new app is launched in RStudio Connect).
You can also set at the top of your server if you want the function to be launched at every shiny session (but I suppose this is not exactly what you want).
So, it depends of your deployment logic:
If you're deploying a container, you can use (pseudo code here) : CMD R -e "myapp::run_app(data = mypak:build_stuff())"
. Note that it will depend on the container management service you are using. For example Shiny Proxy will run one container by user, so build_stuff()
will be called every time a new user comes.
If you're on RStudio Product, you can use the run_app() method from the linked GitHub code.
If you need to explore the behavior of {golem}
apps and when things are run, I've got a toy example here https://github.com/ColinFay/golemexamples/tree/master/golemloadorder that will let you know when things are run/loaded.
Cheers, Colin