04 April, 2022
Analysis price of the my list of currencies.
Install packages and set environment :earth asia:
install.packages("azuremlsdk")
options(max.print = 1e3, scipen = 999, width = 1e2)
options(stringsAsFactors = F)
suppressPackageStartupMessages({
library(dplyr)
library(tidyr)
library(lubridate)
library(stringr)
library(gt)
library(tidyverse)
library(glue)
library(ggplot2)
library(azuremlsdk)
})
.azureml_dataset_name <- "Currencies"
Connect to Azure ML workspace:
ws <- azuremlsdk::load_workspace_from_config()
sprintf(
"%s workspace located in %s region", ws$name, ws$location
)
## [1] "portf-opt-ws workspace located in westeurope region"
WARNING: I used currency exchange rates
data from Kaggle
Dataset:
currencies_ds <- azuremlsdk::get_dataset_by_name(ws, name = .azureml_dataset_name)
sprintf(
"Dataset name: %s. %s",
currencies_ds$name,
currencies_ds$description
)
## [1] "Dataset name: Currencies. Source: https://www.kaggle.com/datasets/dhruvildave/currency-exchange-rates"
Get USD/RUB
top higher rates:
quotes_df <- currencies_ds$to_pandas_dataframe()
# ~ 20 years, 150 currencies and 1.5M rows
quotes_df %>%
filter(slug == "USD/RUB") %>%
select(-slug) %>%
top_n(10) %>%
gt() %>%
tab_header(
title = "USD/RUB Rate",
subtitle = glue("{min(quotes_df$date)} to {max(quotes_df$date)}")
) %>%
fmt_date(
columns = date,
date_style = 6
) %>%
fmt_number(
columns = c(open, high, low, close)
)
## Selecting by close
USD/RUB Rate | ||||
---|---|---|---|---|
1996-10-30 to 2021-08-30 | ||||
date | open | high | low | close |
Jan 21, 2016 | 82.06 | 85.82 | 82.06 | 81.82 |
Jan 22, 2016 | 80.61 | 81.26 | 77.94 | 82.90 |
Jan 26, 2016 | 81.54 | 82.16 | 78.33 | 79.84 |
Feb 3, 2016 | 79.56 | 79.75 | 77.87 | 79.71 |
Feb 10, 2016 | 79.39 | 79.49 | 77.65 | 79.59 |
Feb 12, 2016 | 79.36 | 79.74 | 78.59 | 79.77 |
Mar 19, 2020 | 80.92 | 82.07 | 79.24 | 80.92 |
Mar 23, 2020 | 79.72 | 81.34 | 79.49 | 79.84 |
Mar 31, 2020 | 79.59 | 79.69 | 77.66 | 79.59 |
Nov 3, 2020 | 80.55 | 80.57 | 79.05 | 80.52 |
Calculate Return
and Log Return
for last 10 years:
quotes_df %<>%
transmute(
symbol = slug,
price = close,
date
) %>%
filter(
str_detect(symbol, "USD/") &
date > max(date) - lubridate::years(10)
) %>%
filter(!(symbol == "USD/RUB" & price < 1)) %>%
arrange(date) %>%
group_by(symbol) %>%
mutate(
return = c(NA_real_, diff(price))/lag(price),
log_return = log(1 + return)
) %>%
na.omit
Calculate statistics and volatility
:
quotes_stats <- quotes_df %>%
summarise(
max_price = max(price),
min_price = min(price),
last_price = last(price),
max_min_rate = max(price)/min(price),
volatility = sd(log_return)
)
quotes_stats %>%
mutate(
`100x Volatility` = volatility*100
) %>%
arrange(volatility) %>%
select(-volatility) %>%
gt() %>%
tab_header(
title = "The Least and The Most Volatile Currencies",
subtitle = glue("{min(quotes_df$date)} to {max(quotes_df$date)}")
) %>%
fmt_number(
columns = c(max_price, min_price, max_min_rate, last_price, `100x Volatility`)
)
The Least and The Most Volatile Currencies | |||||
---|---|---|---|---|---|
2011-09-01 to 2021-08-30 | |||||
symbol | max_price | min_price | last_price | max_min_rate | 100x Volatility |
USD/AED | 3.67 | 3.67 | 3.67 | 1.00 | 0.01 |
USD/HKD | 7.85 | 7.75 | 7.79 | 1.01 | 0.03 |
USD/KWD | 0.31 | 0.27 | 0.30 | 1.16 | 0.16 |
USD/CNY | 7.18 | 6.03 | 6.47 | 1.19 | 0.23 |
USD/DJF | 177.72 | 172.00 | 177.50 | 1.03 | 0.28 |
USD/SGD | 1.46 | 1.20 | 1.34 | 1.21 | 0.33 |
USD/SAR | 3.77 | 3.30 | 3.75 | 1.14 | 0.39 |
USD/GTQ | 7.89 | 7.04 | 7.73 | 1.12 | 0.41 |
USD/ILS | 4.07 | 3.13 | 3.20 | 1.30 | 0.45 |
USD/TTD | 6.78 | 5.93 | 6.76 | 1.14 | 0.47 |
USD/CAD | 1.46 | 0.97 | 1.26 | 1.51 | 0.47 |
USD/MYR | 4.49 | 2.96 | 4.16 | 1.52 | 0.50 |
USD/DKK | 7.15 | 5.18 | 6.30 | 1.38 | 0.51 |
USD/EUR | 0.96 | 0.70 | 0.85 | 1.38 | 0.51 |
USD/CRC | 619.70 | 478.54 | 619.70 | 1.29 | 0.53 |
USD/PHP | 54.23 | 39.75 | 49.71 | 1.36 | 0.54 |
USD/INR | 77.57 | 45.70 | 73.29 | 1.70 | 0.54 |
USD/RON | 4.54 | 2.93 | 4.18 | 1.55 | 0.55 |
USD/JPY | 125.63 | 75.74 | 109.90 | 1.66 | 0.55 |
USD/GBP | 0.87 | 0.58 | 0.73 | 1.49 | 0.55 |
USD/JMD | 153.88 | 83.37 | 150.53 | 1.85 | 0.56 |
USD/MKD | 58.92 | 42.07 | 51.98 | 1.40 | 0.58 |
USD/MDL | 20.31 | 11.09 | 17.58 | 1.83 | 0.61 |
USD/BDT | 84.72 | 72.39 | 84.72 | 1.17 | 0.62 |
USD/AUD | 1.74 | 0.93 | 1.37 | 1.88 | 0.63 |
USD/SEK | 10.44 | 6.29 | 8.62 | 1.66 | 0.64 |
USD/CHF | 1.03 | 0.79 | 0.92 | 1.31 | 0.64 |
USD/CZK | 26.03 | 16.75 | 21.67 | 1.55 | 0.64 |
USD/BWP | 12.19 | 6.58 | 11.12 | 1.85 | 0.66 |
USD/NZD | 1.78 | 1.13 | 1.43 | 1.57 | 0.66 |
USD/THB | 36.43 | 28.07 | 32.45 | 1.30 | 0.67 |
USD/LKR | 199.43 | 106.22 | 199.43 | 1.88 | 0.67 |
USD/KRW | 1,262.93 | 999.83 | 1,165.89 | 1.26 | 0.70 |
USD/RSD | 118.47 | 70.05 | 99.29 | 1.69 | 0.70 |
USD/UYU | 45.31 | 18.08 | 42.53 | 2.51 | 0.71 |
USD/PLN | 4.28 | 2.87 | 3.86 | 1.49 | 0.72 |
USD/HUF | 338.26 | 188.61 | 294.66 | 1.79 | 0.74 |
USD/MUR | 42.55 | 26.50 | 42.55 | 1.61 | 0.79 |
USD/MXN | 25.34 | 11.98 | 20.14 | 2.11 | 0.80 |
USD/NIO | 35.13 | 22.05 | 35.00 | 1.59 | 0.84 |
USD/KZT | 454.34 | 174.15 | 427.18 | 2.61 | 0.84 |
USD/QAR | 3.90 | 3.00 | 3.64 | 1.30 | 0.95 |
USD/TRY | 8.78 | 1.71 | 8.38 | 5.12 | 0.97 |
USD/ZAR | 19.25 | 6.98 | 14.66 | 2.76 | 0.99 |
USD/RUB | 82.90 | 28.79 | 73.50 | 2.88 | 1.05 |
USD/ZMW | 22.64 | 5.11 | 15.82 | 4.43 | 1.06 |
USD/BRL | 5.89 | 1.58 | 5.19 | 3.72 | 1.08 |
USD/ARS | 97.70 | 4.10 | 97.70 | 23.85 | 1.11 |
USD/TND | 3.06 | 1.37 | 2.79 | 2.23 | 1.17 |
USD/BGN | 1.87 | 1.21 | 1.66 | 1.55 | 1.28 |
USD/EGP | 19.60 | 5.83 | 15.65 | 3.37 | 1.29 |
USD/NOK | 11.76 | 5.36 | 8.66 | 2.19 | 1.31 |
USD/PEN | 4.11 | 2.38 | 4.07 | 1.72 | 1.34 |
USD/BYN | 3.08 | 0.51 | 2.51 | 6.04 | 1.37 |
USD/MAD | 10.29 | 7.89 | 8.95 | 1.30 | 1.43 |
USD/UAH | 33.50 | 7.80 | 26.92 | 4.30 | 1.83 |
USD/SDG | 451.00 | 1.39 | 440.03 | 324.46 | 5.96 |
USD/BND | 1.43 | 0.66 | 1.34 | 2.18 | 6.29 |
USD/XOF | 647.00 | 58.00 | 555.47 | 11.16 | 6.44 |
USD/IDR | 16,504.80 | 892.00 | 14,370.00 | 18.50 | 6.58 |
USD/HNL | 24.90 | 3.00 | 23.83 | 8.30 | 8.14 |
USD/MZN | 78.49 | 3.30 | 63.11 | 23.78 | 8.77 |
USD/ETB | 45.23 | 1.00 | 45.06 | 45.23 | 9.26 |
USD/TWD | 33.73 | 1.80 | 27.77 | 18.72 | 9.86 |
USD/PKR | 168.15 | 2.00 | 165.63 | 84.07 | 12.69 |
USD/UZS | 10,653.20 | 83.00 | 10,646.89 | 128.35 | 12.93 |
USD/GHS | 573.00 | 1.00 | 5.98 | 573.00 | 13.74 |
USD/ISK | 147.04 | 2.00 | 126.65 | 73.52 | 16.09 |
USD/PGK | 3.51 | 0.29 | 3.51 | 11.89 | 16.18 |
USD/MMK | 1,642.00 | 6.23 | 1,642.00 | 263.65 | 16.59 |
USD/CLP | 867.50 | 5.00 | 782.21 | 173.50 | 18.70 |
USD/SZL | 1,189.00 | 1.07 | 14.91 | 1,111.21 | 18.79 |
USD/XPF | 119.35 | 1.00 | 100.90 | 119.35 | 19.32 |
USD/SOS | 1,670.00 | 6.00 | 571.00 | 278.33 | 29.77 |
USD/MWK | 812.43 | 1.00 | 804.55 | 812.43 | 30.83 |
USD/NGN | 412.50 | 1.00 | 411.00 | 412.50 | 31.65 |
USD/VND | 23,631.00 | 21.00 | 22,775.00 | 1,125.29 | 34.09 |
USD/COP | 4,174.75 | 3.67 | 3,805.25 | 1,136.67 | 37.09 |
USD/IQD | 1,578.00 | 10.00 | 1,458.00 | 157.80 | 37.10 |
USD/MGA | 3,931.18 | 0.30 | 3,808.00 | 12,910.29 | 46.29 |
USD/SLL | 10,250.50 | 1.00 | 10,250.50 | 10,250.50 | 47.59 |
My broker trades the following pairs:
symbols <- c(
'RUB',
'EUR', 'GBP', 'CHF', 'CNY', 'HKD', 'JPY', 'SEK', 'SGD', 'AUD',
'AED', 'KZT', 'BYN', 'TRY', 'MXN'
)
symbols <- str_c("USD", symbols, sep = "/")
quotes_stats %>%
filter(
symbol %in% symbols
) %>%
mutate(
`100x Volatility` = volatility*100
) %>%
arrange(volatility) %>%
select(-volatility) %>%
gt() %>%
tab_header(
title = "The Most Promised Currencies",
subtitle = glue("{min(quotes_df$date)} to {max(quotes_df$date)}")
) %>%
fmt_number(
columns = c(max_price, min_price, last_price, max_min_rate, `100x Volatility`)
)
The Most Promised Currencies | |||||
---|---|---|---|---|---|
2011-09-01 to 2021-08-30 | |||||
symbol | max_price | min_price | last_price | max_min_rate | 100x Volatility |
USD/AED | 3.67 | 3.67 | 3.67 | 1.00 | 0.01 |
USD/HKD | 7.85 | 7.75 | 7.79 | 1.01 | 0.03 |
USD/CNY | 7.18 | 6.03 | 6.47 | 1.19 | 0.23 |
USD/SGD | 1.46 | 1.20 | 1.34 | 1.21 | 0.33 |
USD/EUR | 0.96 | 0.70 | 0.85 | 1.38 | 0.51 |
USD/JPY | 125.63 | 75.74 | 109.90 | 1.66 | 0.55 |
USD/GBP | 0.87 | 0.58 | 0.73 | 1.49 | 0.55 |
USD/AUD | 1.74 | 0.93 | 1.37 | 1.88 | 0.63 |
USD/SEK | 10.44 | 6.29 | 8.62 | 1.66 | 0.64 |
USD/CHF | 1.03 | 0.79 | 0.92 | 1.31 | 0.64 |
USD/MXN | 25.34 | 11.98 | 20.14 | 2.11 | 0.80 |
USD/KZT | 454.34 | 174.15 | 427.18 | 2.61 | 0.84 |
USD/TRY | 8.78 | 1.71 | 8.38 | 5.12 | 0.97 |
USD/RUB | 82.90 | 28.79 | 73.50 | 2.88 | 1.05 |
USD/BYN | 3.08 | 0.51 | 2.51 | 6.04 | 1.37 |
Plot exchange rate for out favorites:
Define low risk symbols:
usdrub_vol <- quotes_stats %>% filter(symbol == "USD/RUB") %>% pull(volatility)
low_risk_symbols <- quotes_stats %>%
filter(
symbol %in% symbols &
volatility <= usdrub_vol
) %>%
pull(symbol) %>%
unique
cat(
sprintf(
"['%s']",
paste(low_risk_symbols, collapse = "', '")
))
## ['USD/AED', 'USD/AUD', 'USD/CHF', 'USD/CNY', 'USD/EUR', 'USD/GBP', 'USD/HKD', 'USD/JPY', 'USD/KZT', 'USD/MXN', 'USD/RUB', 'USD/SEK', 'USD/SGD', 'USD/TRY']
jumper_symbols <- quotes_stats %>% filter(max_min_rate > 2) %>% pull(symbol)
quotes_df %>%
filter(symbol %in% low_risk_symbols) %>%
mutate(
jumper = if_else(symbol %in% jumper_symbols, "High risk currencies", "Low risk currencies")
) %>%
group_by(symbol) %>%
mutate(R = cumsum(return)) %>%
ggplot +
geom_line(aes(x = date, y = R, color = symbol)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
facet_grid(jumper ~ ., scales = "free") +
labs(
title = "Currencies Exchange Rates", subtitle = "Return of Investment for last 10 years",
x = "", y = "Return of Investment",
caption = currencies_ds$description) +
theme_minimal() +
theme(
legend.position = "top", legend.title = element_blank(),
plot.caption = element_text(size = 8)
)