From 1c21515f4fd99adad75672b02ea9f7dd6426f506 Mon Sep 17 00:00:00 2001 From: git Date: Mon, 16 Mar 2026 13:13:15 +0000 Subject: [PATCH] Add main.r --- main.r | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 main.r diff --git a/main.r b/main.r new file mode 100644 index 0000000..672db93 --- /dev/null +++ b/main.r @@ -0,0 +1,129 @@ +GetECBHistoricalExchangeRateData <- function() { + # 1. Setup temporary files and download the data + temp_zip <- tempfile(fileext = ".zip") + url <- "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.zip" + + message("Downloading data from ECB...") + download.file(url, temp_zip, quiet = TRUE) + + # 2. Unzip and identify the CSV file + unzipped_files <- unzip(temp_zip, exdir = tempdir()) + csv_file <- unzipped_files[grep("\\.csv$", unzipped_files)] + + # 3. Load the data into R + message("Loading data...") + df <- read.csv(csv_file, na.strings = c("N/A", "NA", ""), stringsAsFactors = FALSE) + + # Clean up temp files + unlink(temp_zip) + unlink(csv_file) + + return(df) +} +PreProcessData <- function(df, target_currencies, last_n_days = NULL) { + + # Preprocess Dates and Time + df$Date <- as.Date(df$Date) + df <- df[order(df$Date), ] + + # Filter by the last N days if specified + if (!is.null(last_n_days)) { + cutoff_date <- max(df$Date, na.rm = TRUE) - last_n_days + df <- df[df$Date >= cutoff_date, ] + message(sprintf("Filtered data to the last %d days (since %s).", last_n_days, cutoff_date)) + } + + # Create a Time Index for the regression + df$TimeIndex <- as.numeric(df$Date - min(df$Date)) + + # Ensure targets actually exist in the dataframe to prevent errors + valid_targets <- intersect(target_currencies, names(df)) + + # Filter the data frame down to Date, TimeIndex, and those specific targets + df <- df[, c("Date", "TimeIndex", valid_targets)] + + # Create the new cross pairs dynamically + # combn(valid_targets, 2) creates all unique 2-pair combinations + if (length(valid_targets) >= 2) { + pair_combos <- combn(valid_targets, 2) + + for (i in 1:ncol(pair_combos)) { + base_curr <- pair_combos[1, i] + quote_curr <- pair_combos[2, i] + + # Create column name, e.g., "USD_JPY" + pair_name <- paste0(base_curr, "_", quote_curr) + + # Math: To get Base/Quote, divide the ECB Quote column by the ECB Base column + df[[pair_name]] <- df[[quote_curr]] / df[[base_curr]] + } + } + + # Update the 'currencies' vector so the loop analyzes original and new columns + currencies <- setdiff(names(df), c("Date", "TimeIndex")) + + return(list(currencies = currencies, df = df)) +} +CalculateMetrics <- function(df,currencies) { + # 5. Loop through each currency, run regression, and calculate metrics + results_list <- list() + + message("Running regressions...") + for (curr in currencies) { + valid_data <- df[!is.na(df[[curr]]), ] + + if (nrow(valid_data) > 2) { + + # Simple linear regression: Exchange Rate ~ Time + model <- lm(valid_data[[curr]] ~ valid_data$TimeIndex) + + # Extract Beta (slope) and Residual Standard Error (RSE) + beta <- coef(model)[2] + rse <- summary(model)$sigma + + # Calculate Signal-to-Noise Ratio: |Beta| / RSE + if (!is.na(rse) && rse > 0) { + signal_to_noise <- abs(beta) / rse + } else { + signal_to_noise <- NA + } + + # Store results + results_list[[curr]] <- data.frame( + Currency = curr, + Beta = beta, + AbsBeta = abs(beta), + RSE = rse, + SignalToNoise = signal_to_noise, + stringsAsFactors = FALSE, + row.names = NULL + ) + } + } + + # Combine all results + results_df <- do.call(rbind, results_list) + + return (results_df) + +} +OrderBySignalToNoiseRatio <- function(results_df) { + + # 6. Order by the Signal-to-Noise ratio and get the top 3 + top_3_currencies <- results_df[order(results_df$SignalToNoise, decreasing = TRUE), ] + top_3_currencies <- head(top_3_currencies, 3) + return (top_3_currencies) +} + +# +# 10. RUNTIME +# + +df <- GetECBHistoricalExchangeRateData() +res <- PreProcessData(df,c("USD", "JPY", "GBP","CAD","NOK"),720) +results_df <- CalculateMetrics(res$df,res$currencies) +top_3_currencies <- OrderBySignalToNoiseRatio(results_df) + +# Print the final output +message("\nTop 3 currencies by Trend Predictability (|Beta| / RSE):") +print(top_3_currencies) \ No newline at end of file