Last active
July 10, 2026 23:38
-
-
Save SimoneMugnai/1873d5725bde006047a2ccbca61a6836 to your computer and use it in GitHub Desktop.
Retirement Analytics R Package- GSOC2024 Simone Mugnai
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Retirement Analytics R Package - Google Summer of Code 2024 | |
| You can view the full project repository here: [Retirement Analytics on GitHub](https://github.com/braverock/RetirementAnalytics) | |
| ## Overview | |
| The "Retirement Analytics" project is an advanced R package developed during the Google Summer of Code (GSoC) 2024. It provides comprehensive tools for modeling retirement planning scenarios, extending the capabilities of existing financial libraries like PortfolioAnalytics and PerformanceAnalytics. This package is designed to fill a crucial gap in the R ecosystem by offering robust, open-source tools for retirement planning analysis. | |
| ## Key Features | |
| - **Portfolio Customization**: | |
| - Define and implement tailored portfolio configurations beyond the standard 60-40 split. | |
| - Allows for more flexible and complex financial strategies. | |
| - **Tax System Integration**: | |
| - Introduces a basic tax system with account types (non-taxable, deferred, taxable). | |
| - Customizable flat tax calculations add realism and accuracy to simulations. | |
| - **Simulation Enhancements**: | |
| - Features advanced simulation capabilities including Monte Carlo simulations and multivariate bootstrapping. | |
| - Models financial outcomes under various market conditions. | |
| - **Data Integration**: | |
| - Integrates external data sources like Quandl and Tiingo. | |
| - Enables dynamic portfolio rebalancing using historical financial data. | |
| - **Visualization Tools** (Planned): | |
| - Potential future enhancements may include visualization tools. | |
| - Example: Probability graphs with Area Under the Curve (AUC) representation for effective result interpretation. | |
| ## Objectives | |
| This project aims to establish a robust, open-source framework for retirement planning analysis. By enhancing the R ecosystem with these tools, the package will be invaluable for researchers, financial advisors, and anyone interested in detailed financial simulations and planning. | |
| ## Development Process | |
| Since the repository was initially empty with only the package skeleton prepared, the development process was primarily managed through direct commits. This approach allowed for continuous integration of features and immediate testing of functionalities as they were developed. | |
| In the following sections, I will report the code, along with explanations and a detailed developer log, documenting the progression of the project from inception to its current state. | |
| Reminder that each of these classes and the code in general were drafted from scratch. Here, I present the final version (final for GSoC purposes, of course). In the following section, I will show the various processes and changes to each of them. | |
| ## Code: Household Creation and Management | |
| Below is the R code used to create and manage households within the simulation framework: | |
| ```r | |
| #' Create a household | |
| #' | |
| #' This function creates a household object. | |
| #' | |
| #' @param household_name The name of the household. | |
| #' @param persons A list of persons in the household. | |
| #' @return A household object. | |
| #' @export | |
| create_household <- function(household_name, persons = list()) { | |
| stopifnot(is.character(household_name)) | |
| household <- list( | |
| household_name = household_name, | |
| persons = persons | |
| ) | |
| structure(household, class = c("household", "list")) | |
| } | |
| #' Add a person to a household | |
| #' | |
| #' This function adds a person to the household and assigns a role. | |
| #' | |
| #' @param household The household object. | |
| #' @param person The person object to add. | |
| #' @param role The role of the person in the household. | |
| #' @return The updated household object. | |
| #' @export | |
| add_person <- function(household, person, role) { | |
| person$role <- role | |
| household$persons <- append(household$persons, list(person)) | |
| return(household) | |
| } | |
| #' Sum income of household | |
| #' | |
| #' This function sums the income of all persons in the household. | |
| #' | |
| #' @param household The household object. | |
| #' @return The total income of the household. | |
| #' @export | |
| sum_income <- function(household, ...) { | |
| UseMethod("sum_income") | |
| } | |
| #' @export | |
| sum_income.household <- function(household, ...) { | |
| total_income <- sum(sapply(household$persons, function(person) person$income)) | |
| return(total_income) | |
| } | |
| #' Summary of household | |
| #' | |
| #' This function provides a summary of the household. | |
| #' | |
| #' @param object The household object. | |
| #' @export | |
| summary.household <- function(object, ...) { | |
| cat("Household Name:", object$household_name, "\n") | |
| cat("Number of Persons:", length(object$persons), "\n") | |
| cat("Persons Details:\n") | |
| for (i in 1:length(object$persons)) { | |
| person <- object$persons[[i]] | |
| cat("Role:", person$role, "\n") | |
| summary.person(person) | |
| cat("\n") | |
| } | |
| cat("Total Household Income:", sum_income(object), "\n") | |
| } | |
| ``` | |
| The following R code defines a set of functions to create and manage household objects within a retirement planning simulation framework. | |
| 1. **`create_household`**: | |
| - This function initializes a household object. | |
| - It takes two arguments: `household_name`, which is the name of the household, and `persons`, which is a list of individuals in the household (default is an empty list). | |
| - The function returns a structured object of class "household" and "list". | |
| 2. **`add_person`**: | |
| - This function adds a person to the existing household. | |
| - It requires three arguments: `household`, the household object; `person`, the person object to be added; and `role`, the role of the person in the household. | |
| - The function appends the person to the household’s list of persons and returns the updated household object. | |
| 3. **`sum_income`**: | |
| - This generic function is designed to sum the total income of all individuals in a household. | |
| - The method `sum_income.household` calculates the total income by summing the `income` attributes of all persons in the household and returns the total. | |
| 4. **`summary.household`**: | |
| - This function provides a summary of the household. | |
| - It displays the household's name, the number of persons in the household, details of each person (including their role), and the total household income. | |
| ## Code: Person Object Creation and Management | |
| ```r | |
| #' Create a person | |
| #' | |
| #' This function creates a person object. | |
| #' | |
| #' @param name The name of the person. | |
| #' @param birth_date The birth date of the person. | |
| #' @param income The income of the person. | |
| #' @param retirement_date The retirement date of the person. | |
| #' @param longevity The expected longevity of the person. | |
| #' @return A person object. | |
| #' @export | |
| create_person <- function(name, birth_date, income, retirement_date, longevity) { | |
| person <- list( | |
| name = name, | |
| birth_date = as.Date(birth_date), | |
| income = income, | |
| retirement_date = as.Date(retirement_date), | |
| longevity = longevity | |
| ) | |
| structure(person, class = c("Person", "list")) | |
| } | |
| #' Calculate age | |
| #' | |
| #' This function calculates the age of a person. | |
| #' | |
| #' @param person A person object. | |
| #' @return The age of the person. | |
| #' @export | |
| calculate_age <- function(person, ...) { | |
| UseMethod("calculate_age") | |
| } | |
| #' @export | |
| calculate_age.Person <- function(person) { | |
| age <- as.numeric(difftime(Sys.Date(), person[["birth_date"]], units = "weeks")) / 52.25 | |
| return(floor(age)) | |
| } | |
| #' Calculate retirement age | |
| #' | |
| #' This function calculates the age of a person at retirement. | |
| #' | |
| #' @param person A person object. | |
| #' @return The age of the person at retirement. | |
| #' @export | |
| calculate_retirement_age <- function(person, ...) { | |
| UseMethod("calculate_retirement_age") | |
| } | |
| #' @export | |
| calculate_retirement_age.Person <- function(person) { | |
| age_at_retirement <- as.numeric(difftime(person[["retirement_date"]], person[["birth_date"]], units = "weeks")) / 52.25 | |
| return(floor(age_at_retirement)) | |
| } | |
| #' Summary of person | |
| #' | |
| #' This function provides a summary of the person. | |
| #' | |
| #' @param object A person object. | |
| #' @return A list containing the summary information of the person. | |
| #' @export | |
| summary.Person <- function(object) { | |
| age <- calculate_age(object) | |
| summary_list <- list( | |
| Name = object[["name"]], | |
| Birth_Date = format(object[["birth_date"]], "%Y-%m-%d"), | |
| Income = object[["income"]], | |
| Retirement_Date = format(object[["retirement_date"]], "%Y-%m-%d"), | |
| Longevity = object[["longevity"]], | |
| Current_Age = age | |
| ) | |
| return(summary_list) | |
| } | |
| ``` | |
| This set of functions is designed to create and manage `Person` objects within the retirement simulation framework: | |
| - **`create_person`**: Initializes a person object with attributes such as name, birth date, income, retirement date, and longevity. | |
| - **`calculate_age`**: Computes the current age of the person based on their birth date. | |
| - **`calculate_retirement_age`**: Determines the age of the person at the time of retirement. | |
| - **`summary.Person`**: Provides a summary of the person's details, including their current age and other key attributes. | |
| ## Code: Portfolio and Account Management in Retirement Analytics | |
| ```r | |
| library(PerformanceAnalytics) | |
| library(boot) | |
| library(quantmod) | |
| portfolio_env <- new.env() | |
| # Function to add an existing portfolio to the environment | |
| add_existing_portfolio_to_env <- function(portfolio_name, portfolio) { | |
| portfolio_env[[portfolio_name]] <- portfolio | |
| } | |
| # Function to add a return value to a portfolio in the environment | |
| add_return_to_env_portfolio <- function(portfolio_name, return_value, ...) { | |
| portfolio <- portfolio_env[[portfolio_name]] | |
| stopifnot(!is.null(portfolio), inherits(portfolio, "xts")) | |
| new_return <- xts(matrix(return_value, ncol = 1), order.by = Sys.Date()) | |
| colnames(new_return) <- colnames(portfolio) | |
| portfolio <- rbind(portfolio, new_return) | |
| portfolio_env[[portfolio_name]] <- portfolio | |
| } | |
| # Function to retrieve returns of a portfolio in the environment | |
| get_env_portfolio_returns <- function(portfolio_name, ...) { | |
| portfolio <- portfolio_env[[portfolio_name]] | |
| stopifnot(!is.null(portfolio), inherits(portfolio, "xts")) | |
| portfolio | |
| } | |
| # Function to calculate the total return of a portfolio in the environment | |
| calculate_env_portfolio_total_return <- function(portfolio_name, ...) { | |
| portfolio <- portfolio_env[[portfolio_name]] | |
| stopifnot(!is.null(portfolio), inherits(portfolio, "xts")) | |
| total_return <- Return.cumulative(portfolio, ...) | |
| total_return | |
| } | |
| # Function to create an account object | |
| create_account <- function(account_name, person, portfolios = list(), balance = 0, taxable = FALSE, tax_rate = 0, ...) { | |
| stopifnot(is.character(account_name), is.character(person), is.numeric(balance)) | |
| valid_taxable_values <- c(FALSE, TRUE, "deferred") | |
| stopifnot(taxable %in% valid_taxable_values) | |
| stopifnot(is.list(portfolios)) | |
| if (taxable != FALSE) stopifnot(is.numeric(tax_rate) && tax_rate >= 0 && tax_rate <= 1) | |
| for (portfolio in portfolios) { | |
| stopifnot(inherits(portfolio, "xts")) | |
| } | |
| account <- list( | |
| account_name = account_name, | |
| person = person, | |
| portfolios = portfolios, | |
| balance = balance, | |
| taxable = taxable, | |
| tax_rate = ifelse(taxable == FALSE, 0, tax_rate), | |
| history = list() | |
| ) | |
| structure(account, class = c("account", "list")) | |
| } | |
| # Function to withdraw funds from an account | |
| withdraw_from_account <- function(account, amount, ...) { | |
| stopifnot(inherits(account, "account"), is.numeric(amount), amount > 0) | |
| actual_withdrawal <- amount | |
| if (account$taxable == "deferred") { | |
| tax_amount <- amount * account$tax_rate | |
| actual_withdrawal <- amount - tax_amount | |
| account$balance <- account$balance - amount | |
| } else if (account$taxable == TRUE) { | |
| tax_amount <- amount * account$tax_rate | |
| actual_withdrawal <- amount - tax_amount | |
| account$balance <- account$balance - actual_withdrawal | |
| } else { | |
| account$balance <- account$balance - amount | |
| } | |
| account$history[[length(account$history) + 1]] <- paste("Withdrew", amount, "from account:", account$account_name) | |
| return(list(account = account, actual_withdrawal = actual_withdrawal)) | |
| } | |
| # Function to fetch and store historical data | |
| fetch <- function(symbol, source = "tiingo", ...) { | |
| source("private_creds.R") | |
| if (source == "tiingo") { | |
| api_key <- Sys.getenv("TIINGO_API_KEY") | |
| if (api_key == "") stop("Tiingo API key not found.") | |
| getSymbols(symbol, src = "tiingo", api.key = api_key, auto.assign = TRUE, ...) | |
| } else if (source == "quandl") { | |
| api_key <- Sys.getenv("QUANDL_API_KEY") | |
| if (api_key == "") stop("Quandl API key not found.") | |
| getSymbols(symbol, src = "quandl", api.key = api_key, auto.assign = TRUE, ...) | |
| } else { | |
| stop("Unsupported data source.") | |
| } | |
| portfolio_env[[symbol]] <- get(symbol) | |
| } | |
| # Function to add a portfolio to an account and environment | |
| add_portfolio_to_account <- function(account, portfolio_name, portfolio, ...) { | |
| stopifnot(inherits(account, "account"), is.character(portfolio_name), inherits(portfolio, "xts")) | |
| account$portfolios[[portfolio_name]] <- portfolio | |
| account$history[[length(account$history) + 1]] <- paste("Added portfolio:", portfolio_name) | |
| add_existing_portfolio_to_env(portfolio_name, portfolio) | |
| return(account) | |
| } | |
| # Function to rebalance a portfolio | |
| rebalance_portfolio <- function(portfolio_name, target_allocation, rebalance_dates, ...) { | |
| portfolio <- portfolio_env[[portfolio_name]] | |
| stopifnot(!is.null(portfolio), inherits(portfolio, "xts")) | |
| if (!is.vector(target_allocation) || !all(names(target_allocation) %in% colnames(portfolio))) { | |
| stop("Target allocation must be a named vector with names matching portfolio columns.") | |
| } | |
| rebalanced_returns <- Return.portfolio(R = portfolio, weights = target_allocation, rebalance_on = rebalance_dates, ...) | |
| rebalanced_returns | |
| } | |
| # Function to estimate portfolio returns using multivariate bootstrap | |
| estimate_portfolio_return <- function(account, n_simulations = 1000, rebalance = TRUE, withdraw_amount, | |
| target_allocation = c(0.6, 0.4), rebalance_dates = "months", ...) { | |
| stopifnot(inherits(account, "account"), is.numeric(n_simulations), is.numeric(withdraw_amount)) | |
| portfolio_names <- names(account$portfolios) | |
| initial_balance <- account$balance | |
| bootstrap_sample <- function(data, indices) { | |
| data[indices, ] | |
| } | |
| calculate_block_length <- function(returns) { | |
| correlation_matrix <- cor(returns) | |
| avg_correlation <- mean(correlation_matrix[lower.tri(correlation_matrix)]) | |
| block_length <- max(1, round(1 / (1 - avg_correlation))) | |
| return(block_length) | |
| } | |
| simulate_returns <- function() { | |
| balance <- initial_balance | |
| for (name in portfolio_names) { | |
| portfolio <- portfolio_env[[name]] | |
| returns <- rebalance_portfolio(name, target_allocation, rebalance_dates, ...) | |
| block_length <- calculate_block_length(returns) | |
| bootstrapped_returns <- tsbootstrap(returns, statistic = bootstrap_sample, | |
| R = 1, l = block_length, sim = "fixed") | |
| for (ret in bootstrapped_returns) { | |
| balance <- balance * (1 + ret) - withdraw_amount | |
| } | |
| } | |
| balance | |
| } | |
| final_balances <- replicate(n_simulations, simulate_returns()) | |
| prob_success <- mean(final_balances > 0) | |
| list(final_balances = final_balances, probability_of_success = prob_success) | |
| } | |
| ``` | |
| This code manages financial portfolios and accounts within the retirement analytics framework. It includes functions for adding portfolios to an environment, calculating returns, creating accounts, and simulating portfolio performance using multivariate bootstrap methods. The `estimate_portfolio_return` function performs simulations to estimate the probability of success for a given portfolio under different scenarios. | |
| In addition, even if not reported, the repo inclued extensive unit-test for the basic functionalities of each class | |
| ## Summary | |
| To sum up, the package now covers the basic implementation, allowing the creation of a household, setting a goal, and performing basic simulations, including tax scenarios. However, it lacks some customizability in terms of portfolio flexibility and additional complexity in tax calculations and considerations. Moreover, the user interface is entirely absent due to time constraints. It would certainly require effort to present the simulation results more concisely, both graphically and conceptually, without needing to interpret the raw bootstrap results. | |
| # Retirement Analytics R Package - Initial Commits Overview | |
| Here, in this section, I report the various commits grouped by different stages of the development process, along with the developer log to summarize my ideas and the evolution of the work. | |
| ### [View the Initial Commits](https://github.com/braverock/RetirementAnalytics/compare/2e05df3998d0370bde0fecb15104421b2d647782...22bbcb465b33cd4e4db61f82c7602ab69395c3c0) | |
| ### Repository Setup: | |
| - Cloned and set up the repository in RStudio. | |
| - Initial commit: Added myself to the authors list in the DESCRIPTION file to test the setup. | |
| ### Documentation: | |
| - Created a Developer log to keep track of progress and tasks. | |
| ### Planned for Tomorrow: | |
| - Start drafting the "person" class using S3 or R6. | |
| ## 24/05/2024 | |
| - Studied and completed exercises on the S3-R6 OOP system. | |
| - Read a paper about Monte Carlo simulation for analyzing the impact of various factors on retirement planning: [The Impact of Asset Allocation, Savings and Retirement Horizons, Savings Rates, and Social Security Income in Retirement Planning: A Monte Carlo Analysis](https://www.researchgate.net/profile/Joseph-Smolira/publication/228709986_The_Impact_of_Asset_Allocation_Savings_and_Retirement_Horizons_Savings_Rates_and_Social_Security_Income_in_Retirement_Planning_A_Monte_Carlo_Analysis/links/0c96052ed47bf9dcb5000000/The-Impact-of-Asset-Allocation-Savings-and-Retirement-Horizons-Savings-Rates-and-Social-Security-Income-in-Retirement-Planning-A-Monte-Carlo-Analysis.pdf) by Joseph Smolira. | |
| ## 26/05/2024 | |
| - Uploaded S3 and R6 draft of Person class. | |
| I think S3 could be a better choice to have more freedom in defining and using methods across different classes and objects in general. This flexibility could be beneficial in terms of defining various key functions to improve the generalization of the package, allowing it to be used with different frameworks and leveraging it effectively. | |
| - Nonetheless, R6 with encapsulation could be more clear from a user's perspective. By defining the main attributes and methods for all classes, it can be used almost in sequence to have a very ordered simulation and scenario. The downside is that it could become a bit too strict in terms of the possible generalization of the package. | |
| ## 27/05/2024 | |
| - End of the community bonding period | |
| - Scheduled a meeting on Wednesday | |
| - Studied and reviewed some basic R packages that could be helpful for later simulations | |
| ## 29/05/2024 | |
| - **Meeting with Mentors:** Discussed the test of the `Person` class and decided to use the S3 OOP system. It was the safer choice, as R6 did not provide significant advantages at this stage. | |
| - Set up the next planned activities for the package development. | |
| - Discussed the probability of success and how to visualize and interpret it. | |
| - Renamed and moved the test of the S3 `Person` class to the `R` folder. | |
| ### Planned | |
| - Start developing the `Household` class. | |
| - Study how R packages are built and the best practices in R package development. | |
| ## 30/05/2024 | |
| - Study Package development in R | |
| - Deleted person_R6_test in Sandbox | |
| # Retirement Analytics R Package - Commit Comparison Overview (May - June 2024) | |
| ### [View the Commit Comparison](https://github.com/braverock/RetirementAnalytics/compare/f75100cf755481d2af534503101a66555dde8022...e4bbf9cb725b174913d9eb0d0594b39ff37d2a4d) | |
| ## 29/05/2024 | |
| - **Meeting with Mentors:** Discussed the test of the `Person` class and decided to use the S3 OOP system. It was the safer choice, as R6 did not provide significant advantages at this stage. | |
| - Set up the next planned activities for the package development. | |
| - Discussed the probability of success and how to visualize and interpret it. | |
| - Renamed and moved the test of the S3 `Person` class to the `R` folder. | |
| ### Planned | |
| - Start developing the `Household` class. | |
| - Study how R packages are built and the best practices in R package development. | |
| ## 30/05/2024 | |
| - Study Package development in R. | |
| - Deleted person_R6_test in Sandbox. | |
| ## 03/06/2024 | |
| ### Progress | |
| - Implemented and learned R `roxygen2` grammar to generate comments and documentation. | |
| - Learned about `devtools` and `testthat`. | |
| - Studied package development in R. | |
| - Started developing the `Household` class in the Sandbox: | |
| - Implemented basic functions such as `summary`, `add_person`, and `total_income`. | |
| ### Issues Encountered | |
| - **Summary Function**: The `summary` function does not show the information correctly and returns more metadata than necessary. | |
| - **Total Income Function**: Encountered an error with the `total_income` function, but it should be easily solvable tomorrow. | |
| ### Next Steps | |
| - Create a `tests` directory and try to run unit tests on the developed class. | |
| ## 05/06/2024 | |
| ### Progress | |
| - Corrected the Household error. | |
| - Progress in understanding package development. | |
| - Created a test vignette. | |
| ### Issues Encountered | |
| - Having problems when trying to build the package and load_all(*). | |
| - Still need to understand how the build works, especially the import and export. | |
| ## 06/06/2024 | |
| - **Meeting with Mentors:** Discussed parameters needed for calculating the probability of success, focusing on conservative approaches to capital maintenance and inflation considerations. | |
| - Defined account attributes linked to the Person and Household classes. | |
| - Identified the need to simulate returns for various types of investments and implement a safe withdrawal rate of ~3%. | |
| ### Bullet Points | |
| 1. **Account Attributes**: | |
| - Linked to specific persons | |
| - Shared with Person and Household classes | |
| 2. **Investment Types**: | |
| - Bonds | |
| - Shares | |
| - Cash | |
| - Other investments (to be defined) | |
| - Default return values (modifiable) | |
| 3. **Withdrawal Strategy**: | |
| - Safe withdrawal rate: ~3% | |
| - Conservative approach to maintain capital | |
| - Consider market volatility | |
| 4. **Inflation**: | |
| - Initial assumption: constant at Fed's target rate | |
| 5. **Tax Brackets**: | |
| - Progressive structure | |
| - Different rules for various investment accounts | |
| - Requires detailed research and attention | |
| ## 07/06/2024 | |
| - **Exported Methods in NAMESPACE:** | |
| - Used `roxygen2` to export various methods into the NAMESPACE file. This ensures that the functions and methods I created are properly documented and made available for use when the package is loaded. This step is crucial for the correct functioning of the package as it specifies which functions are to be exported and available for users. | |
| ## 08/06/2024 | |
| - **Tested and Built the Package:** | |
| - Conducted testing of the package to ensure all components work as expected. This involved running existing tests and making sure that all features are functioning correctly. | |
| - Updated the DESCRIPTION file automatically. This file contains metadata about the package such as the title, version, authors, and dependencies. Keeping it updated ensures that all package information is current and accurate. | |
| - **Learned and Built Vignette:** | |
| - Created a vignette as both an example and a test. Vignettes are long-form documentation that provide users with comprehensive examples and explanations of the package's functionality. Although I decided not to push it yet, creating it helped me understand how to work with it. | |
| # Retirement Analytics R Package - Commit Comparison Overview (June 2024) | |
| ### [View the Commit Comparison](https://github.com/braverock/RetirementAnalytics/compare/d9f8ae7b94dd9d59ec77b8a29289957baadd7d81...55ade63dc2ccbf26b20a5cfb6a321696373260c6) | |
| ## 09/06/2024 | |
| - **Uploaded Unit Tests for Household and Person:** | |
| - Developed and uploaded unit tests specifically for the Household and Person classes. These tests are designed to verify that individual units of code (i.e., functions and methods) work as intended. | |
| - Ran the tests and confirmed that they all passed, indicating that the code for these components is functioning correctly. | |
| - **NAMESPACE File Push Consideration:** | |
| - Encountered a doubt regarding whether to push the NAMESPACE file. Since this file is automatically generated by `roxygen2` with the `document()` function, it raises the question of whether it should be included in version control throughout the development process or only at the end. | |
| - I had forgotten to push the various updates to the developer log on the previous days :') | |
| ## 10/06/2024 | |
| ### Overview | |
| I began testing the implementation of the account attribute and associated methods within the household class of the `RetirementAnalytics` package. This involved adding functionality to handle accounts linked to specific persons and ensuring that these updates were correctly reflected in the summary outputs. | |
| ### Issues Encountered | |
| 1. **Summary Display Issues:** | |
| - While testing, I encountered issues with the summary function. Specifically, the summary was not displaying the account balances that were added and linked to specific persons within the household. This required debugging to ensure that the account information was correctly integrated and displayed within the person and household summaries. | |
| 2. **Testing New Functionalists:** | |
| - I faced a doubt regarding the best approach to test additional functionalists within a class. The primary question was whether I should copy all the existing code into a sandbox environment and then add the new functionalists for testing, or if it was sufficient to create and test the new functionalists in a separate file without duplicating all the existing code. | |
| 3. **Library Loading Issues:** | |
| - Another problem occurred when I attempted to load the `RetirementAnalytics` package using `library(RetirementAnalytics)`. Despite the package passing all checks and being loadable through `devtools`, the standard library call resulted in an error. This discrepancy suggested there might be an issue with the package installation or namespace configuration that needed further investigation. | |
| ### Steps Taken to Resolve Issues | |
| - **Fixing Summary Display:** | |
| - I carefully reviewed the summary functions to ensure that the account balances were correctly integrated. This involved modifying the `summary.Person` and `summary.Household` functions to include calls to the `summary.Accounts` function, ensuring that all relevant information was displayed. (still not fixed) | |
| ## 12/06/2024 | |
| - **Meeting:** We started to plan the draft of the `Scenario` class. We modified the constructor, using structure and making it inherit from the list. In addition, we decided to start with a simple scenario using multivariate bootstrap with a simple portfolio with automatic rebalancing. The `Account` should be a class of its own, with a flag indicating if it is taxable, non-taxable, or deferred taxable. | |
| ## 13/06/2024 | |
| - Refactored the pre-existing `Person` class. Added unit tests to ensure the `Person` class functions correctly after the modifications. | |
| - Began outlining the `Account` class, focusing on its attributes and methods related to tax status. | |
| - For this class, I had to use uppercase due to a conflict with another package class definition. | |
| # Retirement Analytics R Package - Commit Comparison Overview (June - July 2024) | |
| ### [View the Commit Comparison](https://github.com/braverock/RetirementAnalytics/compare/85c8ffe48cb16f879604eb37ed24386cf7d277bd...18350758d28a1c8c280b436d038cfb2ae8d8e392) | |
| ## 14/06/2024 | |
| - Started the initial implementation of the `Account` class with attributes for different tax statuses (taxable, non-taxable, deferred taxable). Added preliminary methods to handle account-specific operations. Modified unit tests to include the `Account` class and verified its basic functionality. | |
| ## 15/06/2024 | |
| - Enhanced the `Person` class to better integrate with the new `Account` class. Refined the initial structure and methods of the `Account` class for improved performance. Conducted preliminary tests to validate the operations of both classes. | |
| ## 17/06/2024 | |
| - Continued development of the `Account` class, adding more detailed attributes and methods. Conducted a code review and performed initial testing to ensure robustness and accuracy. Began modifications to the `Household` class for integration with the `Account` and `Person` classes. Prepared for the next phase of development. | |
| ## 18/06/2024 | |
| - Started learning about the R environment, focusing on how it can be leveraged for scenario analysis, specifically in terms of evaluating returns on various asset classes. The objective is to streamline the process of calculating returns by focusing on the values stored in the environment, minimizing repetitive calculations, and optimizing efficiency. | |
| ## 19/06/2024 | |
| - Pushed the constructor of the `Account` class to the sandbox. I have some doubts about how the various assets should be stored there. I'm considering different approaches, such as a list of lists, and exploring packages to simulate assets and returns, making them compatible with the `Account` class. | |
| ## 21/06/2024 | |
| ### Updates to Account Class | |
| - Pushed updates to the `Account` class, adding functionality to store a `portfolio` object for simulations and analysis. Considering using the `portfolio.spec` function from the `PortfolioAnalytics` package for rebalancing and managing portfolio operations. | |
| - Still working on understanding how the environment for returns should be configured and how to set up bootstrapping for scenario analysis. | |
| ## 24/06/2024 | |
| ### Study and Research on Environment Setup | |
| - Spent time understanding how to configure the environment for portfolio returns. Reviewed the `PortfolioAnalytics` package documentation and vignettes, focusing on: | |
| - Inputting historical return data. | |
| - Specifying constraints and objectives in the portfolio. | |
| - Simulating returns using bootstrapping and other statistical methods. | |
| ## 25/06/2024 | |
| ### Sandbox Implementation for Account Class | |
| - Created a method `add_portfolio` to include a `portfolio` object. | |
| - Implemented basic retrieval of the `portfolio` object for further analysis and simulation. | |
| ## 26/06/2024 | |
| ### Environment and Bootstrapping for Scenario Analysis | |
| - Deepened understanding of bootstrapping techniques for scenario analysis: | |
| - Studied various bootstrapping methods to generate synthetic return series. | |
| - Tested different scenarios to evaluate the robustness of the portfolio under simulated market conditions. | |
| ## 27/06/2024 | |
| ### Improvements to Account Class | |
| - Made updates to the `Account` class: | |
| - Added functionality to specify bootstrapping parameters. | |
| - Created a method to run and return basic results of the scenario analysis. | |
| ## 28/06/2024 | |
| ### Paper Summary | |
| - Read "Beyond Markowitz: A Comprehensive Wealth Allocation Framework for Individual Investors," shared on the Slack channel. The paper introduces a wealth allocation framework that builds on Modern Portfolio Theory (MPT) by incorporating personal and aspirational risk factors, in addition to market risk, to better suit individual investors. | |
| ## 01/07/2024 | |
| ### Overview | |
| - Managed portfolio objects within an environment and implemented a method to estimate portfolio returns using a multivariate bootstrap approach. | |
| ### Setting Up Portfolio Environment | |
| - Created `portfolio_env` to manage portfolio objects efficiently. | |
| ### Functions for Managing Portfolio Objects | |
| - Implemented functions such as `add_existing_portfolio_to_env`, `add_return_to_env_portfolio`, `get_env_portfolio_returns`, and `calculate_env_portfolio_total_return` for handling portfolios within `portfolio_env`. | |
| ### Estimating Portfolio Returns Using Multivariate Bootstrap | |
| - Implemented `estimate_portfolio_return` function to estimate portfolio returns using a multivariate bootstrap method, including rebalancing and withdrawal options. | |
| ## 02/07/2024 | |
| - Refined multivariate bootstrapping simulation and returns. | |
| - Discussed code base review and guidelines for mid-project evaluation with mentors. | |
| ## 03/07/2024 | |
| - Added dot notation to functions for customizable simulations. | |
| - Integrated `tbootstrap` for time-series data bootstrapping with replacement to create diverse scenarios. | |
| - Studied the `boot` package documentation. | |
| ## 04/07/2024 | |
| - Solved a problem with `tbootstrap`, ensuring block size reflects empirical autocorrelation of portfolio returns. This helps maintain a stationary time-series. | |
| ## 05/07/2024 | |
| - Continued refining `tbootstrap` function, exploring different block sizes for long-term planning. | |
| - Ensured simulations are accurate based on varying time horizons. | |
| ## 08/07/2024 | |
| - Implemented simulations using `tbootstrap` with real-world data. Discussed data sources and project direction with mentors. | |
| ## 09/07/2024 | |
| - Established a pipeline for fetching and processing real-world data. Validated data before using it in simulations. | |
| ## 10/07/2024 | |
| - Ran initial tests with real-world data, resolving bugs related to data formatting and compatibility with `tbootstrap`. | |
| ## 12/07/2024 | |
| - Passed midterm evaluation! Continued discussions with mentors for future enhancements, focusing on data integration and user customization options. | |
| # Retirement Analytics R Package - Commit Comparison Overview (July - August 2024) | |
| ### [View the Commit Comparison](https://github.com/braverock/RetirementAnalytics/compare/b895f6f1817cfade89aad68ce7a169f438d935d5...bdaade02dc283590816c21078e28874d214d95e6) | |
| ## 26/07/2024 | |
| - Integrated external data sources like Quandl and Tiingo into the R package. | |
| - Set up secure handling of API credentials and fetching historical financial data. | |
| - Implemented rebalancing functionality using `Return.portfolio` from the PerformanceAnalytics package for more accurate and dynamic portfolio management. | |
| - Progress slowed due to preparations for my master thesis defense but will continue enhancing the package's features and usability in the coming weeks. | |
| ## 06/08/2024 - 12/08/2024 | |
| - Holiday | |
| ## Goals and Objectives | |
| - Focused on establishing the foundational structure for representing individuals and households within the simulation framework. | |
| - Next objective: Refine and enhance the simulation capabilities, introducing more customizable portfolio options beyond the default 60-40 split. | |
| - Plan to test enhancements using unit tests to maintain the integrity and reliability of the simulation. | |
| - Developing a basic tax system for account simulations, including three primary account classes: non-taxable, deferred, and taxable accounts. | |
| - Aiming to include a flat tax calculation mechanism for taxable accounts, possibly customizable by the user. | |
| - If time permits, plan to develop a visualization tool for simulation results, possibly using a probability graph with an Area Under the Curve (AUC) representation. | |
| ## 14/08/2024 | |
| - Covered more aspects of account simulation with unit tests. | |
| - Some tests failed, likely due to issues with the tests themselves rather than the simulation. Plan to fix this next, particularly by investigating the return environment and bootstrap handling. | |
| ## 15/08/2024 | |
| - Continued refining the simulation's core features, focusing on edge cases identified during testing. | |
| - Started fixing a bug causing inconsistencies in simulation results with specific data configurations. | |
| - Productive debugging session; optimistic about the improvements. | |
| ## 16/08/2024 | |
| - Fixed the bug identified previously, improving simulation accuracy. | |
| - Shifted focus back to implementing the taxation system. | |
| - Drafted initial code for handling different tax scenarios and began testing their integration with the existing account simulation structure. | |
| ## 17/08/2024 | |
| - Made progress on the taxation system, implementing the basic framework for taxable and non-taxable accounts. | |
| - Tested different scenarios to ensure tax calculations are accurate. | |
| - Refined some portfolio rebalancing functionalities to ensure they work with the new tax system. | |
| ## 18/08/2024 | |
| - Focused on testing and refining the taxation framework. | |
| - Continued improving the integration of the tax system with portfolio management features. | |
| ## 19/08/2024 | |
| - Resolved remaining issues with the taxation system, particularly in deferred and taxable accounts. | |
| ## 21/08/2024 | |
| - Conducted a comprehensive review of recent package additions, including running extensive tests to ensure all new features, especially the tax system and portfolio customization options, are functional and bug-free. | |
| - Continued refining user documentation to clearly explain the new functionalities. | |
| - The package is now more stable and feature-complete, ready for further enhancements. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment