1. Import Data

stock_data <- read.csv("20261004120300_hw3(20261004120300_hw3)-2.csv")

head(stock_data)
##                      CO_ID      Date    Open    High     Low    Close
## 1                 0053 PTE 10/4/2024 95.4244 95.4244 94.4654  94.4654
## 2 0050 Yuanta Taiwan Top50 10/4/2024 44.1573 44.4692 43.9173  44.0613
## 3                 0056 PTD 10/4/2024 31.0855 31.1824 30.8513  30.9644
## 4                 0051 TMT 10/4/2024 76.4016 76.4016 74.9954  75.2767
## 5      0057 FB MSCI Taiwan 10/4/2024   136.2  136.95   135.7 135.7000
## 6       0052 FB Technology 10/4/2024  24.566 24.7366 24.3681  24.4636
str(stock_data)
## 'data.frame':    1048575 obs. of  6 variables:
##  $ CO_ID: chr  "0053 PTE" "0050 Yuanta Taiwan Top50" "0056 PTD" "0051 TMT" ...
##  $ Date : chr  "10/4/2024" "10/4/2024" "10/4/2024" "10/4/2024" ...
##  $ Open : chr  "95.4244" "44.1573" "31.0855" "76.4016" ...
##  $ High : chr  "95.4244" "44.4692" "31.1824" "76.4016" ...
##  $ Low  : chr  "94.4654" "43.9173" "30.8513" "74.9954" ...
##  $ Close: num  94.5 44.1 31 75.3 135.7 ...

2. Data Preparation

stock_data$Date <- as.Date(stock_data$Date, format = "%m/%d/%Y")

stock_data$Open <- parse_number(stock_data$Open)
## Warning: 95635 parsing failures.
##  row col expected actual
## 2839  -- a number      .
## 2841  -- a number      .
## 2843  -- a number      .
## 2844  -- a number      .
## 2845  -- a number      .
## .... ... ........ ......
## See problems(...) for more details.
stock_data$High <- parse_number(stock_data$High)
## Warning: 95637 parsing failures.
##  row col expected actual
## 2839  -- a number      .
## 2841  -- a number      .
## 2843  -- a number      .
## 2844  -- a number      .
## 2845  -- a number      .
## .... ... ........ ......
## See problems(...) for more details.
stock_data$Low  <- parse_number(stock_data$Low)
## Warning: 95637 parsing failures.
##  row col expected actual
## 2839  -- a number      .
## 2841  -- a number      .
## 2843  -- a number      .
## 2844  -- a number      .
## 2845  -- a number      .
## .... ... ........ ......
## See problems(...) for more details.
str(stock_data)
## 'data.frame':    1048575 obs. of  6 variables:
##  $ CO_ID: chr  "0053 PTE" "0050 Yuanta Taiwan Top50" "0056 PTD" "0051 TMT" ...
##  $ Date : Date, format: "2024-10-04" "2024-10-04" ...
##  $ Open : num  95.4 44.2 31.1 76.4 136.2 ...
##   ..- attr(*, "problems")= tibble [95,635 × 4] (S3: tbl_df/tbl/data.frame)
##   .. ..$ row     : int [1:95635] 2839 2841 2843 2844 2845 2846 2847 2848 2849 2850 ...
##   .. ..$ col     : int [1:95635] NA NA NA NA NA NA NA NA NA NA ...
##   .. ..$ expected: chr [1:95635] "a number" "a number" "a number" "a number" ...
##   .. ..$ actual  : chr [1:95635] "." "." "." "." ...
##  $ High : num  95.4 44.5 31.2 76.4 137 ...
##   ..- attr(*, "problems")= tibble [95,637 × 4] (S3: tbl_df/tbl/data.frame)
##   .. ..$ row     : int [1:95637] 2839 2841 2843 2844 2845 2846 2847 2848 2849 2850 ...
##   .. ..$ col     : int [1:95637] NA NA NA NA NA NA NA NA NA NA ...
##   .. ..$ expected: chr [1:95637] "a number" "a number" "a number" "a number" ...
##   .. ..$ actual  : chr [1:95637] "." "." "." "." ...
##  $ Low  : num  94.5 43.9 30.9 75 135.7 ...
##   ..- attr(*, "problems")= tibble [95,637 × 4] (S3: tbl_df/tbl/data.frame)
##   .. ..$ row     : int [1:95637] 2839 2841 2843 2844 2845 2846 2847 2848 2849 2850 ...
##   .. ..$ col     : int [1:95637] NA NA NA NA NA NA NA NA NA NA ...
##   .. ..$ expected: chr [1:95637] "a number" "a number" "a number" "a number" ...
##   .. ..$ actual  : chr [1:95637] "." "." "." "." ...
##  $ Close: num  94.5 44.1 31 75.3 135.7 ...

3. Data Overview

dim(stock_data)
## [1] 1048575       6
names(stock_data)
## [1] "CO_ID" "Date"  "Open"  "High"  "Low"   "Close"
min(stock_data$Date, na.rm = TRUE)
## [1] "2024-10-04"
max(stock_data$Date, na.rm = TRUE)
## [1] "2026-01-20"
length(unique(stock_data$CO_ID))
## [1] 3599

4. Company Summary

company_summary <- stock_data %>%
  group_by(CO_ID) %>%
  summarise(
    Observations = n(),
    First_Date = min(Date, na.rm = TRUE),
    Last_Date = max(Date, na.rm = TRUE),
    Average_Close = mean(Close, na.rm = TRUE),
    Min_Close = min(Close, na.rm = TRUE),
    Max_Close = max(Close, na.rm = TRUE),
    .groups = "drop"
  )

head(company_summary, 20)
## # A tibble: 20 × 7
##    CO_ID    Observations First_Date Last_Date  Average_Close Min_Close Max_Close
##    <chr>           <int> <date>     <date>             <dbl>     <dbl>     <dbl>
##  1 0050 Yu…          317 2024-10-04 2026-01-20         50.6      35.6      71.2 
##  2 0051 TMT          317 2024-10-04 2026-01-20         77.9      55.8     103.  
##  3 0052 FB…          317 2024-10-04 2026-01-20         28.5      19.2      41.6 
##  4 0053 PTE          316 2024-10-04 2026-01-19        109.       73.9     157.  
##  5 0055 PTF          317 2024-10-04 2026-01-20         28.1      23.2      32.5 
##  6 0056 PTD          316 2024-10-04 2026-01-19         31.5      24.5      35.7 
##  7 0057 FB…          317 2024-10-04 2026-01-20        153.      110.      211.  
##  8 0061 PW…          317 2024-10-04 2026-01-20         20.1      17.4      26.5 
##  9 006201 …          317 2024-10-04 2026-01-20         21.6      14.9      28.2 
## 10 006203 …          316 2024-10-04 2026-01-19         93.1      66.1     129.  
## 11 006204 …          316 2024-10-04 2026-01-19        119.       86.3     161.  
## 12 006205 …          317 2024-10-04 2026-01-20         34.4      30.2      41.4 
## 13 006206 …          317 2024-10-04 2026-01-20         32.5      29.0      38.8 
## 14 006207 …          316 2024-10-04 2026-01-19         26.3      22.7      32.0 
## 15 006208 …          316 2024-10-04 2026-01-19        116.       81.5     162.  
## 16 00625K …          317 2024-10-04 2026-01-20          7.92      6.92      9.21
## 17 00631L …          317 2024-10-04 2026-01-20         11.7       5.75     19.7 
## 18 00632R …          317 2024-10-04 2026-01-20         21.2      15.0      29.6 
## 19 00633L …          317 2024-10-04 2026-01-20         42.4      33.8      56   
## 20 00634R …          316 2024-10-04 2026-01-19          3.70      3.15      4.3

5. Descriptive Statistics

summary(stock_data[, c("Open", "High", "Low", "Close")])
##       Open               High               Low               Close          
##  Min.   :    0.79   Min.   :    0.80   Min.   :    0.78   Min.   :     0.79  
##  1st Qu.:   22.32   1st Qu.:   22.59   1st Qu.:   22.01   1st Qu.:    23.92  
##  Median :   42.64   Median :   43.15   Median :   42.05   Median :    49.01  
##  Mean   :  149.23   Mean   :  150.72   Mean   :  147.73   Mean   :   945.13  
##  3rd Qu.:   99.00   3rd Qu.:   99.50   3rd Qu.:   98.50   3rd Qu.:   111.88  
##  Max.   :71340.64   Max.   :72457.58   Max.   :71223.99   Max.   :173067.45  
##  NAs    :95635      NAs    :95637      NAs    :95637

6. Daily Closing Price Visualization

selected_companies <- unique(stock_data$CO_ID)[1:5]

sample_data <- stock_data %>%
  filter(CO_ID %in% selected_companies)

ggplot(sample_data,
       aes(x = Date, y = Close, color = CO_ID)) +
  geom_line(linewidth = 0.7) +
  labs(
    title = "Daily Closing Prices of Selected Taiwan Stocks",
    x = "Date",
    y = "Closing Price",
    color = "Stock"
  ) +
  theme_minimal()

## 7. Daily Returns

stock_return <- stock_data %>%
  arrange(CO_ID, Date) %>%
  group_by(CO_ID) %>%
  mutate(
    Daily_Return = Close / lag(Close) - 1
  ) %>%
  ungroup()

head(stock_return)
## # A tibble: 6 × 7
##   CO_ID                    Date        Open  High   Low Close Daily_Return
##   <chr>                    <date>     <dbl> <dbl> <dbl> <dbl>        <dbl>
## 1 0050 Yuanta Taiwan Top50 2024-10-04  44.2  44.5  43.9  44.1    NA       
## 2 0050 Yuanta Taiwan Top50 2024-10-07  44.6  45.2  44.6  45.2     0.0248  
## 3 0050 Yuanta Taiwan Top50 2024-10-08  44.9  45.0  44.5  44.9    -0.00478 
## 4 0050 Yuanta Taiwan Top50 2024-10-09  45.4  45.6  45.4  45.4     0.00935 
## 5 0050 Yuanta Taiwan Top50 2024-10-11  45.4  46.3  45.4  46.1     0.0167  
## 6 0050 Yuanta Taiwan Top50 2024-10-14  46.1  46.3  45.8  46.1     0.000781
return_summary <- stock_return %>%
  group_by(CO_ID) %>%
  summarise(
    Average_Return = mean(Daily_Return, na.rm = TRUE),
    Volatility = sd(Daily_Return, na.rm = TRUE),
    .groups = "drop"
  )

head(return_summary, 20)
## # A tibble: 20 × 3
##    CO_ID                       Average_Return Volatility
##    <chr>                                <dbl>      <dbl>
##  1 0050 Yuanta Taiwan Top50         0.00163       0.0148
##  2 0051 TMT                         0.00108       0.0141
##  3 0052 FB Technology               0.00182       0.0164
##  4 0053 PTE                         0.00176       0.0169
##  5 0055 PTF                         0.000666      0.0108
##  6 0056 PTD                         0.000514      0.0113
##  7 0057 FB MSCI Taiwan              0.00151       0.0149
##  8 0061 PWC300                      0.0000162     0.0153
##  9 006201 Yuanta TW TPEx 50         0.000831      0.0171
## 10 006203 Yuanta MSCI TW ETF        0.00149       0.0149
## 11 006204 SinoPac TAIEX ETF         0.00134       0.0138
## 12 006205 FB SSE180                 0.000310      0.0117
## 13 006206 YT SSE50                  0.000157      0.0116
## 14 006207 Fuh Hwa CSI 300           0.000368      0.0129
## 15 006208 FB TW50                   0.00161       0.0149
## 16 00625K FB SSE180+R               0.000629      0.0106
## 17 00631L T50Bull2X                 0.00247       0.0293
## 18 00632R T50Bear1X                -0.00136       0.0144
## 19 00633L Fubon SSE180 L2X ETF     -0.0000220     0.0222
## 20 00634R FubonSSE180 INVR.ETF     -0.000344      0.0107

8. Conclusion

This report analyzes daily stock prices of companies listed in the Taiwan stock market.

The dataset contains daily Open, High, Low, and Close prices for 3,599 stocks. The data were cleaned and converted into appropriate formats in R.

Descriptive statistics were calculated for stock prices. Daily closing price trends were also visualized for selected stocks. In addition, daily returns and volatility were calculated to provide further information about stock price movements.