Введение

Мы будем изучать торговую стратегию, описанную в Использование анализа основных компонентов для мультивалютной торговли на валютном рынке Хён Ву Бён и др. ». Цель статьи - понять силу доллара США по отношению к нескольким валютам и использовать это в качестве сигнала для построения торговых стратегий.

Почему доллары? По данным МВФ, около 62% распределения валюты приходится на доллар США.

Поскольку это многомерная проблема, авторы использовали PCA для уменьшения размеров до 2D. Математика для машинного обучения: PCA от Imeperial College London - отличный ресурс (IMO).

Подготовка данных

  1. Получайте данные по интересующим валютам с помощью AlphaVantage API
  2. Убедитесь, что данные представлены в формате таймсерий (например, xts). Если нет, создайте таймсерию USDCAD <- xts(x = USDCAD[,c("open", "high", "low", "close")
  3. Конвертируйте все котировки валютных пар в доллары США (USDCAD будет CADUSD)
  4. Объедините все цены закрытия валют. Назовите эту переменную X

Алгоритм

  1. Определите временное окно окна. В основном количество дней с текущего дня. В этой статье было выбрано n = 55.
  2. Выберите окно тренировки. От начала до количества дней. Рассчитайте доходность валютных пар для выбранного окна обучения.
  3. Матричное умножение X ′ * X (размер: 55 x 55)
  4. Примените PCA к шагу 3
  5. Извлечь собственный вектор (размерность: количество валют * 1)
  6. Умножьте строку n + 1 матрицы X на собственный вектор ′ (размерность: 1 x 9 * 9 x 1).
  7. Запишите шаг 6 как USDindex
  8. Сдвиньте окно (временные рамки) и повторяйте алгоритм до последнего дня набора данных.

Код

rolling_window_eigen_weight_g <- function(data, n = 55,...) {
  numRow <- nrow(data)
  rolling_window_eigen_df<- data.frame(EURUSD = numeric(), AUDUSD = numeric(), JPYUSD = numeric(), CHFUSD = numeric())
  rolling_g_it <- list()
#Loop for each window
    for (i in 1:(numRow-n-1)) {
    window_start <- i #start window
    window_end <- i+n -1 #end window
    x <- data[window_start:window_end, ] #training sample
    x_x <- t(x) %*% x #Step 3 of the algorithm
    e1 <- matrix(prcomp(x_x)$rotation[,1]) #extracting eigenvector - step 5
    
    #Checking to see whether the weights add up to 1
    if (round(sum(e1^2)) !=1) {
      stop("weights do not add up to 1")
    }
    
    #Ensure that number of rows in the sample is equal to window length
    if (nrow(x) == n) {
      #Verifying that number of column of training sample is equivalent to number of rows in eigen vector 
      if (ncol(x) == nrow(e1)) {
        g_it <- data[window_end+1,] %*% e1 #multuply the n+1 data with eigenvector
        g_it <- xts(order.by = index(data[window_end+1,]), g_it) #Store the results in xts format
      }
    }
    
    rolling_g_it[[i]] <- g_it #store the xts in a list
  }
  
  colnames(rolling_window_eigen_df) <- c("EURUSD", "AUDUSD", "JPYUSD", "CHFUSD") #naming the columns
  rolling_g_it <- do.call(rbind, rolling_g_it) #convering from list to xts
  return(rolling_g_it)
}

Выполнение кода

USDindex <- rolling_window_eigen_weight_g(X)

Сюжет

Теперь мы можем сгенерировать длинный и короткий сигнал с помощью USDindex. Поскольку математика упрощена, остальная часть статьи должна быть легко реализована.