Add main.r
This commit is contained in:
parent
f898db12bc
commit
1c21515f4f
129
main.r
Normal file
129
main.r
Normal file
@ -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)
|
||||||
Loading…
x
Reference in New Issue
Block a user