You are on page 1of 30

UEH UNIVERSITY

UEH COLLEGE OF TECHNOLOGY AND DESIGN


UEH INSTITUTE OF INNOVATION

ĐỒ ÁN CUỐI KỲ
Môn học: Lập trình căn bản

ĐỀ TÀI: PHÂN TÍCH VÀ DỰ ĐOÁN THỊ TRƯỜNG


CHỨNG KHOÁN BẰNG PHƯƠNG PHÁP HỒI QUY
TUYẾN TÍNH

Giáo viên hướng dẫn: Ngô Hiếu Trường


Mã học phần: 24D1TEC55001903
Nhóm trưởng: Lưu Phan Bình Thy - MSSV: 31231025476
DANH SÁCH THÀNH VIÊN VÀ NHIỆM VỤ

Họ tên MSSV Nhiệm vụ nhóm giao Mức độ Trưởng


hoàn nhóm đánh
thành (%) giá (%)
Lưu Phan Bình 31231025476 Viết báo cáo, chỉnh 100 100
Thy sửa chung
Nguyễn Võ 31231025613 Đào tạo mô hình 99 100
Hoàng Nhật
Nguyễn Thị 31231026786 Viết báo cáo, làm slide 97 100
Trúc Vy thuyết trình
Lương Thanh 31231021845 Đào tạo mô hình, viết 100 100
Trúc báo cáo
Đỗ Lê Phúc 31231020173 Viết báo cáo, làm slide 95 100
Đức thuyết trình
Trần Trọng 31231024329 Viết báo cáo, làm slide 90 100
Nguyễn thuyết trình

2
MỤC LỤC
DANH MỤC BẢNG BIỂU...................................................................................................................
CHƯƠNG 1. TỔNG QUAN ĐỀ TÀI..................................................................................................
1.1. Giới thiệu đề tài...........................................................................................................................
1.2. Phương pháp nghiên cứu.............................................................................................................
CHƯƠNG 2. HIỆN THỰC ĐỀ TÀI....................................................................................................
2.1. Mô tả thuật toán...........................................................................................................................
2.1.1. Nhập các thư viện cần thiết................................................................................................
2.1.2. Lấy dữ liệu và chuyển dữ liệu thành bảng hoàn chỉnh.......................................................
2.1.2.1 Lấy dữ liệu về giá cổ phiếu........................................................................................
2.1.2.2. Chuyển dữ liệu thành bảng dữ liệu hoàn chỉnh..........................................................
2.1.3. Khởi tạo danh sách cổ phiếu, thiết lập thời gian và tải dữ liệu cổ phiếu............................
2.1.3.1. Khởi tạo danh sách cổ phiếu......................................................................................
2.1.3.2. Kết hợp dữ liệu và mô tả dữ liệu................................................................................
2.1.3.3. Chuẩn hóa dữ liệu......................................................................................................
2.1.4. Chia dữ liệu theo dãy thời gian thành các tập huấn luyện và kiểm thử..............................
2.1.5. Tính hệ số và điểm giao của đường thẳng tuyến tính.........................................................
2.1.6. Vẽ biểu đồ scatter plot và đường thẳng tuyến tính.............................................................
2.1.7. Vẽ biểu đồ thể hiện Closing price......................................................................................
2.1.8. Vẽ biểu đồ số lượng giao dịch............................................................................................
2.1.9. Vẽ đường trung bình động.................................................................................................
2.1.10. Chia dữ liệu thành tập huấn luyện và tập kiểm tra...........................................................
2.1.11. Tạo và huấn luyện mô hình..............................................................................................
2.1.12. Dự đoán và đánh giá.........................................................................................................
2.1.13. Trực quan hóa dữ liệu (Vẽ biểu đồ).................................................................................
2.1.14. Xây dựng mô hình Random Forest..................................................................................
2.1.15. Các số đo đánh giá mô hình.............................................................................................
2.2. Tổng hợp các kết quả (Biểu đồ)..................................................................................................
CHƯƠNG 3. KẾT QUẢ VÀ HƯỚNG PHÁT TRIỂN......................................................................
3.1. Kết quả nghiên cứu.....................................................................................................................
3.2. Hạn chế đề tài..............................................................................................................................
3.3. Hướng phát triển đề tài................................................................................................................
3.4. Kịch bản demo............................................................................................................................
TÀI LIỆU THAM KHẢO....................................................................................................................

3
DANH MỤC BẢNG BIỂU

Bảng 1. Model Summary

Bảng 2. Bảng biểu thị giá đóng cửa đã được điều chỉnh của Apple

Bảng 3. Bảng số lượng giao dịch trong ngày của Apple

Bảng 4. Bảng đường trung bình động (MA)

Bảng 5. Phân tích và dự đoán giá cổ phiếu AAPL

4
CHƯƠNG 1. TỔNG QUAN ĐỀ TÀI
1.1. Giới thiệu đề tài

Đầu tư chứng khoán là một trong những xu hướng kiếm tiền khá phổ biến hiện nay
với đa dạng các cổ phiếu, trái phiếu, quỹ mở,... từ các công ty trên toàn cầu. Và các
sàn giao dịch chứng khoán luôn được cho là rất khó dự đoán cũng như có rất nhiều rủi
ro bất ngờ khi đầu tư với số tiền lớn. Chính vì vậy mà các bài toán về việc dự đoán xu
hướng của thị trường chứng khoán luôn là điểm quan tâm của các nhà đầu tư, các
chuyên gia kinh tế học. Và một trong những lý do khiến thị trường chứng khoán thu
hút nhiều sự quan tâm đến từ các nhà đầu tư hay các chuyên gia kinh tế chính bởi sự
phát triển vô cùng mạnh mẽ của nó. Đồng thời, sự phát triển nhanh chóng của công
nghệ thông tin giúp cho việc giao dịch và lưu trữ dữ liệu chứng khoán trở nên ngày
một dễ dàng hơn. Người dùng có thể dễ dàng tra cứu xu hướng tăng giảm của các mã
cổ phiếu mà họ quan tâm một cách thường xuyên và dễ dàng.

Dự báo giá cổ phiếu luôn là một bài toán đau đầu của rất nhiều người vì sự khó đoán
của nó. Nhưng ngày nay với các dữ liệu khổng lồ được khai thác từ các sàn giao dịch
đã phần nào giúp cho việc nghiên cứu và dự đoán xu hướng tăng giảm của các mã cổ
phiếu trở nên thuận tiện hơn. Bằng sự phân tích kỹ lưỡng qua các thông số thống kê từ
giá cổ phiếu phản ánh được xu hướng vận động quan trọng của chứng khoán. Từ xu
hướng vận động đó, chúng ta có thể đánh giá các dữ liệu một cách hiệu quả hơn. Và
một trong những khó khăn của việc dự đoán giá cổ phiếu chính là sự tác động từ nhiều
yếu tố bên ngoài cũng như bị ảnh hưởng bởi nền kinh tế ở mỗi khu vực và quốc gia
khác nhau. Và bằng việc nghiên cứu, nhìn nhận và phân tích thị trường cũng là một
trong những yếu tố quan trọng trong việc phân tích chứng khoán và đưa ra những
nhận định phù hợp với tình thời điểm giúp các nhà đầu tư có thêm những cái nhìn khái
quát hơn về xu hướng tăng hay giảm của cổ phiếu.

1.2. Phương pháp nghiên cứu

Thị trường chứng khoán được nhìn nhận là một kênh đầu tư cực kỳ tiềm năng hiện
nay, nơi cung cấp các sản phẩm đầu tư phong phú, giúp giảm thiểu rủi ro nhờ sự đa
dạng hóa danh mục đầu tư.

Mô hình hồi quy tuyến tính là một công cụ đơn giản với các ứng dụng trong nhiều lĩnh
vực không chỉ trong lĩnh vực thống kê mà trong tất cả các lĩnh vực cần quan tâm đến
ước lượng và dự báo, đặc biệt đối với các nghiên cứu trong lĩnh vực chứng khoán.

5
Phương pháp Hồi quy tuyến tính:

Hồi quy tuyến tính là một kỹ thuật phân tích dữ liệu dự đoán giá trị của dữ liệu không
xác định bằng cách sử dụng giá trị dữ liệu liên quan và đã biết khác. Nó mô hình hóa
toán học biến không xác định hoặc phụ thuộc và biến đã biết hoặc độc lập như một
phương trình tuyến tính. Ở đồ án này, kỹ thuật Hồi quy tuyến tính phân tích dữ liệu là
giá cổ phiếu trong quá khứ để dự đoán giá cổ phiếu của tương lai.

Các mô hình hồi quy tuyến tính tương đối đơn giản và cung cấp một công thức toán
học dễ giải thích để đưa ra các dự đoán. Hồi quy tuyến tính là một kỹ thuật thống kê
được sử dụng từ lâu và áp dụng dễ dàng cho phần mềm và tính toán. Các doanh
nghiệp sử dụng nó để chuyển đổi dữ liệu thô một cách đáng tin cậy và có thể dự đoán
được thành nghiệp vụ thông minh và thông tin chuyên sâu hữu ích. Các nhà khoa học
trong nhiều lĩnh vực, bao gồm sinh học và các ngành khoa học hành vi, môi trường, và
xã hội, sử dụng hồi quy tuyến tính để tiến hành phân tích dữ liệu sơ bộ và dự đoán các
xu hướng tương lai. Nhiều phương pháp khoa học dữ liệu, chẳng hạn như máy học và
trí tuệ nhân tạo, sử dụng hồi quy tuyến tính để giải quyết các bài toán phức tạp.

Công thức chung của của phương trình Hồi quy tuyến tính là Y = a + bX, trong đó Y
là biến phụ thuộc, X là biến độc lập, a là hệ số góc (hằng số) và b là hệ số chặn (biến
số). Để tìm giá trị a, ta chia hiệp phương sai của X và Y cho phương sai của X. Để tìm
b, ta lấy giá trị trung bình của Y trừ đi tích của hệ số góc và giá trị trung bình của X.
Sau khi tìm được hệ số a, b, ta sử dụng phương trình hồi quy để dự đoán giá trị của
biến phụ thuộc (Y) dựa trên giá trị của biến độc lập (X).

6
CHƯƠNG 2. HIỆN THỰC ĐỀ TÀI
2.1. Mô tả thuật toán

2.1.1. Nhập các thư viện cần thiết


import yfinance as yf
import datetime as dt
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from numpy import arange
from pandas import read_csv
from sklearn import metrics
from sklearn.model_selection import TimeSeriesSplit
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import confusion_matrix, accuracy_score
from pandas_datareader.data import DataReader
from pandas_datareader import data as pdr
from datetime import datetime
Các thư viện nhóm đã sử dụng:
● import yfinance as yf: tải dữ liệu tài chính.
● import datetime as dt: xử lý ngày tháng và thời gian
● import pandas as pd: thư viện pandas để thao tác và phân tích dữ liệu.
● import numpy as np: thư viện numpy để thực hiện tính toán số
● import seaborn as sns: tạo biểu đồ thống kê.
● import matplotlib.pyplot as plt: tạo biểu đồ.
● from numpy import arange: tạo ra các giá trị cách đều nhau trong một khoảng
cụ thể.
● from pandas import read_csv: đọc dữ liệu từ file CSV.
● from sklearn import metrics: đánh giá hiệu suất mô hình.
● from sklearn.model_selection import TimeSeriesSplit: Import lớp
TimeSeriesSplit từ thư viện scikit-learn để tạo các tập chia theo thời gian trong
dữ liệu chuỗi thời gian cho xác thực chéo.

7
● from sklearn.ensemble import RandomForestRegressor: Import lớp
RandomForestRegressor từ thư viện scikit-learn để tạo mô hình hồi quy
● from sklearn.preprocessing import MinMaxScaler: Import lớp MinMaxScaler
từ thư viện scikit-learn để chuẩn hóa dữ liệu giữa 0 và 1.
● from sklearn.model_selection import RandomizedSearchCV: Import lớp
RandomizedSearchCV từ thư viện scikit-learn để thực hiện điều chỉnh siêu
tham số ngẫu nhiên.
● from sklearn.linear_model import LinearRegression: Import lớp
LinearRegression từ mô-đun linear_model của thư viện scikit-learn để xây
dựng mô hình hồi quy tuyến tính.
● from sklearn.metrics import confusion_matrix, accuracy_score: Import các
hàm confusion_matrix và accuracy_score từ mô-đun metrics của thư viện
scikit-learn.
● confusion_matrix: Tính toán ma trận nhiễu loạn (confusion matrix) để
đánh giá hiệu suất của mô hình phân loại.
● accuracy_score: Tính toán độ chính xác (accuracy) của mô hình phân
loại.
● from pandas_datareader.data import DataReader: Import hàm DataReader từ
mô-đun data của thư viện pandas_datareader để tải dữ liệu tài chính từ các
nguồn trực tuyến.
● from pandas_datareader import data as pdr: Import alias pdr cho mô-đun data
của thư viện pandas_datareader giúp sử dụng cú pháp pdr.DataReader thay cho
pandas_datareader.data.DataReader.
● from datetime import datetime: Import datetime từ thư viện datetime để làm
việc với ngày tháng và thời gian.

2.1.2. Lấy dữ liệu và chuyển dữ liệu thành bảng hoàn chỉnh

2.1.2.1 Lấy dữ liệu về giá cổ phiếu


start_date = input("Nhập ngày bắt đầu lấy dữ liệu (yyyy-mm-dd): ")
end_date = dt.datetime.now().strftime("%Y-%m-%d")
data = yf.download("AAPL", start = start_date, end = end_date)
print("Dữ liệu chứng khoán AAPL từ ngày ",start_date," đến ",end_date,":")
Nhóm đã thực hiện:
● Lấy dữ liệu (do người dùng nhập) ngày bắt đầu và lưu vào biến start_date, dữ
liệu kết thúc là thời gian hiện tại và lưu vào biến end_date.
● Dùng hàm yf.download để tải dữ liệu chứng khoán của Apple (AAPL) từ
Yahoo Finance và lưu trữ dữ liệu trong biến data.

8
2.1.2.2. Chuyển dữ liệu thành bảng dữ liệu hoàn chỉnh
sp500_df = pd.DataFrame(data)
sp500_df.to_csv("data.csv")
read_df = pd.read_csv("data.csv")
read_df.set_index("Date", inplace=True)
print(read_df.head())
Nhóm đã thực hiện các lệnh: Tạo DataFrames: sp500_df = pd.DataFrame(data) và
chuyển đổi dữ liệu trong biến data thành một DataFrame (một cấu trúc dữ liệu dạng
bảng hai chiều, tương tự như một bảng tính) của thư viện pandas, lưu trữ trong biến
sp500_df
● Lưu trữ dữ liệu vào một file CSV tên "data.csv": sp500_df.to_csv("data.csv")
● read_df = pd.read_csv("data.csv") sử dụng để đọc dữ liệu từ file CSV
"data.csv", lưu trữ vào file read_df.
● Thiết lập cột "Date" (Ngày) làm chỉ mục (index) của DataFrame để dễ dàng
truy cập dữ liệu theo ngày
● In ra 5 dòng đầu tiên để kiểm tra nhanh nội dung dữ liệu
(kết quả)

read_df.interpolate()
Nội suy dữ liệu để điền vào những chỗ còn thiếu trong DataFrame

x = read_df[['Open','High','Low']]
y = read_df['Close']
Chọn biến x làm biến độc lập, khởi tạo danh sách gồm các giá trị "Open" (Giá mở
cửa), "High" (Giá cao nhất), và "Low" (Giá thấp nhất) và lưu vào biến x. Chọn biến y
làm biến phụ thuộc. Danh sách gồm giá trị Close và lưu vào biến y.

2.1.3. Khởi tạo danh sách cổ phiếu, thiết lập thời gian và tải dữ liệu cổ phiếu

2.1.3.1. Khởi tạo danh sách cổ phiếu


tech_list = ['AAPL']
for stock in tech_list:
globals()[stock] = yf.download(stock, start_date, end_date)
company_list = [AAPL]
company_name = ["AAPL"]

9
for company, com_name in zip(company_list, company_name):
company["company_name"] = com_name
Nhóm khởi tạo danh sách tech_list chứa tên mã cổ phiếu “AAPL” (Apple). Nhóm
dùng vòng lặp for để duyệt qua từng dữ liệu cổ phiếu, sử dụng hàm download từ thư
viện yfinance để tải dữ liệu cổ phiếu trong khoảng thời gian từ start_date đến
end_date. Sau đó, nhóm thêm tên công ty tương ứng vào DataFrame của từng cổ
phiếu: duyệt hai danh sách company_list và company_name song song bằng hàm zip,
thêm một cột mới tên “company_name” vào DataFrame và gán vào biến com_name.

2.1.3.2. Kết hợp dữ liệu và mô tả dữ liệu


df = pd.concat(company_list, axis=0)
df.tail(10)
print(AAPL.describe())
AAPL.info()
Nhóm sử dụng hàm concat từ thư viện pandas để kết hợp các DataFrame trong danh
sách company_list thành một DataFrame mới, lưu vào biến df. Sau đó, nhóm in các
thống kê dữ liệu tóm tắt (count, mean, std,...), các thông tin chi tiết (kiểu dữ liệu, số
lượng giá trị Non-Null: bao nhiêu ô chứa giá trị thực tế) của DataFrame.
Kết quả:

2.1.3.3. Chuẩn hóa dữ liệu


scaler = MinMaxScaler()
X = scaler.fit_transform(read_df[['Open', 'High', 'Low', 'Close']])
X = pd.DataFrame(columns=['Open', 'High', 'Low', 'Close'], data=X,
index=read_df.index)
print(X.head())
Vì dữ liệu có các giá trị và thang đo khác nhau nên cần phải chuẩn hóa dữ liệu, giúp
các thuật toán học máy hoạt động hiệu quả hơn. Vì vậy, nhóm đã tạo ra một đối tượng
scaler thuộc lớp MinMaxScaler để chuẩn hóa dữ liệu thành dữ liệu có giá trị trong
khoảng từ 0 đến 1.

10
Nhóm tiến hành chọn 4 cột “Open”, “High”, “Low” và “Close”; dùng phương thức
fit_transform để tính toán các tham số cần thiết cho việc chuẩn hóa dựa trên dữ liệu
đầu vào là 4 cột giá (Open, High, Low, Close); sau đó lưu trữ dữ liệu đã được chuẩn
hóa vào biến X.
Cuối cùng, nhóm tạo DataFrame mới tên X từ dữ liệu đã chuẩn hóa (giá trị nằm trong
khoảng từ 0 đến 1) với các cột như DataFrame ban đầu (Open, High, Low, Close); sử
dụng chỉ mục cho DataFrame mới để dữ liệu được chuẩn hóa giữ được mối liên hệ với
ngày tháng tương ứng trong dữ liệu gốc.
Kết quả in ra 5 dòng đầu tiên:

2.1.4. Chia dữ liệu theo dãy thời gian thành các tập huấn luyện và kiểm thử
timesplit = TimeSeriesSplit(n_splits=10)
for train_index, test_index in timesplit.split(X):
X_train, X_test = X.iloc[train_index], X.iloc[test_index]
y_train, y_test = y.iloc[train_index], y.iloc[test_index]
Đầu tiên, nhóm khởi tạo đối tượng timesplit. Lớp TimeSeriesSplit được sử dụng để
chia dữ liệu theo dãy thời gian (time series) cho việc đánh giá chéo (cross-validation)
trong các bài toán học máy. Tham số n_splits=10 thiết lập số lượng phân chia của dữ
liệu. Trong trường hợp này, dữ liệu sẽ được chia thành 10 phần.
Vòng lặp for lặp qua các cách chia dữ liệu khác nhau (10 lần). Bên trong vòng lặp, các
phần tử của DataFrame X (dữ liệu đã chuẩn hóa) và cột y (giá đóng cửa) được trích
xuất riêng rẽ cho tập huấn luyện và kiểm thử. Qua đó, mô hình có thể được huấn luyện
trên nhiều tập hợp dữ liệu con khác nhau để đánh giá hiệu suất một cách đáng tin cậy
hơn.

2.1.5. Tính hệ số và điểm giao của đường thẳng tuyến tính


x = X["Open"].values

y = X["Close"].values

N = x.shape[0]

m = (N*np.sum(x*y)-np.sum(x)*np.sum(y))/(N*np.sum(x**2)-(np.sum(x)**2))

11
b = (np.sum(y)-m*np.sum(x))/N

x_min = np.min(x)

y_min = m*x_min+b

x_max = np.max(x)

y_max = m*x_max+b

Đầu tiên, nhóm trích xuất các cột "Open" và "Close" từ DataFrame X và chuyển đổi
chúng thành mảng NumPy bằng cách sử dụng .values. Sau đó, nhóm tính toán số
lượng điểm dữ liệu (N) bằng cách truy cập chiều đầu tiên ([0]) của thuộc tính hình
dạng của mảng NumPy x.

Nhóm tiến hành tính toán các hệ số:

● Hệ số góc m: m=(N*np.sum(x*y)-np.sum(x)*np.sum(y))/(N*np.sum(x**2)-
(np.sum(x)**2)):
■ np.sum(x*y): Tính tổng tích của các phần tử tương ứng trong x
và y.
■ np.sum(x) và np.sum(y): Tính tổng các phần tử trong x và y
tương ứng.
■ np.sum(x**2): Tính tổng bình phương của các phần tử trong x.
■ N: Số lượng điểm dữ liệu (đã được tính toán trước đó).
● Hệ số chặn b:
b = (np.sum(y)-m*np.sum(x))/N:

● x_min = np.min(x): tìm giá trị tối thiểu (x_min) trong mảng x.
● y_min = m*x_min+b: tính toán tọa độ y (y_min) tương ứng với giá trị x tối
thiểu (x_min) bằng cách sử dụng phương trình đường thẳng phù hợp nhất (hệ
số góc m và hệ số chặn b).
● x_max = np.max(x): tìm giá trị tối đa (x_max) trong mảng x.
● y_max = m*x_max+b: tính toán tọa độ y (y_max) tương ứng với giá trị x tối
đa (x_max) ( công thức tương tự dòng trên)
sns.set_style('whitegrid')
plt.style.use("fivethirtyeight")

Sau đó, nhóm thiết lập phong cách trực quan tổng thể cho các biểu đồ Seaborn. Đối số
'whitegrid' được truyền vào để thiết lập thành chủ đề có nền trắng và lưới mờ.

12
Nhóm sử dụng hàm plt.style.use từ thư viện Matplotlib (Seaborn được xây dựng dựa
trên Matplotlib) để thiết lập bảng kiểu cho các biểu đồ được tạo bằng các hàm
Matplotlib, bao gồm cả các hàm được sử dụng bởi Seaborn. Đối số "fivethirtyeight"
cho biết hàm sử dụng bảng kiểu "fivethirtyeight" được thiết kế để mô phỏng phong
cách trực quan của các biểu đồ và đồ thị.

2.1.6. Vẽ biểu đồ scatter plot và đường thẳng tuyến tính


fig,ax = plt.subplots()
sns.scatterplot(
data = X,
x = "Open",
y = "Close",
ax = ax,
alpha = 0.5
)
sns.lineplot(
x = [x_min,x_max],
y = [y_min,y_max],
linewidth = 2,
color = 'red'
Đầu tiên, nhóm tạo một hình fig và một trục ax để vẽ biểu đồ. Tiếp theo, vẽ biểu đồ
Scatterplot (biểu đồ phân tán) để thể hiện mối quan hệ giữa giá mở cửa (trục hoành)
và giá đóng cửa (trục tung) dựa trên dữ liệu trong DataFrame: alpha=0.5 cho biết các
điểm dữ liệu có độ mờ 50%, cho phép thấy các điểm dữ liệu chồng lên nhau.
Sau đó, nhóm vẽ đường thẳng thể hiện đường hồi quy tuyến tính bằng cách:
● Xác định giá trị x của hai điểm đầu và cuối của đường thẳng, đường thẳng sẽ
trải dài từ giá mở cửa tối thiểu (x_min) đến giá mở cửa tối đa (x_max).
● Xác định giá trị y của hai điểm đầu và cuối của đường thẳng. Giá trị y được
tính toán dựa trên hệ số góc m và hệ số chặn b của đường hồi quy tuyến tính,
cùng với giá trị x tương ứng (x_min và x_max).
● Thiết lập độ dày và màu sắc của đường thẳng.

13
2.1.7. Vẽ biểu đồ thể hiện Closing price
plt.figure(figsize = (10, 5))
AAPL['Adj Close'].plot()
plt.ylabel('Adj Close')
plt.xlabel(None)
plt.title(f"Closing Price of AAPL")
plt.tight_layout()

Nhóm tạo một đối tượng hình ảnh mới bằng cách sử dụng hàm plt.figure. Tham số
figsize đặt kích thước của hình ảnh có chiều rộng 10 inch và chiều cao 5 inch.

Sau đó, nhóm tiến hành vẽ đường Closing price (giá đóng cửa) AAPL['Adj
Close'].plot(): vẽ cột "Adj Close" (giá đóng cửa điều chỉnh) từ DataFrame AAPL.
Hàm plot() của Matplotlib được sử dụng để tạo một biểu đồ đường, thể hiện trực quan
giá đóng cửa điều chỉnh theo thời gian.
Nhóm sử dụng những lệnh sau để cài đặt nhãn và tiêu đề:
● plt.ylabel('Adj Close'): đặt nhãn cho trục y thành "Adj Close" để biểu thị cho
giá đóng cửa điều chỉnh.
● plt.xlabel(None): đặt nhãn cho trục x thành None.

14
● plt.title(f"Closing Price of AAPL"): đặt tiêu đề cho biểu đồ bằng cách sử dụng
f-string, hiển thị "Closing Price of AAPL".
Cuối cùng, định cấu hình bố cục bằng dòng plt.tight_layout() để điều chỉnh khoảng
cách giữa các phần tử biểu đồ và các cạnh hình ảnh, ngăn các nhãn hoặc tiêu đề chồng
chéo.

2.1.8. Vẽ biểu đồ số lượng giao dịch


plt.figure(figsize = (10, 5))

AAPL['Volume'].plot()

plt.ylabel('Volume')

plt.xlabel(None)

plt.title(f"Sales Volume for AAPL")

plt.tight_layout()

Tương tự với cách vẽ ở phần trên, nhóm tạo một đối tượng hình ảnh mới bằng cách sử
dụng hàm plt.figure. Tham số figsize đặt kích thước của hình ảnh có chiều rộng 10
inch và chiều cao 5 inch.

Sau đó, nhóm tiến hành vẽ đường Volume, vẽ cột "Volume" từ DataFrame AAPL.
Hàm plot() của Matplotlib được sử dụng để tạo một biểu đồ đường, thể hiện trực quan
số lượng giao dịch.

15
Nhóm sử dụng những lệnh sau để đặt nhãn và tiêu đề:
● plt.ylabel('Volume'): đặt nhãn cho trục y thành "Volume" để biểu thị cho số
lượng giao dịch.
● plt.xlabel(None): đặt nhãn cho trục x thành None.
● plt.title(f"Sales Volume for AAPL"): đặt tiêu đề cho biểu đồ bằng cách sử dụng
f-string, hiển thị "Sales Volume for AAPL".
Cuối cùng, định cấu hình bố cục bằng dòng plt.tight_layout() để điều chỉnh khoảng
cách giữa các phần tử biểu đồ và các cạnh hình ảnh, ngăn các nhãn hoặc tiêu đề chồng
chéo.

2.1.9. Vẽ đường trung bình động

plt.figure(figsize=(10,5))

ma_day = [10, 20, 50]

for ma in ma_day:

column_name = f"MA for {ma} days"

AAPL[column_name] = AAPL['Adj Close'].rolling(ma).mean()

plt.plot(AAPL["Adj Close"], label='Adj Close')

plt.plot(AAPL["MA for 10 days"], label='MA for 10 days')

plt.plot(AAPL["MA for 20 days"], label='MA for 20 days')

16
plt.plot(AAPL["MA for 50 days"], label='MA for 50 days')

plt.xlabel('Date')

plt.ylabel('')

plt.title('APPLE')

plt.legend(loc='lower right')

plt.tight_layout()

Giải thích chi tiết các bước thực hiện:

● plt.figure(figsize = (10, 5)): sử dụng hàm plt.figure để tạo một hình vẽ mới,
tham số figsize để đặt kích thước của hình vẽ có chiều rộng 10 inches và chiều
cao là 5 inches.

● ma_day = [10, 20, 50]:chỉ định số ngày là 10 ngày, 20 ngày, 50 ngày dùng để
tính toán đường trung bình động (moving average).

for ma in ma_day:

column_name = f"MA for {ma} days"

AAPL[column_name] = AAPL['Adj Close'].rolling(ma).mean()

● for ma in ma_day: bắt đầu vòng lặp qua các số ngày trong danh sách ma_day.

● column_name = f"MA for {ma} days: tạo tên cho cột Trung bình động với số
ngày tương ứng.
● AAPL[column_name] = AAPL['Adj Close'].rolling(ma).mean(): tính toán
Trung bình động của giá chứng khoán công ty Apple trong số ngày tương ứng.
Kết quả tính được lưu vào một cột mới trong dữ liệu của Apple với tên cột
được đặt theo “column_name” ở trên.
● plt.plot(AAPL["Adj Close"], label='Adj Close'): vẽ biểu đồ đường dựa trên dữ
liệu trong cột “Adj Close” của biến “AAPL”, đặt tên cho dòng biểu đồ là “Adj
Close”.

17
● plt.plot(AAPL["MA for 10 days"], label='MA for 10 days'): vẽ biểu đồ đường
dựa trên dữ liệu trong cột “MA for 10 days” của biến “AAPL”, đặt tên cho
dòng biểu đồ là “MA for 10 days”.
● plt.plot(AAPL["MA for 20 days"], label='MA for 20 days'): vẽ biểu đồ đường
dựa trên dữ liệu trong cột “MA for 20 days” của biến “AAPL”, đặt tên cho
dòng biểu đồ là “MA for 20 days”.
● plt.plot(AAPL["MA for 50 days"], label='MA for 50 days'): vẽ biểu đồ đường
dựa trên dữ liệu trong cột “MA for 50 days” của biến “AAPL”, đặt tên cho
dòng biểu đồ là “MA for 50 days”.
● plt.xlabel('Date'): đặt tên trục X là “Date”.
● plt.ylabel(''): bỏ qua tên trục Y.
● plt.title('APPLE'): đặt tên biểu đồ là “APPLE”.
● plt.legend(loc='lower right'): tạo hộp chú thích cho các dòng của biểu đồ, đặt
hộp chú thích ở góc dưới bên phải biểu đồ.
● plt.tight_layout(): điều chỉnh các thành phần của biểu đồ không chồng lên nhau
để thẩm mĩ và dễ hiểu hơn.

2.1.10. Chia dữ liệu thành tập huấn luyện và tập kiểm tra
train_size = 0.8

num_train_data = int(len(read_df) * train_size)

18
X_train = read_df[['Open','High','Low']].iloc[:num_train_data]

y_train = read_df['Close'].iloc[:num_train_data]

Chi tiết các bước nhóm thực hiện:

● train_size = 0.8: Sử dụng 80% dữ liệu để train mô hình.


● num_train_data = int(len(read_df) * train_size): Tính số lượng dữ liệu
huấn luyện dựa trên tỷ lệ và tổng số dữ liệu.
● X_train = read_df[['Open', 'High', 'Low']].iloc[:num_train_data]: Lấy dữ
liệu huấn luyện cho các thuộc tính "Open", "High", "Low".
● y_train = read_df['Close'].iloc[:num_train_data]: Lấy dữ liệu huấn luyện
cho thuộc tính "Close" (giá đóng cửa).

Chia dữ liệu còn lại để kiểm tra (optional)


X_test = read_df[['Open','High','Low']].iloc[num_train_data:]

y_test = read_df['Close'].iloc[num_train_data:]

2.1.11. Tạo và huấn luyện mô hình


model = LinearRegression()

model.fit(X_train, y_train)

predictions = model.predict(X_test)

● model = LinearRegression() Khởi tạo mô hình hồi quy tuyến tính.


● model.fit(X_train, y_train) Huấn luyện mô hình với dữ liệu huấn luyện.
● predictions = model.predict(X_test) thực hiện việc dự đoán giá cổ phiếu
dựa trên dữ liệu test.

2.1.12. Dự đoán và đánh giá


y_predicted = model.predict(X_test)

fr_df = pd.DataFrame({"Actual": y_test, "Predicted": y_predicted})

print(fr_df.head(None))

train = read_df[:num_train_data]

19
valid = read_df[num_train_data:]

● y_predicted = model.predict(X_test): Dự đoán giá cổ phiếu dựa trên dữ


liệu test.
● fr_df = pd.DataFrame({"Actual": y_test, "Predicted": y_predicted}):
Tạo DataFrame để so sánh giá thực tế và dự đoán.
● print(fr_df.head()): Hiển thị 5 dòng đầu tiên của DataFrame để đánh giá.

Lưu trữ dữ liệu:

● train = read_df[:num_train_data]: Lưu trữ dữ liệu huấn luyện.


● valid = read_df[num_train_data:]: Lưu trữ dữ liệu kiểm tra (tùy chọn).

2.1.13. Trực quan hóa dữ liệu (Vẽ biểu đồ)


plt.figure(figsize = (18,7))

plt.title('Phân Tích & Dự Đoán Giá Cổ Phiếu AAPL'),

plt.xlabel('Date', fontsize = 16)

plt.ylabel('Close Price USD ($)', fontsize = 16)

plt.plot(train['Close'])

plt.plot(fr_df[['Actual','Predicted']])

plt.legend(['Train', 'Val', 'Predictions'], loc = 'lower right')

plt.xticks(rotation = 45)

plt.tight_layout()

Chi tiết các bước nhóm thực hiện để trực quan hóa dữ liệu:

● plt.figure(figsize = (18,7)): Tạo một hình ảnh với kích thước 18 inch x 7
inch.
● plt.title('Phân Tích & Dự Đoán Giá Cổ Phiếu AAPL'): Đặt tiêu đề cho
hình ảnh là "Phân Tích & Dự Đoán Giá Cổ Phiếu AAPL".
● plt.xlabel('Date', fontsize = 16): Đặt nhãn cho trục x là "Ngày" với cỡ
chữ 16.
● plt.ylabel('Close Price USD ($)', fontsize = 16): Đặt nhãn cho trục y là
"Giá đóng cửa USD ($)" với cỡ chữ 16.

20
● plt.plot(train['Close']): Vẽ đường biểu thị giá đóng cửa của tập dữ liệu
huấn luyện.
● plt.plot(fr_df[['Actual','Predicted']]): Vẽ đường biểu thị giá thực tế và dự
đoán của tập dữ liệu kiểm tra.
● plt.legend(['Train', 'Val', 'Predictions'], loc = 'lower right'): Thêm chú
thích cho các đường biểu thị với vị trí ở góc dưới bên phải.
● plt.xticks(rotation = 45): Xoay nhãn trục x 45 độ.
● plt.tight_layout(): Tự động điều chỉnh khoảng cách giữa các thành phần
trong hình ảnh.

2.1.14. Xây dựng mô hình Random Forest


model = RandomForestRegressor(n_estimators=500, random_state=42,
min_samples_split=2, min_samples_leaf=1, max_depth=10, bootstrap=True)

model.fit(X_train, y_train)

Nhóm khởi tạo mô hình Random Forest Regressor với các tham số sau:

● n_estimators=500: Sử dụng 500 cây quyết định trong mô hình.


● random_state=42: Cố định giá trị ngẫu nhiên để đảm bảo tính nhất quán
kết quả.
● min_samples_split=2: Số lượng mẫu tối thiểu để chia một node trong
cây quyết định.
● min_samples_leaf=1: Số lượng mẫu tối thiểu để tạo một lá trong cây
quyết định.
● max_depth=10: Chiều sâu tối đa của cây quyết định.
● bootstrap=True: Sử dụng phương pháp bootstrap để lấy mẫu dữ liệu.

21
● model.fit(X_train, y_train): Huấn luyện mô hình với tập dữ liệu huấn
luyện.

Dự đoán giá cổ phiếu trên tập kiểm tra: predict = model.predict(X_test).

2.1.15. Các số đo đánh giá mô hình


print("Mean Absolute Error:", round(metrics.mean_absolute_error(y_test,
predict), 4))
print("Mean Squared Error:", round(metrics.mean_squared_error(y_test,
predict), 4))
print("Root Mean Squared Error:",
round(np.sqrt(metrics.mean_squared_error(y_test, predict)), 4))
print("(R^2) Score:", round(metrics.r2_score(y_test, predict), 4))
print(f'Train Score : {model.score(X_train, y_train) * 100:.2f}% and
Test Score : {model.score(X_test, y_test) * 100:.2f}% using Random Tree
Regressor.')

Kết quả và giải thích:

● "Mean Absolute Error:".


print("Mean Absolute Error:", round(metrics.mean_absolute_error(y_test,
predict), 4))

○ metrics.mean_absolute_error(y_test, predict) tính Sai số Trung bình


Tuyệt đối (MAE) giữa giá đóng cửa thực tế (y_test) và giá đóng cửa dự
đoán (predict). MAE thể hiện trung bình giá trị tuyệt đối của chênh lệch
giữa giá trị dự đoán và giá trị thực tế.

○ round(..., 4) làm tròn giá trị MAE đã tính toán đến 4 chữ số thập phân.
● "Mean Squared Error:".
print("Mean Squared Error:", round(metrics.mean_squared_error(y_test,
predict), 4))

22
○ metrics.mean_squared_error(y_test, predict) tính sai số trung bình bình
phương (MSE) giữa giá đóng cửa thực tế và dự đoán. MSE thể hiện
trung bình giá trị bình phương của chênh lệch.

○ round(..., 4) làm tròn giá trị MSE đã tính toán đến 4 chữ số thập phân.

In ra thông báo "Root Mean Squared Error:".


print("Root Mean Squared Error:",
round(np.sqrt(metrics.mean_squared_error(y_test, predict)), 4))

○ np.sqrt(metrics.mean_squared_error(y_test, predict)) tính sai số trung


bình bình phương Căn bậc hai (RMSE), lấy căn bậc hai của MSE, đưa
chỉ số lỗi về cùng đơn vị với dữ liệu ban đầu (giá đóng cửa).

○ round(..., 4) làm tròn giá trị RMSE đã tính toán đến 4 chữ số thập phân.

In ra thông báo "(R^2) Score:".


print("(R^2) Score:", round(metrics.r2_score(y_test, predict), 4))

○ metrics.r2_score(y_test, predict) tính toán điểm R-squared để thể hiện tỷ


lệ phần trăm biến động của giá đóng cửa thực tế được giải thích bởi dự
đoán của mô hình. Giá trị càng gần 1 cho thấy sự phù hợp càng tốt.

○ round(..., 4) làm tròn giá trị điểm R-squared đến 4 chữ số thập phân.

In ra chuỗi định dạng hiển thị cả điểm số đào tạo và kiểm tra của mô hình.
print(f'Train Score : {model.score(X_train, y_train) * 100:.2f}% and
Test Score : {model.score(X_test, y_test) * 100:.2f}% using Random Tree
Regressor.')

○ model.score(X_train, y_train) tính toán điểm R-squared cho dữ liệu đào


tạo, phản ánh mức độ phù hợp của mô hình với dữ liệu được dùng để
đào tạo.

○ model.score(X_test, y_test) tính toán điểm R-squared cho dữ liệu kiểm


tra, phản ánh mức độ khái quát của mô hình đối với dữ liệu chưa từng
được nhìn thấy.
○ Thể hiện dưới dạng phần trăm.

23
○ Chuỗi định dạng f-string hiển thị điểm số với nhãn và làm tròn đến 2
chữ số thập phân.

2.1.16. Tính toán độ chính xác của mô hình


errors = abs(predict - y_test)
mape = 100 * (errors / y_test)
accuracy = 100 - np.mean(mape)
print('Accuracy:', round(accuracy, 2), '%.')
plt.show()
valid

errors = abs(predict - y_test)


● Tính toán sai số tuyệt đối giữa giá đóng cửa dự đoán và giá đóng cửa thực tế.

● abs(predict - y_test) lấy giá trị tuyệt đối của chênh lệch giữa mỗi giá trị dự
đoán trong predict và giá trị thực tế tương ứng trong y_test.

mape = 100 * (errors / y_test)

● Tính toán Sai số Trung bình Tuyệt đối Phần trăm (MAPE).

● errors / y_test chia mỗi sai số tuyệt đối cho giá đóng cửa thực tế tương ứng, thể
hiện sai số dưới dạng phần trăm.

accuracy = 100 - np.mean(mape)

● Tính toán độ chính xác dựa trên MAPE.

● np.mean(mape) tính toán trung bình giá trị MAPE cho tất cả dự đoán.
● `100 - X

Hiển thị biểu đồ và kiểm tra cú pháp.

24
2.2. Tổng hợp các kết quả (Biểu đồ)

Bảng 1. Model Summary

Biểu đồ này giúp quan sát biến động của giá cổ phiếu trong khoảng thời gian được
chọn.

25
Bảng 2. Bảng biểu thị giá đóng cửa đã được điều chỉnh của Apple

Biểu đồ này sẽ thể hiện sự dao động giá đóng cửa được điều chỉnh của Apple qua từng
khoảng thời gian.

Bảng 3. Bảng số lượng giao dịch của Apple

Biểu đồ này sẽ cho chúng ta cái nhìn về sự dao động số giao dịch của Apple qua từng
mốc thời gian cụ thể.

26
Bảng 4. Bảng đường trung bình động (MA)

Biểu đồ này sẽ thể hiện sự dao động lần lượt của đường trung bình động được cập
nhật liên tục qua từng mốc thời gian lần lượt là 10 ngày, 20 ngày và 50 ngày hoặc bất
kỳ khoảng thời gian nào mà nhà giao dịch chọn.

Bảng 5. Phân tích và dự đoán giá cổ phiếu AAPL

Biểu đồ này thể hiện sự phân tích và dự đoán của máy đối với giá cổ phiếu của Apple.
Từ đó, nhìn nhận được độ chính xác của máy khi dự đoán giá chứng khoán.

27
CHƯƠNG 3. KẾT QUẢ VÀ HƯỚNG PHÁT TRIỂN
3.1. Kết quả nghiên cứu

Sau thời gian tìm hiểu và nghiên cứu dưới sự hướng dẫn của giảng viên về các hàm cơ
bản trong python cũng như cách áp dụng và xây dựng các bài toán lập trình ứng dụng
vào thực tế, nhóm đã tích lũy cho mình những hiểu biết thêm về ngôn ngữ lập trình, từ
đó xây dựng đồ án lập trình phân tích và dự đoán chứng khoán bằng phương pháp hồi
quy tuyến tính. Sau quá trình nghiên cứu, nhóm đã đạt được một số kết quả:

● Hiểu thêm về ngôn ngữ lập trình Python.


● Hiểu thêm về bài toán dự đoán chứng khoán.
● Hiểu được bài toán ứng dụng dự đoán giá cổ phiếu.
● Có thêm được cái nhìn tổng quan về thị trường chứng khoán qua các biểu đồ.
Từ đó đưa ra nhận xét thêm về thị trường chứng khoán một cách khách quan
hơn.
● Viết và xây dựng được chương trình thử nghiệm dự đoán giá chứng khoán.

3.2. Hạn chế đề tài

Thành viên nhóm tham gia nghiên cứu đề tài là những sinh viên năm nhất nên không
tránh khỏi những sai sót trong quá trình xây dựng đồ án:

● Chưa hiểu được sâu về bài toán dự đoán chứng khoán.


● Giao diện vẫn còn một số lỗi gặp phải do chưa tối ưu hóa được giao diện.

Bên cạnh đó, trong thời gian sắp tới, nhóm mong muốn có thể hoàn thiện được những
sai sót kể trên cũng như trau dồi thêm kinh nghiệm, kỹ năng lập trình Python thành
thạo hơn. Từ bài toán dự đoán chứng khoán, nhóm cũng mong muốn dựa vào đó để
phát triển thêm những nghiên cứu ở các lĩnh vực khác.

3.3. Hướng phát triển đề tài

Nhóm mong muốn cải tiến và tối ưu chương trình để có thể dự đoán thị trường của
những loại tài sản khác như ngoại tệ, vàng, bất động sản, cổ phiếu, trái phiếu, forex,
tài sản số như tiền ảo, crypto, NFT. Ứng dụng máy học để chương trình có thể phát
triển thêm nhiều mô hình dự đoán khác.

28
3.4. Kịch bản demo

Kịch bản demo: Chương trình code dự đoán thị trường chứng khoán được nhóm xây
dựng sẽ chạy ra các bảng biểu đồ và dữ liệu như: biểu đồ scatter plot và đường thẳng
tuyến tính, biểu đồ thể hiện Closing price, biểu đồ thể hiện số lượng giao dịch
(Volume), biểu đồ đường trung bình động (MA) và bảng phân tích dự đoán giá cổ
phiếu Apple. Từ các bảng biểu đồ trên giúp cho người đọc có cái nhìn khái quát và
tổng quan hơn về các chỉ số chứng khoán. Từ đó, đưa ra được những nhìn nhận đúng
về giá cổ phiếu, cụ thể hơn là Apple.

29
TÀI LIỆU THAM KHẢO
1. FARES SAYAH.(2023). Stock Market Analysis + Prediction using LSTM
2. Project dự đoán giá chứng khoán bằng mô hình hồi quy
3. Tài chính Academy.(2022). Simple Linear Regression in Python

30

You might also like