5.3.1. Correlation

Mục đích: Dùng để tính hệ số tương quan trượt (rolling correlation) giữa hai chuỗi thời gian giá hoặc lợi suất trong tài chính.

Cấu trúc hàm: correlation(x, y, w=, type_=SeriesType.PRICES)

Tham số:

Tham số
Kiểu dữ liệu
Ý nghĩa

x

Series

Chuỗi thời gian thứ nhất (giá hoặc lợi suất)

y

Series

Chuỗi thời gian thứ hai (giá hoặc lợi suất)

w

Window, int hoặc str

Kích thước cửa sổ trượt (rolling window) Ví dụ: Window(22, 10) là dùng cửa sổ 22 phiên và bỏ qua 10 phiên đầu để "ramp-up". Nếu dùng str, có thể là '1m' (1 tháng), '1d' (1 ngày)...

type_

SeriesType.PRICES (mặc định) hoặc SeriesType.RETURNS

Xác định đầu vào là giá hay lợi suất

Ý nghĩa toán học: Hàm tính hệ số tương quan Pearson giữa hai chuỗi lợi suất (hoặc giá được chuyển thành lợi suất) trong cửa sổ trượt w.

Công thức:

ρt=i=tw+1t(RiR)(SiS)(N1).σR.σS\rho_t = \frac{\sum_{i=t-w+1}^t (R_i - \overline{R})(S_i - \overline{S})}{(N-1).\sigma_{R}.\sigma_{S}}

Trong đó:

  • Ri=XiXi1R_i = \frac{X_i}{X_i - 1}: lợi suất từ chuỗi x nếu input là giá.

  • Si=YiYi1S_i = \frac{Y_i}{Y_i - 1}: lợi suất từ chuỗi y nếu input là giá.

  • Nếu input đã là lợi suất thì dùng trực tiếp Ri=XiR_i = X_i, Si=YiS_i = Y_i.

  • R\overline{R}, S\overline{S}: trung bình mẫu trong mỗi cửa sổ.

  • σR\sigma_{R}, σS\sigma_{S}: độ lệch chuẩn mẫu trong mỗi cửa sổ.

Giá trị trả về:

  • Một Series chứa hệ số tương quan qua từng thời điểm ttt, tương ứng với mỗi cửa sổ trượt.

  • Có thể dùng để đánh giá mối quan hệ đồng biến/nghịch biến theo thời gian.

Ví dụ mẫu tính rolling correlation trong vòng 22 ngày gần nhất từ 03/06/2025 - 25/06/2025 của HPG và HSG trên tập dữ liệu 1 năm từ 25/05/2024 - 25/06/2025:

import pandas as pd
from FiinQuantX import FiinSession
from FiinQuantX.timeseries.econometrics import correlation
from FiinQuantX.timeseries.helper import Window
from datetime import datetime
from dateutil.relativedelta import relativedelta

username = "REPLACE_WITH_YOUR_USERNAME"
password = "REPLACE_WITH_YOUR_PASSWORD"

client = FiinSession(
    username=username,
    password=password
).login()

# Lấy dữ liệu giá đóng cửa 1 năm EOD của HPG và HSG
data = client.Fetch_Trading_Data(
    realtime=False,
    tickers=["HPG","HSG"],
    fields=["close"],
    adjusted=True,
    by="1d",
    from_date=(datetime.now() - relativedelta(years=1)).strftime("%Y-%m-%d")
).get_data()

# Pivot theo ticker để tách riêng từng mã
data["timestamp"] = pd.to_datetime(data["timestamp"])
pivot_data = data.pivot(index="timestamp", columns="ticker", values="close")

# Lấy Series
series_HPG = pivot_data["HPG"]
series_HSG = pivot_data["HSG"]

# Tính rolling correlation 22 ngày
corr = correlation(series_HPG, series_HSG, w=22)

# Ghép 3 series vào thành 1 dataframe
df_hpg = series_HPG.rename("HPG").reset_index().rename(columns={"index": "timestamp"})
df_hsg = series_HSG.rename("HSG").reset_index().rename(columns={"index": "timestamp"})
df_corr = corr.rename("correlation").reset_index().rename(columns={"index": "timestamp"})

df_merged = pd.merge(df_hpg, df_hsg, on="timestamp", how="outer")
df_merged = pd.merge(df_merged, df_corr, on="timestamp", how="outer")

df_merged = df_merged.sort_values("timestamp").reset_index(drop=True)
print(df_merged)

Kết quả trả ra (code chạy tại ngày 25/06/2025)

   timestamp   HPG      HSG       correlation
0  2025-01-24  26550.0  16954.42          NaN
1  2025-02-03  26400.0  17100.16          NaN
2  2025-02-04  26850.0  17391.64          NaN
3  2025-02-05  26800.0  17391.64          NaN
4  2025-02-06  26800.0  17245.90          NaN
..        ...      ...       ...          ...
95 2025-06-19  26900.0  16750.00     0.674208
96 2025-06-20  27000.0  16600.00     0.661541
97 2025-06-23  26850.0  16350.00     0.667212
98 2025-06-24  27000.0  16750.00     0.655733
99 2025-06-25  27200.0  16750.00     0.668507

Biểu đồ minh họa (tuỳ chọn)

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# Chuẩn hóa giá HPG và HSG (min-max normalization)
df_merged['timestamp'] = pd.to_datetime(df_merged['timestamp'])
df_merged['HPG_norm'] = (df_merged['HPG'] - df_merged['HPG'].min()) / (df_merged['HPG'].max() - df_merged['HPG'].min())
df_merged['HSG_norm'] = (df_merged['HSG'] - df_merged['HSG'].min()) / (df_merged['HSG'].max() - df_merged['HSG'].min())

fig, ax1 = plt.subplots(figsize=(14, 6))

# Plot HPG và HSG đã chuẩn hóa
ax1.plot(df_merged['timestamp'], df_merged['HPG_norm'], label='HPG (normalized)', color='blue')
ax1.plot(df_merged['timestamp'], df_merged['HSG_norm'], label='HSG (normalized)', color='green')
ax1.set_ylabel('Normalized Price', color='black')
ax1.legend(loc='upper left')
ax1.grid(True)

# Format thời gian
ax1.xaxis.set_major_locator(mdates.AutoDateLocator())
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
fig.autofmt_xdate(rotation=45)

# Trục y phải: correlation
ax2 = ax1.twinx()
ax2.plot(df_merged['timestamp'], df_merged['correlation'], label='Rolling Correlation (HPG-HSG)', color='red', linestyle='--')
ax2.set_ylabel('Correlation', color='red')
ax2.legend(loc='upper right')

plt.title('Giá HPG & HSG (chuẩn hóa) và hệ số tương quan theo thời gian')
plt.tight_layout()
plt.show()

Last updated