# Long-Short Momentum Portfolio Construction with 3-month lookback window
# This script creates a portfolio that:
# - Goes LONG in stocks with positive returns over the last 3 months
# - Goes SHORT in stocks with negative returns over the last 3 months
# - Rebalanced monthly with equal weighting

# ---- PACKAGE INSTALLATION AND LOADING ----

# Install and load required packages
if (!require("pacman")) install.packages("pacman")
## Cargando paquete requerido: pacman
pacman::p_load(
  tidyverse,    # Data manipulation and visualization
  quantmod,     # Financial data retrieval and analysis
  PerformanceAnalytics, # Performance and risk analysis
  zoo,          # Time series analysis
  roll,         # Rolling window calculations
  xts,          # Extensible time series
  lubridate,    # Date handling
  readxl,       # Excel file reading
  knitr,        # For tables
  grid,         # For graphics
  gridExtra     # For arranging multiple plots
)

# ---- FILE PATH CONFIGURATION ----

# Create file paths using file.path() to handle spaces and special characters better
base_dir <- file.path("C:", "Users", "lcyep", "OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey", 
                      "Tec", "Semestre 6", "Risk", "R, project")

# Use forward slashes instead of backslashes
stock_file_path <- file.path(base_dir, "data.xlsx") 
market_file_path <- file.path(base_dir, "data2.xlsx")

# Print the paths for verification
cat("Stock file path:", stock_file_path, "\n")
## Stock file path: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/data.xlsx
cat("Market file path:", market_file_path, "\n")
## Market file path: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/data2.xlsx
# Check if files exist
if (!file.exists(stock_file_path)) {
  stop("Stock file not found. Please check the path and filename.")
}
if (!file.exists(market_file_path)) {
  stop("Market file not found. Please check the path and filename.")
}

# ---- DATA IMPORT FUNCTION ----

# Function to import Excel data
import_excel_data <- function(stock_file_path, market_file_path) {
  tryCatch({
    # Read stock price data
    cat("Reading stock data from:", stock_file_path, "\n")
    stock_data <- read_excel(stock_file_path)
    
    # Read benchmark and risk-free rate data
    cat("Reading market data from:", market_file_path, "\n")
    market_data <- read_excel(market_file_path)
    
    # Convert the first column to dates
    dates <- as.Date(stock_data[[1]])
    
    # Create xts objects for stock prices
    stock_prices <- as.matrix(stock_data[, -1])  # Remove the date column
    rownames(stock_prices) <- NULL
    stock_prices_xts <- xts(stock_prices, order.by = dates)
    colnames(stock_prices_xts) <- colnames(stock_data)[-1]  # Preserve stock names
    
    # Extract S&P 500 price and T-bill data
    sp500_prices <- as.numeric(market_data[[2]])  # S&P 500 Price Index
    tbill_rates <- as.numeric(market_data[[4]]) / 100 / 12  # Convert annual rate to monthly
    
    market_dates <- as.Date(market_data[[1]])
    sp500_prices_xts <- xts(sp500_prices, order.by = market_dates)
    tbill_rates_xts <- xts(tbill_rates, order.by = market_dates)
    
    # Calculate returns for stocks
    stock_returns_xts <- ROC(stock_prices_xts, type = "discrete", n = 1)
    stock_returns_xts <- stock_returns_xts[-1, ]  # Remove first NA row
    
    # Calculate returns for S&P 500
    sp500_returns_xts <- ROC(sp500_prices_xts, type = "discrete", n = 1)
    sp500_returns_xts <- sp500_returns_xts[-1, ]  # Remove first NA row
    
    # Remove first value from tbill rates to align with returns
    tbill_rates_xts <- tbill_rates_xts[-1, ]
    
    return(list(
      stock_returns = stock_returns_xts,
      sp500_returns = sp500_returns_xts,
      risk_free_rate = tbill_rates_xts
    ))
  }, error = function(e) {
    stop(paste("Error reading files:", e$message))
  })
}

# ---- MOMENTUM ANALYSIS FUNCTIONS ----

# Function to calculate N-month cumulative returns
calculate_momentum <- function(returns, lookback_period = 3) {
  # Calculate cumulative returns over the lookback period
  # For 3-month lookback, we calculate (1+r1)*(1+r2)*(1+r3) - 1
  momentum <- rep(NA, length(returns))
  
  if (length(returns) >= lookback_period) {
    # Calculate cumulative returns using rolling product
    for (i in lookback_period:length(returns)) {
      momentum[i] <- prod(1 + returns[(i - lookback_period + 1):i]) - 1
    }
  }
  
  return(momentum)
}

# Function to construct long-short momentum portfolio based on trailing returns
construct_long_short_momentum_portfolio <- function(asset_returns, lookback_period = 3, 
                                                    start_after_months = 36) {
  
  dates <- index(asset_returns)
  n_stocks <- ncol(asset_returns)
  n_periods <- length(dates) - start_after_months
  
  portfolio_returns <- numeric(n_periods)
  selected_long_assets <- list()
  selected_short_assets <- list()
  momentum_scores <- list()
  
  cat("Starting long-short momentum portfolio construction with", n_periods, "rebalancing periods\n")
  
  for (i in 1:n_periods) {
    # Define the current position in the time series
    current_idx <- i + start_after_months - 1
    
    # Calculate momentum for each asset using data up to the current month
    asset_momentums <- numeric(n_stocks)
    
    for (j in 1:n_stocks) {
      # Get returns for the current asset
      asset_data <- asset_returns[1:current_idx, j]
      
      # Calculate momentum (trailing return over lookback period)
      if (current_idx >= lookback_period) {
        # Get the last lookback_period months of returns
        recent_returns <- asset_data[(current_idx - lookback_period + 1):current_idx]
        
        # Calculate cumulative return over the lookback period
        if (all(!is.na(recent_returns))) {
          asset_momentums[j] <- prod(1 + recent_returns) - 1
        } else {
          asset_momentums[j] <- NA
        }
      } else {
        asset_momentums[j] <- NA
      }
    }
    
    # Create data frame of stocks and their momentum scores
    asset_names <- colnames(asset_returns)
    momentum_df <- data.frame(
      asset = asset_names,
      momentum = asset_momentums
    )
    
    # Store momentum scores for this period
    momentum_scores[[i]] <- momentum_df
    
    # Select assets with positive momentum for LONG positions
    selected_long_df <- momentum_df %>%
      filter(!is.na(momentum) & momentum > 0) %>%
      arrange(desc(momentum))
    
    # Select assets with negative momentum for SHORT positions
    selected_short_df <- momentum_df %>%
      filter(!is.na(momentum) & momentum < 0) %>%
      arrange(momentum)  # Arrange in ascending order (most negative first)
    
    selected_long_assets_names <- selected_long_df$asset
    selected_short_assets_names <- selected_short_df$asset
    
    selected_long_assets[[i]] <- selected_long_assets_names
    selected_short_assets[[i]] <- selected_short_assets_names
    
    # Find indices of selected stocks
    selected_long_idx <- match(selected_long_assets_names, asset_names)
    selected_short_idx <- match(selected_short_assets_names, asset_names)
    
    # Calculate portfolio return for the next month
    next_month_return <- 0
    
    # Determine the capital allocation (50% to long, 50% to short)
    long_allocation <- 0.5
    short_allocation <- 0.5
    
    # Calculate long component return (if any long positions)
    long_return <- 0
    if (length(selected_long_idx) > 0) {
      # Equal weighting for all selected long stocks
      long_weights <- rep(1/length(selected_long_idx), length(selected_long_idx))
      
      # Get the returns for the next month
      long_next_month_returns <- as.numeric(asset_returns[current_idx + 1, selected_long_idx])
      
      # Calculate weighted return for long positions
      long_return <- sum(long_weights * long_next_month_returns, na.rm = TRUE)
    }
    
    # Calculate short component return (if any short positions)
    short_return <- 0
    if (length(selected_short_idx) > 0) {
      # Equal weighting for all selected short stocks
      short_weights <- rep(1/length(selected_short_idx), length(selected_short_idx))
      
      # Get the returns for the next month (returns are negative for successful shorts)
      short_next_month_returns <- as.numeric(asset_returns[current_idx + 1, selected_short_idx])
      
      # Calculate weighted return for short positions (negative of the asset returns)
      short_return <- -sum(short_weights * short_next_month_returns, na.rm = TRUE)
    }
    
    # Combine long and short returns with proper allocation
    if (length(selected_long_idx) > 0 && length(selected_short_idx) > 0) {
      # Both long and short positions
      next_month_return <- (long_allocation * long_return) + (short_allocation * short_return)
    } else if (length(selected_long_idx) > 0) {
      # Only long positions
      next_month_return <- long_return
    } else if (length(selected_short_idx) > 0) {
      # Only short positions
      next_month_return <- short_return
    } else {
      # If no assets meet criteria, return 0 (cash position)
      next_month_return <- 0
    }
    
    portfolio_returns[i] <- next_month_return
    
    # Print progress
    if (i %% 5 == 0 || i == 1 || i == n_periods) {
      cat("Processing period", i, "of", n_periods, 
          "- Date:", as.character(dates[current_idx + 1]), "\n")
      
      cat("LONG positions count:", length(selected_long_assets_names), "\n")
      if (length(selected_long_assets_names) > 0) {
        cat("Top 5 long momentum assets:", paste(head(selected_long_assets_names, 5), collapse=", "), 
            ifelse(length(selected_long_assets_names) > 5, "...", ""), "\n")
        cat("Top 5 long momentum scores:", paste(sprintf("%.2f%%", head(selected_long_df$momentum, 5) * 100), collapse=", "),
            ifelse(length(selected_long_assets_names) > 5, "...", ""), "\n")
      } else {
        cat("No assets with positive momentum found this period\n")
      }
      
      cat("SHORT positions count:", length(selected_short_assets_names), "\n")
      if (length(selected_short_assets_names) > 0) {
        cat("Top 5 short momentum assets:", paste(head(selected_short_assets_names, 5), collapse=", "), 
            ifelse(length(selected_short_assets_names) > 5, "...", ""), "\n")
        cat("Top 5 short momentum scores:", paste(sprintf("%.2f%%", head(selected_short_df$momentum, 5) * 100), collapse=", "),
            ifelse(length(selected_short_assets_names) > 5, "...", ""), "\n")
      } else {
        cat("No assets with negative momentum found this period\n")
      }
    }
  }
  
  # Create a time series of portfolio returns
  portfolio_returns_ts <- xts(portfolio_returns, order.by = dates[(start_after_months + 1):length(dates)])
  
  # Save all momentum scores to a file for analysis
  all_momentum_df <- do.call(rbind, lapply(1:length(momentum_scores), function(i) {
    df <- momentum_scores[[i]]
    df$period <- i
    df$date <- as.character(dates[i + start_after_months])
    return(df)
  }))
  
  output_file <- file.path(base_dir, "long_short_momentum_scores.csv")
  write.csv(all_momentum_df, output_file, row.names = FALSE)
  cat("Saved all momentum scores to:", output_file, "\n")
  
  return(list(
    returns = portfolio_returns_ts,
    selected_long_assets = selected_long_assets,
    selected_short_assets = selected_short_assets,
    all_momentum = all_momentum_df
  ))
}

# ---- PERFORMANCE ANALYSIS FUNCTION ----

# Function to analyze portfolio performance
analyze_long_short_momentum_portfolio <- function(portfolio_result, risk_free_rate, sp500_returns, start_after_months = 36) {
  portfolio_returns <- portfolio_result$returns
  
  # Calculate cumulative returns
  cumulative_returns <- cumprod(1 + portfolio_returns) - 1
  
  # Plot results
  plot(cumulative_returns, main = "Cumulative Long-Short Momentum Portfolio Returns", 
       ylab = "Return", xlab = "Date")
  
  # Calculate performance metrics
  portfolio_avg_return <- mean(portfolio_returns) * 12 * 100  # Annualized and as percentage
  portfolio_sd <- sd(portfolio_returns) * sqrt(12) * 100      # Annualized and as percentage
  portfolio_sharpe <- mean(portfolio_returns - risk_free_rate[(start_after_months + 1):length(risk_free_rate)]) / 
                     sd(portfolio_returns)
  
  # Calculate benchmark metrics for the same period
  benchmark_returns <- sp500_returns[(start_after_months + 1):length(sp500_returns)]
  benchmark_avg_return <- mean(benchmark_returns) * 12 * 100  # Annualized and as percentage
  benchmark_sd <- sd(benchmark_returns) * sqrt(12) * 100      # Annualized and as percentage
  benchmark_sharpe <- mean(benchmark_returns - risk_free_rate[(start_after_months + 1):length(risk_free_rate)]) / 
                     sd(benchmark_returns)
  
  # Calculate Upside-Potential Ratio for both
  target_return <- mean(risk_free_rate[(start_after_months + 1):length(risk_free_rate)])
  portfolio_upside <- mean(pmax(portfolio_returns - target_return, 0)) / 
                    sqrt(mean((portfolio_returns - mean(portfolio_returns))^2))
  benchmark_upside <- mean(pmax(benchmark_returns - target_return, 0)) / 
                    sqrt(mean((benchmark_returns - mean(benchmark_returns))^2))
  
  # Create performance comparison table
  performance_table <- data.frame(
    Metric = c("Average Return", "Standard Deviation", "Sharpe Ratio", "Upside-Potential Ratio"),
    `Long-Short Portfolio` = c(sprintf("%.2f%%", portfolio_avg_return), 
                 sprintf("%.2f%%", portfolio_sd),
                 sprintf("%.3f", portfolio_sharpe),
                 sprintf("%.3f", portfolio_upside)),
    `S&P 500 Benchmark` = c(sprintf("%.2f%%", benchmark_avg_return),
                 sprintf("%.2f%%", benchmark_sd),
                 sprintf("%.3f", benchmark_sharpe),
                 sprintf("%.3f", benchmark_upside))
  )
  
  cat("\n----- Long-Short Momentum Portfolio Performance Metrics -----\n")
  print(performance_table)
  
  # Save the performance table
  output_file <- file.path(base_dir, "long_short_momentum_performance_comparison.csv")
  write.csv(performance_table, output_file, row.names = FALSE)
  cat("Saved performance comparison to:", output_file, "\n")
  
  # Create a data frame of portfolio composition over time
  composition <- data.frame(
    Date = index(portfolio_returns),
    stringsAsFactors = FALSE
  )
  
  composition$Long_Assets <- sapply(portfolio_result$selected_long_assets, function(assets) {
    paste(assets, collapse = ", ")
  })
  
  composition$Short_Assets <- sapply(portfolio_result$selected_short_assets, function(assets) {
    paste(assets, collapse = ", ")
  })
  
  composition$Long_Asset_Count <- sapply(portfolio_result$selected_long_assets, length)
  composition$Short_Asset_Count <- sapply(portfolio_result$selected_short_assets, length)
  
  # Save portfolio composition to CSV
  output_file <- file.path(base_dir, "long_short_momentum_portfolio_composition.csv")
  write.csv(composition, output_file, row.names = FALSE)
  cat("Saved portfolio composition to:", output_file, "\n")
  
  # Save portfolio returns to CSV
  returns_df <- data.frame(
    Date = index(portfolio_returns),
    Return = as.numeric(portfolio_returns)
  )
  output_file <- file.path(base_dir, "long_short_momentum_portfolio_returns.csv")
  write.csv(returns_df, output_file, row.names = FALSE)
  cat("Saved portfolio returns to:", output_file, "\n")
  
  # Count frequency of asset selection for long positions
  all_selected_long <- unlist(portfolio_result$selected_long_assets)
  long_selection_freq <- sort(table(all_selected_long), decreasing = TRUE)
  
  # Count frequency of asset selection for short positions
  all_selected_short <- unlist(portfolio_result$selected_short_assets)
  short_selection_freq <- sort(table(all_selected_short), decreasing = TRUE)
  
  cat("\n----- Most Frequently Selected Long Assets -----\n")
  print(head(long_selection_freq, 10))
  
  cat("\n----- Most Frequently Selected Short Assets -----\n")
  print(head(short_selection_freq, 10))
  
  # Save selection frequency to CSV for long positions
  long_selection_freq_df <- data.frame(
    Asset = names(long_selection_freq),
    Frequency = as.numeric(long_selection_freq),
    Percentage = as.numeric(long_selection_freq) / length(portfolio_result$selected_long_assets) * 100
  )
  output_file <- file.path(base_dir, "long_short_momentum_long_asset_selection_frequency.csv")
  write.csv(long_selection_freq_df, output_file, row.names = FALSE)
  cat("Saved long asset selection frequency to:", output_file, "\n")
  
  # Save selection frequency to CSV for short positions
  short_selection_freq_df <- data.frame(
    Asset = names(short_selection_freq),
    Frequency = as.numeric(short_selection_freq),
    Percentage = as.numeric(short_selection_freq) / length(portfolio_result$selected_short_assets) * 100
  )
  output_file <- file.path(base_dir, "long_short_momentum_short_asset_selection_frequency.csv")
  write.csv(short_selection_freq_df, output_file, row.names = FALSE)
  cat("Saved short asset selection frequency to:", output_file, "\n")
  
  return(list(
    cumulative_returns = cumulative_returns,
    performance_table = performance_table,
    composition = composition,
    long_selection_frequency = long_selection_freq_df,
    short_selection_frequency = short_selection_freq_df
  ))
}

# ---- MAIN EXECUTION ----

# Run the complete analysis
run_long_short_momentum_analysis <- function() {
  # Start timer
  start_time <- Sys.time()
  cat("Starting long-short momentum portfolio analysis at", as.character(start_time), "\n")
  
  # Import data
  cat("Importing data from Excel files...\n")
  data <- import_excel_data(stock_file_path, market_file_path)
  
  # Basic data exploration
  cat("\nData summary:\n")
  cat("- Number of stocks:", ncol(data$stock_returns), "\n")
  cat("- Date range:", as.character(first(index(data$stock_returns))), 
      "to", as.character(last(index(data$stock_returns))), "\n")
  cat("- Number of observations:", nrow(data$stock_returns), "\n\n")
  
  # Run the portfolio construction
  cat("Constructing long-short momentum portfolio...\n")
  portfolio_result <- construct_long_short_momentum_portfolio(
    asset_returns = data$stock_returns,
    lookback_period = 3,     # 3 months lookback for momentum
    start_after_months = 36  # Start after 36 months of data
  )
  
  # Analyze performance
  cat("\nAnalyzing long-short momentum portfolio performance...\n")
  analysis <- analyze_long_short_momentum_portfolio(
    portfolio_result = portfolio_result, 
    risk_free_rate = data$risk_free_rate,
    sp500_returns = data$sp500_returns,
    start_after_months = 36
  )
  
  # End timer
  end_time <- Sys.time()
  cat("\nAnalysis completed in", round(difftime(end_time, start_time, units = "mins"), 2), "minutes\n")
  
  # Return results
  return(list(
    portfolio = portfolio_result,
    analysis = analysis,
    data = data
  ))
}

# Execute the analysis and store the results
long_short_momentum_result <- run_long_short_momentum_analysis()
## Starting long-short momentum portfolio analysis at 2025-05-03 15:36:45.884326 
## Importing data from Excel files...
## Reading stock data from: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/data.xlsx
## New names:
## • `` -> `...1`
## Reading market data from: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/data2.xlsx
## New names:
## • `` -> `...1`
## 
## Data summary:
## - Number of stocks: 50 
## - Date range: 2005-01-31 to 2024-02-29 
## - Number of observations: 230 
## 
## Constructing long-short momentum portfolio...
## Starting long-short momentum portfolio construction with 194 rebalancing periods
## Processing period 1 of 194 - Date: 2008-01-31 
## LONG positions count: 23 
## Top 5 long momentum assets: APPLE, NETFLIX, SALESFORCE, ALPHABET A, MICROSOFT ... 
## Top 5 long momentum scores: 29.07%, 28.29%, 22.16%, 21.90%, 20.84% ... 
## SHORT positions count: 27 
## Top 5 short momentum assets: CITIGROUP, COMCAST A, STARBUCKS, LOWE'S COMPANIES, CISCO SYSTEMS ... 
## Top 5 short momentum scores: -36.92%, -24.48%, -21.87%, -19.27%, -18.29% ... 
## Processing period 5 of 194 - Date: 2008-05-30 
## LONG positions count: 31 
## Top 5 long momentum assets: SALESFORCE, APPLE, NETFLIX, UNION PACIFIC, AMERICAN TOWER ... 
## Top 5 long momentum scores: 28.55%, 28.51%, 27.16%, 16.38%, 16.00% ... 
## SHORT positions count: 19 
## Top 5 short momentum assets: UNITEDHEALTH GROUP, MERCK & COMPANY, NVIDIA, BANK OF AMERICA, STARBUCKS ... 
## Top 5 short momentum scores: -35.82%, -17.48%, -16.43%, -14.97%, -14.17% ... 
## Processing period 10 of 194 - Date: 2008-10-31 
## LONG positions count: 21 
## Top 5 long momentum assets: WELLS FARGO & CO, BANK OF AMERICA, JP MORGAN CHASE & CO., AMGEN, CITIGROUP ... 
## Top 5 long momentum scores: 58.02%, 46.63%, 36.11%, 25.68%, 22.37% ... 
## SHORT positions count: 29 
## Top 5 short momentum assets: NVIDIA, APPLE, SALESFORCE, ALPHABET A, TEXAS INSTRUMENTS ... 
## Top 5 short momentum scores: -42.79%, -32.12%, -29.06%, -23.92%, -23.65% ... 
## Processing period 15 of 194 - Date: 2009-03-31 
## LONG positions count: 9 
## Top 5 long momentum assets: NETFLIX, AMAZON.COM, ALPHABET A, INTERNATIONAL BUS.MCHS., NVIDIA ... 
## Top 5 long momentum scores: 57.70%, 51.73%, 15.37%, 12.78%, 10.84% ... 
## SHORT positions count: 41 
## Top 5 short momentum assets: CITIGROUP, BANK OF AMERICA, WELLS FARGO & CO, ADOBE (NAS), JP MORGAN CHASE & CO. ... 
## Top 5 short momentum scores: -81.91%, -75.69%, -58.12%, -27.89%, -27.83% ... 
## Processing period 20 of 194 - Date: 2009-08-31 
## LONG positions count: 45 
## Top 5 long momentum assets: BANK OF AMERICA, TEXAS INSTRUMENTS, APPLE, THERMO FISHER SCIENTIFIC, AMGEN ... 
## Top 5 long momentum scores: 65.62%, 33.17%, 29.85%, 29.08%, 28.55% ... 
## SHORT positions count: 5 
## Top 5 short momentum assets: LOCKHEED MARTIN, COMCAST A, NETFLIX, HOME DEPOT, WALMART  
## Top 5 short momentum scores: -4.80%, -3.88%, -3.02%, -1.44%, -1.03%  
## Processing period 25 of 194 - Date: 2010-01-29 
## LONG positions count: 40 
## Top 5 long momentum assets: AMAZON.COM, SALESFORCE, ALPHABET A, NVIDIA, UNITEDHEALTH GROUP ... 
## Top 5 long momentum scores: 44.09%, 29.58%, 25.03%, 24.28%, 21.73% ... 
## SHORT positions count: 10 
## Top 5 short momentum assets: CITIGROUP, BANK OF AMERICA, GILEAD SCIENCES, AMGEN, JP MORGAN CHASE & CO. ... 
## Top 5 short momentum scores: -31.61%, -10.99%, -6.95%, -6.08%, -4.91% ... 
## Processing period 30 of 194 - Date: 2010-06-30 
## LONG positions count: 22 
## Top 5 long momentum assets: NETFLIX, SALESFORCE, APPLE, CITIGROUP, STARBUCKS ... 
## Top 5 long momentum scores: 68.28%, 27.34%, 25.54%, 16.47%, 13.01% ... 
## SHORT positions count: 28 
## Top 5 short momentum assets: GILEAD SCIENCES, NVIDIA, UNITEDHEALTH GROUP, PFIZER, ABBOTT LABORATORIES ... 
## Top 5 short momentum scores: -24.55%, -18.89%, -14.15%, -13.22%, -12.38% ... 
## Processing period 35 of 194 - Date: 2010-11-30 
## LONG positions count: 41 
## Top 5 long momentum assets: NETFLIX, AMAZON.COM, NVIDIA, ALPHABET A, ORACLE ... 
## Top 5 long momentum scores: 69.25%, 40.16%, 30.80%, 26.58%, 24.28% ... 
## SHORT positions count: 9 
## Top 5 short momentum assets: BANK OF AMERICA, JP MORGAN CHASE & CO., WELLS FARGO & CO, LOCKHEED MARTIN, MEDTRONIC ... 
## Top 5 short momentum scores: -18.45%, -6.58%, -6.02%, -5.14%, -4.71% ... 
## Processing period 40 of 194 - Date: 2011-04-29 
## LONG positions count: 35 
## Top 5 long momentum assets: NETFLIX, UNITEDHEALTH GROUP, NVIDIA, CHEVRON, GILEAD SCIENCES ... 
## Top 5 long momentum scores: 35.33%, 25.17%, 19.87%, 17.80%, 17.19% ... 
## SHORT positions count: 15 
## Top 5 short momentum assets: CISCO SYSTEMS, NIKE 'B', MICROSOFT, MERCK & COMPANY, CITIGROUP ... 
## Top 5 short momentum scores: -15.22%, -11.38%, -9.03%, -8.41%, -6.55% ... 
## Processing period 45 of 194 - Date: 2011-09-30 
## LONG positions count: 11 
## Top 5 long momentum assets: MCDONALDS, APPLE, AMAZON.COM, MICROSOFT, COCA COLA ... 
## Top 5 long momentum scores: 10.88%, 10.64%, 9.43%, 6.36%, 5.45% ... 
## SHORT positions count: 39 
## Top 5 short momentum assets: NVIDIA, BANK OF AMERICA, ADOBE (NAS), TEXAS INSTRUMENTS, CITIGROUP ... 
## Top 5 short momentum scores: -33.58%, -30.47%, -27.12%, -25.75%, -24.54% ... 
## Processing period 50 of 194 - Date: 2012-02-29 
## LONG positions count: 39 
## Top 5 long momentum assets: NETFLIX, LOWE'S COMPANIES, HOME DEPOT, AMGEN, GILEAD SCIENCES ... 
## Top 5 long momentum scores: 46.44%, 27.64%, 23.99%, 18.61%, 17.28% ... 
## SHORT positions count: 11 
## Top 5 short momentum assets: ORACLE, SALESFORCE, AMAZON.COM, ACCENTURE CLASS A, CITIGROUP ... 
## Top 5 short momentum scores: -13.92%, -12.29%, -8.93%, -4.85%, -2.75% ... 
## Processing period 55 of 194 - Date: 2012-07-31 
## LONG positions count: 22 
## Top 5 long momentum assets: VERIZON COMMUNICATIONS, AT&T, WALMART, AMAZON.COM, NEXTERA ENERGY ... 
## Top 5 long momentum scores: 16.24%, 14.19%, 13.92%, 12.76%, 12.66% ... 
## SHORT positions count: 28 
## Top 5 short momentum assets: NETFLIX, CITIGROUP, JP MORGAN CHASE & CO., NIKE 'B', CISCO SYSTEMS ... 
## Top 5 short momentum scores: -40.47%, -25.01%, -22.29%, -19.05%, -18.82% ... 
## Processing period 60 of 194 - Date: 2012-12-31 
## LONG positions count: 36 
## Top 5 long momentum assets: NETFLIX, GILEAD SCIENCES, LOWE'S COMPANIES, BANK OF AMERICA, CITIGROUP ... 
## Top 5 long momentum scores: 36.82%, 30.01%, 26.72%, 23.40%, 16.36% ... 
## SHORT positions count: 14 
## Top 5 short momentum assets: INTEL, NVIDIA, MICROSOFT, APPLE, AT&T ... 
## Top 5 short momentum scores: -21.20%, -14.68%, -13.64%, -12.02%, -6.85% ... 
## Processing period 65 of 194 - Date: 2013-05-31 
## LONG positions count: 44 
## Top 5 long momentum assets: NETFLIX, GILEAD SCIENCES, VERIZON COMMUNICATIONS, AMGEN, MICROSOFT ... 
## Top 5 long momentum scores: 30.76%, 28.37%, 23.62%, 21.94%, 20.58% ... 
## SHORT positions count: 6 
## Top 5 short momentum assets: ORACLE, SALESFORCE, AMAZON.COM, APPLE, EXXON MOBIL ... 
## Top 5 short momentum scores: -7.69%, -4.47%, -4.40%, -2.79%, -1.09% ... 
## Processing period 70 of 194 - Date: 2013-10-31 
## LONG positions count: 33 
## Top 5 long momentum assets: NETFLIX, SALESFORCE, GILEAD SCIENCES, APPLE, LOCKHEED MARTIN ... 
## Top 5 long momentum scores: 46.48%, 35.96%, 22.63%, 20.23%, 17.60% ... 
## SHORT positions count: 17 
## Top 5 short momentum assets: VERIZON COMMUNICATIONS, COCA COLA, INTEL, ABBOTT LABORATORIES, EXXON MOBIL ... 
## Top 5 short momentum scores: -7.28%, -5.56%, -5.40%, -4.85%, -4.77% ... 
## Processing period 75 of 194 - Date: 2014-03-31 
## LONG positions count: 34 
## Top 5 long momentum assets: THERMO FISHER SCIENTIFIC, NETFLIX, ADOBE (NAS), SALESFORCE, ELI LILLY ... 
## Top 5 long momentum scores: 23.49%, 21.82%, 20.87%, 19.74%, 18.70% ... 
## SHORT positions count: 16 
## Top 5 short momentum assets: STARBUCKS, AT&T, CITIGROUP, AMAZON.COM, WALMART ... 
## Top 5 short momentum scores: -12.89%, -9.32%, -8.11%, -8.01%, -7.79% ... 
## Processing period 80 of 194 - Date: 2014-08-29 
## LONG positions count: 36 
## Top 5 long momentum assets: NETFLIX, INTEL, GILEAD SCIENCES, AMGEN, APPLE ... 
## Top 5 long momentum scores: 31.26%, 26.98%, 16.64%, 14.00%, 13.41% ... 
## SHORT positions count: 14 
## Top 5 short momentum assets: PFIZER, WALMART, MCDONALDS, PROCTER & GAMBLE, NEXTERA ENERGY ... 
## Top 5 short momentum scores: -8.25%, -7.69%, -6.73%, -6.34%, -5.97% ... 
## Processing period 85 of 194 - Date: 2015-01-30 
## LONG positions count: 37 
## Top 5 long momentum assets: LOWE'S COMPANIES, ORACLE, UNITEDHEALTH GROUP, MEDTRONIC, BRISTOL MYERS SQUIBB ... 
## Top 5 long momentum scores: 30.01%, 17.48%, 17.21%, 16.55%, 15.34% ... 
## SHORT positions count: 13 
## Top 5 short momentum assets: NETFLIX, INTERNATIONAL BUS.MCHS., GILEAD SCIENCES, ALPHABET A, VERIZON COMMUNICATIONS ... 
## Top 5 short momentum scores: -24.29%, -15.48%, -11.45%, -9.81%, -6.42% ... 
## Processing period 90 of 194 - Date: 2015-06-30 
## LONG positions count: 23 
## Top 5 long momentum assets: NETFLIX, AMAZON.COM, ELI LILLY, STARBUCKS, GILEAD SCIENCES ... 
## Top 5 long momentum scores: 31.41%, 12.91%, 12.44%, 11.16%, 8.44% ... 
## SHORT positions count: 27 
## Top 5 short momentum assets: UNION PACIFIC, WALMART, PROCTER & GAMBLE, AMERICAN TOWER, LOCKHEED MARTIN ... 
## Top 5 short momentum scores: -16.09%, -11.51%, -7.92%, -6.41%, -5.92% ... 
## Processing period 95 of 194 - Date: 2015-11-30 
## LONG positions count: 27 
## Top 5 long momentum assets: NVIDIA, INTEL, AMAZON.COM, NIKE 'B', TEXAS INSTRUMENTS ... 
## Top 5 long momentum scores: 42.21%, 16.96%, 16.74%, 13.72%, 13.49% ... 
## SHORT positions count: 23 
## Top 5 short momentum assets: WALMART, INTERNATIONAL BUS.MCHS., ABBOTT LABORATORIES, AMGEN, CITIGROUP ... 
## Top 5 short momentum scores: -20.48%, -13.53%, -11.62%, -10.43%, -9.05% ... 
## Processing period 100 of 194 - Date: 2016-04-29 
## LONG positions count: 26 
## Top 5 long momentum assets: VERIZON COMMUNICATIONS, NEXTERA ENERGY, AT&T, ORACLE, WALMART ... 
## Top 5 long momentum scores: 17.01%, 13.91%, 13.83%, 11.99%, 11.73% ... 
## SHORT positions count: 24 
## Top 5 short momentum assets: BANK OF AMERICA, CITIGROUP, ELI LILLY, AMAZON.COM, WELLS FARGO & CO ... 
## Top 5 short momentum scores: -19.67%, -19.32%, -14.54%, -12.17%, -11.04% ... 
## Processing period 105 of 194 - Date: 2016-09-30 
## LONG positions count: 39 
## Top 5 long momentum assets: NVIDIA, TEXAS INSTRUMENTS, INTEL, UNION PACIFIC, MERCK & COMPANY ... 
## Top 5 long momentum scores: 31.29%, 14.75%, 13.61%, 13.47%, 11.61% ... 
## SHORT positions count: 11 
## Top 5 short momentum assets: BRISTOL MYERS SQUIBB, GILEAD SCIENCES, MCDONALDS, SALESFORCE, NETFLIX ... 
## Top 5 short momentum scores: -19.96%, -9.97%, -5.24%, -5.12%, -4.99% ... 
## Processing period 110 of 194 - Date: 2017-02-28 
## LONG positions count: 40 
## Top 5 long momentum assets: NVIDIA, BANK OF AMERICA, WELLS FARGO & CO, JP MORGAN CHASE & CO., COMCAST A ... 
## Top 5 long momentum scores: 53.43%, 37.21%, 22.43%, 22.19%, 22.00% ... 
## SHORT positions count: 10 
## Top 5 short momentum assets: AMERICAN TOWER, MEDTRONIC, WALMART, BRISTOL MYERS SQUIBB, NEXTERA ENERGY ... 
## Top 5 short momentum scores: -11.68%, -7.32%, -4.68%, -3.44%, -3.34% ... 
## Processing period 115 of 194 - Date: 2017-07-31 
## LONG positions count: 33 
## Top 5 long momentum assets: NVIDIA, MCDONALDS, THERMO FISHER SCIENTIFIC, UNITEDHEALTH GROUP, ORACLE ... 
## Top 5 long momentum scores: 32.71%, 18.17%, 13.59%, 13.05%, 12.40% ... 
## SHORT positions count: 17 
## Top 5 short momentum assets: INTERNATIONAL BUS.MCHS., AT&T, VERIZON COMMUNICATIONS, CISCO SYSTEMS, INTEL ... 
## Top 5 short momentum scores: -11.66%, -9.19%, -8.39%, -7.40%, -6.46% ... 
## Processing period 120 of 194 - Date: 2017-12-29 
## LONG positions count: 42 
## Top 5 long momentum assets: INTEL, WALMART, UNION PACIFIC, AMAZON.COM, HOME DEPOT ... 
## Top 5 long momentum scores: 27.86%, 24.54%, 20.13%, 20.00%, 19.98% ... 
## SHORT positions count: 8 
## Top 5 short momentum assets: MERCK & COMPANY, GILEAD SCIENCES, COMCAST A, AT&T, AMERICAN TOWER ... 
## Top 5 short momentum scores: -13.45%, -10.67%, -7.56%, -2.88%, -2.78% ... 
## Processing period 125 of 194 - Date: 2018-05-31 
## LONG positions count: 11 
## Top 5 long momentum assets: NETFLIX, ADOBE (NAS), AMAZON.COM, INTEL, CISCO SYSTEMS ... 
## Top 5 long momentum scores: 15.60%, 10.93%, 7.94%, 7.23%, 6.62% ... 
## SHORT positions count: 39 
## Top 5 short momentum assets: COMCAST A, LOWE'S COMPANIES, WELLS FARGO & CO, WALMART, BRISTOL MYERS SQUIBB ... 
## Top 5 short momentum scores: -26.19%, -21.29%, -21.01%, -17.02%, -16.73% ... 
## Processing period 130 of 194 - Date: 2018-10-31 
## LONG positions count: 45 
## Top 5 long momentum assets: ELI LILLY, APPLE, PFIZER, ABBOTT LABORATORIES, LOWE'S COMPANIES ... 
## Top 5 long momentum scores: 25.76%, 21.95%, 21.47%, 20.28%, 20.14% ... 
## SHORT positions count: 5 
## Top 5 short momentum assets: WELLS FARGO & CO, INTEL, NETFLIX, CHEVRON, TEXAS INSTRUMENTS  
## Top 5 short momentum scores: -5.19%, -4.87%, -4.42%, -3.28%, -2.68%  
## Processing period 135 of 194 - Date: 2019-03-29 
## LONG positions count: 27 
## Top 5 long momentum assets: NETFLIX, DANAHER, SALESFORCE, NIKE 'B', LOWE'S COMPANIES ... 
## Top 5 long momentum scores: 25.15%, 15.96%, 14.63%, 14.12%, 11.36% ... 
## SHORT positions count: 23 
## Top 5 short momentum assets: UNITEDHEALTH GROUP, COCA COLA, GILEAD SCIENCES, AMGEN, WELLS FARGO & CO ... 
## Top 5 short momentum scores: -13.91%, -10.04%, -9.62%, -8.73%, -8.09% ... 
## Processing period 140 of 194 - Date: 2019-08-30 
## LONG positions count: 32 
## Top 5 long momentum assets: STARBUCKS, MEDTRONIC, COSTCO WHOLESALE, PROCTER & GAMBLE, AT&T ... 
## Top 5 long momentum scores: 21.90%, 14.78%, 12.26%, 10.86%, 9.98% ... 
## SHORT positions count: 17 
## Top 5 short momentum assets: NETFLIX, LOWE'S COMPANIES, JOHNSON & JOHNSON, EXXON MOBIL, ELI LILLY ... 
## Top 5 short momentum scores: -12.83%, -10.38%, -7.78%, -7.37%, -6.91% ... 
## Processing period 145 of 194 - Date: 2020-01-31 
## LONG positions count: 39 
## Top 5 long momentum assets: UNITEDHEALTH GROUP, NVIDIA, APPLE, BRISTOL MYERS SQUIBB, AMGEN ... 
## Top 5 long momentum scores: 35.28%, 35.18%, 31.11%, 26.58%, 24.58% ... 
## SHORT positions count: 11 
## Top 5 short momentum assets: MCDONALDS, INTERNATIONAL BUS.MCHS., HOME DEPOT, ORACLE, CISCO SYSTEMS ... 
## Top 5 short momentum scores: -7.96%, -7.83%, -5.88%, -3.73%, -2.93% ... 
## Processing period 150 of 194 - Date: 2020-06-30 
## LONG positions count: 35 
## Top 5 long momentum assets: NVIDIA, AMAZON.COM, ABBOTT LABORATORIES, LOWE'S COMPANIES, ELI LILLY ... 
## Top 5 long momentum scores: 31.45%, 29.65%, 23.22%, 22.31%, 21.26% ... 
## SHORT positions count: 15 
## Top 5 short momentum assets: WELLS FARGO & CO, CITIGROUP, JP MORGAN CHASE & CO., BANK OF AMERICA, COCA COLA ... 
## Top 5 short momentum scores: -35.20%, -24.50%, -16.19%, -15.37%, -12.73% ... 
## Processing period 155 of 194 - Date: 2020-11-30 
## LONG positions count: 25 
## Top 5 long momentum assets: NIKE 'B', SALESFORCE, NVIDIA, THERMO FISHER SCIENTIFIC, STARBUCKS ... 
## Top 5 long momentum scores: 23.02%, 19.20%, 18.08%, 14.29%, 13.63% ... 
## SHORT positions count: 25 
## Top 5 short momentum assets: CISCO SYSTEMS, EXXON MOBIL, CHEVRON, CITIGROUP, GILEAD SCIENCES ... 
## Top 5 short momentum scores: -23.78%, -22.48%, -17.20%, -17.18%, -16.37% ... 
## Processing period 160 of 194 - Date: 2021-04-30 
## LONG positions count: 34 
## Top 5 long momentum assets: EXXON MOBIL, WELLS FARGO & CO, INTEL, BANK OF AMERICA, CHEVRON ... 
## Top 5 long momentum scores: 35.44%, 29.46%, 28.46%, 27.65%, 24.09% ... 
## SHORT positions count: 16 
## Top 5 short momentum assets: APPLE, COSTCO WHOLESALE, NIKE 'B', WALMART, MERCK & COMPANY ... 
## Top 5 short momentum scores: -7.94%, -6.45%, -6.06%, -5.77%, -5.76% ... 
## Processing period 165 of 194 - Date: 2021-09-30 
## LONG positions count: 37 
## Top 5 long momentum assets: NVIDIA, ADOBE (NAS), ELI LILLY, DANAHER, ALPHABET A ... 
## Top 5 long momentum scores: 37.80%, 31.54%, 29.31%, 26.56%, 22.79% ... 
## SHORT positions count: 13 
## Top 5 short momentum assets: CITIGROUP, AT&T, CHEVRON, EXXON MOBIL, LOCKHEED MARTIN ... 
## Top 5 short momentum scores: -8.64%, -6.83%, -6.76%, -6.60%, -5.86% ... 
## Processing period 170 of 194 - Date: 2022-02-28 
## LONG positions count: 21 
## Top 5 long momentum assets: PFIZER, EXXON MOBIL, LOCKHEED MARTIN, APPLE, CHEVRON ... 
## Top 5 long momentum scores: 20.46%, 17.82%, 17.09%, 16.68%, 14.71% ... 
## SHORT positions count: 29 
## Top 5 short momentum assets: NETFLIX, SALESFORCE, ADOBE (NAS), WALT DISNEY, ORACLE ... 
## Top 5 short momentum scores: -38.12%, -22.38%, -17.85%, -15.44%, -15.41% ... 
## Processing period 175 of 194 - Date: 2022-07-29 
## LONG positions count: 13 
## Top 5 long momentum assets: AT&T, ELI LILLY, MERCK & COMPANY, INTERNATIONAL BUS.MCHS., BRISTOL MYERS SQUIBB ... 
## Top 5 long momentum scores: 17.22%, 13.22%, 11.12%, 8.59%, 5.44% ... 
## SHORT positions count: 37 
## Top 5 short momentum assets: NETFLIX, NVIDIA, AMAZON.COM, WALT DISNEY, INTEL ... 
## Top 5 short momentum scores: -53.32%, -44.44%, -34.84%, -31.18%, -24.52% ... 
## Processing period 180 of 194 - Date: 2022-12-30 
## LONG positions count: 37 
## Top 5 long momentum assets: GILEAD SCIENCES, NETFLIX, MERCK & COMPANY, ELI LILLY, STARBUCKS ... 
## Top 5 long momentum scores: 38.38%, 36.67%, 29.01%, 23.19%, 21.57% ... 
## SHORT positions count: 13 
## Top 5 short momentum assets: AMAZON.COM, AMERICAN TOWER, WALT DISNEY, MEDTRONIC, ADOBE (NAS) ... 
## Top 5 short momentum scores: -23.85%, -12.91%, -12.68%, -10.10%, -7.63% ... 
## Processing period 185 of 194 - Date: 2023-05-31 
## LONG positions count: 24 
## Top 5 long momentum assets: NVIDIA, MICROSOFT, SALESFORCE, APPLE, ELI LILLY ... 
## Top 5 long momentum scores: 42.03%, 23.99%, 18.10%, 17.60%, 15.03% ... 
## SHORT positions count: 26 
## Top 5 short momentum assets: BANK OF AMERICA, WELLS FARGO & CO, AT&T, PFIZER, DANAHER ... 
## Top 5 short momentum scores: -17.47%, -15.19%, -13.25%, -11.93%, -10.39% ... 
## Processing period 190 of 194 - Date: 2023-10-31 
## LONG positions count: 15 
## Top 5 long momentum assets: AMGEN, ELI LILLY, EXXON MOBIL, ALPHABET A, CHEVRON ... 
## Top 5 long momentum scores: 21.05%, 14.53%, 9.63%, 9.32%, 7.16% ... 
## SHORT positions count: 35 
## Top 5 short momentum assets: NEXTERA ENERGY, AMERICAN TOWER, NETFLIX, NIKE 'B', VERIZON COMMUNICATIONS ... 
## Top 5 short momentum scores: -22.79%, -15.21%, -14.28%, -13.36%, -12.85% ... 
## Processing period 194 of 194 - Date: 2024-02-29 
## LONG positions count: 42 
## Top 5 long momentum assets: NVIDIA, CITIGROUP, SALESFORCE, NETFLIX, BANK OF AMERICA ... 
## Top 5 long momentum scores: 50.88%, 42.24%, 39.96%, 37.02%, 29.12% ... 
## SHORT positions count: 8 
## Top 5 short momentum assets: PFIZER, LOCKHEED MARTIN, BRISTOL MYERS SQUIBB, UNITEDHEALTH GROUP, CISCO SYSTEMS ... 
## Top 5 short momentum scores: -11.39%, -5.55%, -5.16%, -4.45%, -3.74% ... 
## Saved all momentum scores to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_scores.csv 
## 
## Analyzing long-short momentum portfolio performance...
## 
## ----- Long-Short Momentum Portfolio Performance Metrics -----
##                   Metric Long.Short.Portfolio S.P.500.Benchmark
## 1         Average Return               -0.00%             9.04%
## 2     Standard Deviation                5.96%            16.18%
## 3           Sharpe Ratio               -0.047             0.144
## 4 Upside-Potential Ratio                0.329             0.465
## Saved performance comparison to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_performance_comparison.csv 
## Saved portfolio composition to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_portfolio_composition.csv 
## Saved portfolio returns to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_portfolio_returns.csv 
## 
## ----- Most Frequently Selected Long Assets -----
## all_selected_long
##              ADOBE (NAS)                  NETFLIX       UNITEDHEALTH GROUP 
##                      139                      137                      136 
##         COSTCO WHOLESALE                    APPLE                  DANAHER 
##                      135                      133                      133 
##            UNION PACIFIC               SALESFORCE THERMO FISHER SCIENTIFIC 
##                      132                      131                      131 
##        ACCENTURE CLASS A 
##                      130 
## 
## ----- Most Frequently Selected Short Assets -----
## all_selected_short
##                    AT&T             EXXON MOBIL  VERIZON COMMUNICATIONS 
##                     104                     101                      98 
##                   INTEL               CITIGROUP                 CHEVRON 
##                      94                      93                      92 
##           CISCO SYSTEMS         GILEAD SCIENCES                  PFIZER 
##                      86                      86                      86 
## INTERNATIONAL BUS.MCHS. 
##                      85 
## Saved long asset selection frequency to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_long_asset_selection_frequency.csv 
## Saved short asset selection frequency to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_short_asset_selection_frequency.csv 
## 
## Analysis completed in 0.03 minutes
# ---- ADDITIONAL ANALYSIS ----

# 1. Plot the portfolio returns alongside the benchmark
portfolio_vs_benchmark <- merge(
  `Long-Short` = cumprod(1 + long_short_momentum_result$portfolio$returns) - 1, 
  Benchmark = cumprod(1 + long_short_momentum_result$data$sp500_returns[(36+1):length(long_short_momentum_result$data$sp500_returns)]) - 1
)

# Create a plot with different colors and a legend
plot(portfolio_vs_benchmark, 
     main = "Long-Short Momentum Portfolio vs. S&P 500", 
     col = c("blue", "red"),
     lwd = c(2, 2),
     legend.loc = "topleft")

# Save the plot
output_file <- file.path(base_dir, "long_short_momentum_portfolio_vs_benchmark.png")
png(output_file, width = 800, height = 500)
plot(portfolio_vs_benchmark, 
     main = "Long-Short Momentum Portfolio vs. S&P 500", 
     col = c("blue", "red"),
     lwd = c(2, 2),
     legend.loc = "topleft")
dev.off()
## png 
##   2
cat("Saved portfolio vs benchmark plot to:", output_file, "\n")
## Saved portfolio vs benchmark plot to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_portfolio_vs_benchmark.png
# 2. Calculate annual returns
annual_returns <- apply.yearly(long_short_momentum_result$portfolio$returns, Return.cumulative)
print(annual_returns)
##                     [,1]
## 2008-12-31 -0.0707925166
## 2009-12-31 -0.0242900337
## 2010-12-31  0.0281704396
## 2011-12-30  0.0802211329
## 2012-12-31 -0.1076291865
## 2013-12-31  0.0138861492
## 2014-12-31 -0.0204361646
## 2015-12-31 -0.0003605381
## 2016-12-30 -0.0320946763
## 2017-12-29 -0.0123021490
## 2018-12-31  0.0114466335
## 2019-12-31 -0.0021798030
## 2020-12-31  0.0915335408
## 2021-12-31  0.0224574350
## 2022-12-30  0.0126632810
## 2023-12-29 -0.0316552711
## 2024-02-29  0.0308158468
# 3. Monthly returns statistics
monthly_stats <- data.frame(
  Statistic = c("Min", "1st Quartile", "Median", "Mean", "3rd Quartile", "Max", "Standard Deviation"),
  Value = c(
    min(long_short_momentum_result$portfolio$returns),
    quantile(long_short_momentum_result$portfolio$returns, 0.25),
    median(long_short_momentum_result$portfolio$returns),
    mean(long_short_momentum_result$portfolio$returns),
    quantile(long_short_momentum_result$portfolio$returns, 0.75),
    max(long_short_momentum_result$portfolio$returns),
    sd(long_short_momentum_result$portfolio$returns)
  )
)

# Print monthly statistics
cat("\n----- Monthly Return Statistics -----\n")
## 
## ----- Monthly Return Statistics -----
print(monthly_stats)
##            Statistic         Value
## 1                Min -1.121605e-01
## 2       1st Quartile -9.546434e-03
## 3             Median  3.418900e-04
## 4               Mean -1.527840e-06
## 5       3rd Quartile  1.009043e-02
## 6                Max  4.661465e-02
## 7 Standard Deviation  1.720165e-02
# Save statistics to CSV
output_file <- file.path(base_dir, "long_short_momentum_monthly_statistics.csv")
write.csv(monthly_stats, output_file, row.names = FALSE)
cat("Saved monthly return statistics to:", output_file, "\n")
## Saved monthly return statistics to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_monthly_statistics.csv
# Save all output files in one directory for easy access
save(long_short_momentum_result, file = file.path(base_dir, "long_short_momentum_portfolio_results.RData"))
cat("All analysis results saved to:", file.path(base_dir, "long_short_momentum_portfolio_results.RData"), "\n")
## All analysis results saved to: C:/Users/lcyep/OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey/Tec/Semestre 6/Risk/R, project/long_short_momentum_portfolio_results.RData
# 4. Additional visualization: Histogram of returns
png(file.path(base_dir, "long_short_momentum_returns_histogram.png"), width = 800, height = 500)
hist(long_short_momentum_result$portfolio$returns, 
     breaks = 30, 
     main = "Long-Short Momentum Portfolio Monthly Returns Distribution", 
     xlab = "Monthly Return", 
     col = "skyblue")
abline(v = mean(long_short_momentum_result$portfolio$returns), col = "red", lwd = 2)
dev.off()
## png 
##   2
# 5. Drawdown analysis
drawdown_portfolio <- PerformanceAnalytics::Drawdowns(long_short_momentum_result$portfolio$returns)
drawdown_benchmark <- PerformanceAnalytics::Drawdowns(
  long_short_momentum_result$data$sp500_returns[(36+1):length(long_short_momentum_result$data$sp500_returns)]
)

drawdowns <- merge(
  `Long-Short` = drawdown_portfolio,
  Benchmark = drawdown_benchmark
)

png(file.path(base_dir, "long_short_momentum_drawdowns.png"), width = 800, height = 500)
plot(drawdowns, 
     main = "Drawdowns: Long-Short Momentum Portfolio vs S&P 500", 
     col = c("blue", "red"),
     lwd = c(2, 2),
     legend.loc = "bottomleft")
dev.off()
## png 
##   2
# 6. Count the average number of stocks in the portfolio
avg_long_stocks <- mean(sapply(long_short_momentum_result$portfolio$selected_long_assets, length))
avg_short_stocks <- mean(sapply(long_short_momentum_result$portfolio$selected_short_assets, length))
cat("\nAverage number of long stocks in the portfolio:", round(avg_long_stocks, 2), "\n")
## 
## Average number of long stocks in the portfolio: 30.68
cat("Average number of short stocks in the portfolio:", round(avg_short_stocks, 2), "\n")
## Average number of short stocks in the portfolio: 19.32
# 7. Calculate the turnover rate for long positions
long_turnover <- numeric(length(long_short_momentum_result$portfolio$selected_long_assets) - 1)

for (i in 2:length(long_short_momentum_result$portfolio$selected_long_assets)) {
  prev_stocks <- long_short_momentum_result$portfolio$selected_long_assets[[i-1]]
  curr_stocks <- long_short_momentum_result$portfolio$selected_long_assets[[i]]
  
  # Calculate how many stocks were changed
  stocks_removed <- setdiff(prev_stocks, curr_stocks)
  stocks_added <- setdiff(curr_stocks, prev_stocks)
  
  # Turnover is the number of stocks changed divided by the average number of stocks
  total_changed <- length(stocks_removed) + length(stocks_added)
  avg_portfolio_size <- (length(prev_stocks) + length(curr_stocks)) / 2
  
  if (avg_portfolio_size > 0) {
    long_turnover[i-1] <- total_changed / (2 * avg_portfolio_size)
  } else {
    long_turnover[i-1] <- 0
  }
}

# Calculate the turnover rate for short positions
short_turnover <- numeric(length(long_short_momentum_result$portfolio$selected_short_assets) - 1)

for (i in 2:length(long_short_momentum_result$portfolio$selected_short_assets)) {
  prev_stocks <- long_short_momentum_result$portfolio$selected_short_assets[[i-1]]
  curr_stocks <- long_short_momentum_result$portfolio$selected_short_assets[[i]]
  
  # Calculate how many stocks were changed
  stocks_removed <- setdiff(prev_stocks, curr_stocks)
  stocks_added <- setdiff(curr_stocks, prev_stocks)
  
  # Turnover is the number of stocks changed divided by the average number of stocks
  total_changed <- length(stocks_removed) + length(stocks_added)
  avg_portfolio_size <- (length(prev_stocks) + length(curr_stocks)) / 2
  
  if (avg_portfolio_size > 0) {
    short_turnover[i-1] <- total_changed / (2 * avg_portfolio_size)
  } else {
    short_turnover[i-1] <- 0
  }
}

cat("Average monthly turnover rate for long positions:", round(mean(long_turnover, na.rm = TRUE) * 100, 2), "%\n")
## Average monthly turnover rate for long positions: 25.49 %
cat("Average monthly turnover rate for short positions:", round(mean(short_turnover, na.rm = TRUE) * 100, 2), "%\n")
## Average monthly turnover rate for short positions: 40.58 %