# 加载必要的库
library(readr)
library(dplyr)
library(lubridate) # 可选，用于更方便的日期处理
library(zoo)       # 用于 rollmean 和 lag/lead (dplyr也有lag/lead)
setwd("C:/Research_data/Markov_subsampling/real_data/realdata1")
# 1. 加载原始数据
tryCatch({
  df_nasdaq <- read_csv("nasdq2.csv")
  print("文件 'nasdq2.csv' 加载成功.")
}, error = function(e) {
  stop(paste("错误: 文件 'nasdq2.csv' 未找到或加载失败. 请确保文件存在于工作目录中。", e))
})

# 2. 日期处理 和 排序
# 将Date列转换为Date类型
df_nasdaq$Date <- as.Date(df_nasdaq$Date)
# 按日期排序，确保后续的滞后和移动平均计算正确
df_nasdaq <- df_nasdaq %>% arrange(Date)

print("数据框头部 (日期转换后):")
print(head(df_nasdaq))
# str(df_nasdaq) # 查看数据结构

# 3. 定义目标变量 (Y)
df_nasdaq <- df_nasdaq %>%
  mutate(
    Future_Close = lead(Close, n = 1), # 获取下一天的收盘价
    Target_Return = (Future_Close - Close) / Close # 计算日收益率
  )

# 4. 特征工程 (X)

# 创建滞后收益率 (例如，过去5天的收益率)
# dplyr的lag默认是在当前分组内操作，这里数据已按Date排好序，直接用即可
for (i in 1:5) {
  col_name <- paste0("Return_Lag_", i)
  df_nasdaq <- df_nasdaq %>% mutate(!!col_name := lag(Target_Return, n = i))
}

# 创建滞后收盘价
df_nasdaq <- df_nasdaq %>% mutate(Close_Lag_1 = lag(Close, n = 1))

# 创建移动平均线 (例如，5日和20日收盘价移动平均)
# zoo::rollmean 需要数据没有NA，并且有足够的观测数据
# align = "right" 表示使用过去N天的数据
# fill = NA 会在窗口不足时填充NA
df_nasdaq <- df_nasdaq %>%
  mutate(
    MA_5 = rollmean(Close, k = 5, fill = NA, align = "right"),
    MA_20 = rollmean(Close, k = 20, fill = NA, align = "right")
  )

# 5. 处理因特征工程产生的NA值
# 在所有滞后和移动平均计算完成后，删除包含NA的行
df_nasdaq_processed <- df_nasdaq %>% na.omit()

print("处理后数据框的头部 (特征工程和移除NA后):")
print(head(df_nasdaq_processed))
print(paste("处理后数据框的维度:", paste(dim(df_nasdaq_processed), collapse = "x")))

# 6. 定义特征 (X) 和目标 (y)
# 我们要预测 'Target_Return'
# 选择与Python脚本中类似的特征列
#feature_names <- c(
 #'Open', 'High', 'Low', 'Close', 'Volume',  # 当日市场数据
 #'InterestRate', 'ExchangeRate', 'VIX', 'TEDSpread', 'EFFR', 'Gold', 'Oil', # 经济指标
 #'Return_Lag_1', 'Return_Lag_2', 'Return_Lag_3', 'Return_Lag_4', 'Return_Lag_5', # 滞后收益率  
 ##'Close_Lag_1', # 前一日收盘价 
 #'MA_5', 'MA_20' # 移动平均线
#)

#X <- df_nasdaq_processed[, feature_names]
#y <- df_nasdaq_processed$Target_Return


# 7. 数据分割 (按时间顺序)
# 分割为训练集 (80%) 和测试集 (20%)
#split_index <- floor(0.8 * nrow(X))
#
#X_train <- X[1:split_index, ]
#X_test <- X[(split_index + 1):nrow(X), ]

#y_train <- y[1:split_index]
#y_test <- y[(split_index + 1):length(y)]
#
#print(paste("训练集维度: X_train:", paste(dim(X_train), collapse = "x"), ", y_train:", length(y_train)))
#print(paste("测试集维度: X_test:", paste(dim(X_test), collapse = "x"), ", y_test:", length(y_test)))


# 8. 数据标准化 (Scaling)
# 计算训练集的均值和标准差
#train_mean <- apply(X_train, 2, mean)
#train_sd <- apply(X_train, 2, sd)

# 标准化训练集
#X_train_scaled <- scale(X_train, center = train_mean, scale = train_sd)

# 使用训练集的均值和标准差来标准化测试集
#X_test_scaled <- scale(X_test, center = train_mean, scale = train_sd)

# 将矩阵转换回数据框 (可选，但通常更方便)
#X_train_scaled <- as.data.frame(X_train_scaled)
#X_test_scaled <- as.data.frame(X_test_scaled)

#print("标准化后的训练集特征头部:")
#print(head(X_train_scaled))

# ---- 后续可以基于 X_train_scaled, y_train, X_test_scaled, y_test 进行模型训练 ----
# 例如，使用 R 的 lm() 函数进行线性回归:
#
# model_lm <- lm(y_train ~ ., data = data.frame(X_train_scaled, y_train = y_train))
#summary(model_lm)
#
#y_pred_test <- predict(model_lm, newdata = X_test_scaled)
#
# # 评估指标 (示例)
#mse_test <- mean((y_test - y_pred_test)^2)
#rmse_test <- sqrt(mse_test)
#mae_test <- mean(abs(y_test - y_pred_test))
# print(paste("测试集 RMSE:", rmse_test))
# print(paste("测试集 MAE:", mae_test))
#
# # 计算 R-squared for test set
# ss_tot <- sum((y_test - mean(y_train))^2) # 使用训练集的均值作为基准
# ss_res <- sum((y_test - y_pred_test)^2)
# r2_test <- 1 - (ss_res / ss_tot)
# print(paste("测试集 R-squared:", r2_test))
#
# # (可选) 将处理好的数据框 (在分割和标准化之前) 保存到文件
write_csv(df_nasdaq_processed, "nasdaq_processed_R.csv")

