## Question 2

# URL of the CSV file
url <- "https://s3.us-east-2.amazonaws.com/artificium.us/datasets/financial_portfolio_data.csv"

# Read the CSV file into a data frame
df <- read.csv(url, stringsAsFactors = FALSE)

# Show the first five rows of df
head(df, 5)
## Question 3

# Convert Date column from chr to Date
df$Date <- as.Date(df$Date)

# Show the updated first five rows of df
head(df, 5)
## Question 4

# Extract rows with Bond B
bond_b_rows <- which(df$Asset == "Bond B")
df.B <- df[bond_b_rows, ]

# Sort the subset by Date in ascending order
df.B <- df.B[order(df.B$Date), ]

# Show the least recent data
head (df.B, 5)
## Question 5

# Add a new Month column to df.B
df.B$Month <- as.numeric(format(df.B$Date, "%m"))

# Show numeric Month column in df.B
head(df.B, 5)
## Question 6

# Calculate the monthly average price of Bond B transactions
df.Monthly <- sqldf("SELECT Month, AVG(Price) AS `AvgPrice`
                     FROM `df.B`
                     GROUP BY Month
                     ORDER BY Month")

# Show averaged Bond B prices per month in a table
head(df.Monthly, 5)
## Question 7

# Create a vector for the months (1-12)
months_numeric <- 1:12

# Create a vector for the average prices
avg_prices <- df.Monthly$AvgPrice

# Plot the monthly average price with month labels
plot(months_numeric, avg_prices, 
     type = "o",
     col = "darkorange",
     xlab = "Month (1-12)",
     ylab = "Average Price ($)",
     main = "Monthly Average Price of Bond B",
     pch = 19)

# Set x-axis labels
axis(1, at = months_numeric, labels = months_numeric)

## Question 8

# Define the weights for the WMA 
weights <- c(0.2, 0.3, 0.5)

# Calculate the Weighted Moving Average
wma <- TTR::WMA(avg_prices, n = length(weights), wts = weights)

# Forecast using the last value of WMA
forecast.val <- tail(wma, 1)

# Show the forecasted value for the next month
print(forecast.val)
## [1] 282.1885
## Question 9

# Define the weights for the WMA (3-period example)
w <- c(0.2, 0.3, 0.5)

# Calculate forecast for each prior time period
df.Monthly$WMA <- TTR::WMA(avg_prices, 
                                 n = 3, 
                                 weights = w)

periods <- nrow(df.Monthly)

# Calculate the absolute errors
for (t in 3:periods) {
  df.Monthly$abs.err[t] <- abs(df.Monthly$WMA[t-1] - df.Monthly$WMA[t])
}

# Calculate mean of absolute errors (MAE)
MAE.WMA <- mean(df.Monthly$abs.err, na.rm = TRUE)

# Show MAE and forecasts with absolute error
print(MAE.WMA)
## [1] 22.78582
print(df.Monthly)
##    Month AvgPrice      WMA   abs.err
## 1      1 297.4357       NA        NA
## 2      2 317.4233       NA        NA
## 3      3 266.3863 288.5735        NA
## 4      4 269.3782 276.3884 12.185125
## 5      5 326.7325 297.5567 21.168289
## 6      6 375.9030 341.7587 44.202011
## 7      7 226.1575 292.8352 48.923530
## 8      8 280.6593 278.3660 14.469190
## 9      9 311.6131 287.0526  8.686574
## 10    10 255.4080 278.3516  8.700977
## 11    11 335.8140 304.9785 26.626940
## 12    12 260.7255 284.8687 20.109786
## Question 10

# Assign quarters based on the month
# Assumed that the instructions were incorrectly categorizing months into trimesters instead of quarters
df.Monthly$Quarter <- ifelse(df.Monthly$Month %in% 1:3, "Q1",
                              ifelse(df.Monthly$Month %in% 4:6, "Q2",
                                     ifelse(df.Monthly$Month %in% 7:9, "Q3", "Q4")))

# Dummy-coded columns
df.Monthly$Q1 <- ifelse(df.Monthly$Quarter == "Q1", 1, 0)
df.Monthly$Q2 <- ifelse(df.Monthly$Quarter == "Q2", 1, 0)
df.Monthly$Q3 <- ifelse(df.Monthly$Quarter == "Q3", 1, 0)
# Q4 is not any of the previous three quarters

# Additive seasonality, adjusted linear regression trend forecasting model
trend.model.adjusted <- lm(
  df.Monthly$AvgPrice ~ df.Monthly$Month + 
    df.Monthly$Q1 +
    df.Monthly$Q2 +
    df.Monthly$Q3
)

# Print the trend model sumamry
summary(trend.model.adjusted)
## 
## Call:
## lm(formula = df.Monthly$AvgPrice ~ df.Monthly$Month + df.Monthly$Q1 + 
##     df.Monthly$Q2 + df.Monthly$Q3)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -48.143 -27.865   5.289  23.873  51.832 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)
## (Intercept)         55.39     158.25   0.350    0.737
## df.Monthly$Month    20.78      14.23   1.460    0.188
## df.Monthly$Q1      196.80     132.22   1.488    0.180
## df.Monthly$Q2      164.71      91.49   1.800    0.115
## df.Monthly$Q3       51.17      53.88   0.950    0.374
## 
## Residual standard error: 40.25 on 7 degrees of freedom
## Multiple R-squared:  0.4076, Adjusted R-squared:  0.06906 
## F-statistic: 1.204 on 4 and 7 DF,  p-value: 0.3883
# Print the updated data frame
print(df.Monthly)
##    Month AvgPrice      WMA   abs.err Quarter Q1 Q2 Q3
## 1      1 297.4357       NA        NA      Q1  1  0  0
## 2      2 317.4233       NA        NA      Q1  1  0  0
## 3      3 266.3863 288.5735        NA      Q1  1  0  0
## 4      4 269.3782 276.3884 12.185125      Q2  0  1  0
## 5      5 326.7325 297.5567 21.168289      Q2  0  1  0
## 6      6 375.9030 341.7587 44.202011      Q2  0  1  0
## 7      7 226.1575 292.8352 48.923530      Q3  0  0  1
## 8      8 280.6593 278.3660 14.469190      Q3  0  0  1
## 9      9 311.6131 287.0526  8.686574      Q3  0  0  1
## 10    10 255.4080 278.3516  8.700977      Q4  0  0  0
## 11    11 335.8140 304.9785 26.626940      Q4  0  0  0
## 12    12 260.7255 284.8687 20.109786      Q4  0  0  0
## Question 11

# Pull values from adjusted trend model
b <- trend.model.adjusted$coefficients[[1]]   # intercept
t <- trend.model.adjusted$coefficients[[2]]   # time period coefficient
Q1 <- trend.model.adjusted$coefficients[[3]]  # Q1 coefficient
Q2 <- trend.model.adjusted$coefficients[[4]]  # Q2 coefficient
Q3 <- trend.model.adjusted$coefficients[[5]]  # Q3 coefficient

# Next month prediction (January = month 13 = Q1)
F.13 <- (t * 13) + b + (Q1*1) + (Q2*0) + (Q3*0) 

# Show Month 13 predicted value
print(F.13)
## [1] 522.34