Import + File input + File output
# ==== CELL 1: DỮ LIỆU ĐẦU VÀO ====
import os
import numpy as np
import pandas as pd
# ====== CẤU HÌNH NGƯỜI DÙNG (GIỮ NGUYÊN NHƯ BẠN ĐÃ CHO) ======
INPUT_PATH = "/Users/phamhuuhien/Downloads/[Link]"
OUTDIR = "/Users/phamhuuhien/PycharmProjects/Dulieu chứng
khoán /.venv/te_outputs_notebook"
[Link](OUTDIR, exist_ok=True)
# Tham số TE
N_BINS = 7
LAG = 1
N_PERM = 1000
RANDOM_STATE = 42
# Tham số WTC / CWT
dt = 1.0
min_scale = 2
max_scale = 256
num_scales = 96
# Nhãn trục
x_label = "EPU_MoM"
y_label = "INF_MoM"
# ====== ĐỌC & CHUẨN HÓA DỮ LIỆU ======
df = pd.read_csv(INPUT_PATH)
if "Time" not in [Link] or x_label not in [Link] or y_label
not in [Link]:
raise ValueError("CSV phải có cột: Time, EPU_MoM, INF_MoM")
df["Time"] = pd.to_datetime(df["Time"])
df = df.sort_values("Time").dropna(subset=[x_label,
y_label]).reset_index(drop=True)
t = df["Time"].values
x = df[x_label].astype(float).values
y = df[y_label].astype(float).values
# Chuẩn hóa z-score để wavelet ổn định về thang đo
x = (x - [Link](x)) / ([Link](x) + 1e-12)
y = (y - [Link](y)) / ([Link](y) + 1e-12)
Xử lý và tính toán dữ liệu từng index
# ============================================
# Wavelet + Circular Test + TE + AME Pipeline
# ============================================
# ==== IMPORTS ====
import numpy as np
import pandas as pd
import pywt
from [Link] import gaussian_filter, uniform_filter
# ==== GLOBAL CONFIG (bạn có thể chỉnh) ====
RANDOM_STATE = 42
dt = 1.0 # đơn vị thời gian giữa 2
quan sát (ví dụ: 1 tháng)
wavelet_name = "cmor1.5-1.0"
min_scale, max_scale, num_scales = 2, 128, 64
# TE/AME & Permutation
LAG = 1
N_BINS = 6
N_PERM = 500
# WTC significance + thực dụng
alpha_wtc = 0.05
coh_thr = 0.70
min_run = 6 # tối thiểu 6 điểm liên tiếp trong một cửa sổ
# Nhãn (để ghi kết quả) — dùng đúng tên cột của bạn
x_label = "EPU_MoM"
y_label = "INF_MoM"
rng = [Link].default_rng(RANDOM_STATE)
df = pd.read_csv("/Users/phamhuuhien/Downloads/[Link]")
# Chuẩn hóa thời gian & chọn đúng hai biến nghiên cứu
df = [Link]()
df["Time"] = pd.to_datetime(df["Time"], errors="coerce")
df =
[Link](subset=["Time"]).sort_values("Time").set_index("Time")
df = df[["EPU_MoM", "INF_MoM"]].apply(pd.to_numeric,
errors="coerce").dropna()
# Gán cho pipeline
t = [Link] # DatetimeIndex
x = df["EPU_MoM"].to_numpy() # nguồn
y = df["INF_MoM"].to_numpy() # đích
assert len(t) == len(x) == len(y) and len(x) > 30, "Độ dài chuỗi
không hợp lệ."
# ==== WTC CORE (NEW) ====
def _smooth2d(A, sigma_t=3, size_s=3):
B = gaussian_filter(A, sigma=(0, sigma_t)) # (scale, time)
B = uniform_filter(B, size=(size_s, 1))
return B
def compute_wtc_arrays(x_vals, y_vals, dt=1.0, wavelet='cmor1.5-
1.0',
min_scale=2, max_scale=128, num_scales=64,
smooth_t=3, smooth_s=3):
x0 = x_vals - [Link](x_vals)
y0 = y_vals - [Link](y_vals)
scales = [Link](min_scale, max_scale, num_scales)
Wx, freqs = [Link](x0, scales, wavelet, dt)
Wy, _ = [Link](y0, scales, wavelet, dt)
period = 1.0 / (freqs + 1e-12)
Wxy = Wx * [Link](Wy)
Px = [Link](Wx)**2
Py = [Link](Wy)**2
Sx = _smooth2d(Px / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
Sy = _smooth2d(Py / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
Sxy = _smooth2d(Wxy / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
coh = ([Link](Sxy)**2) / (Sx * Sy + 1e-12)
coh = [Link](coh, 0, 1)
phase = [Link](Wxy) # pha từ XWT
return coh, phase, period
def wtc_pvals_circular(x_series, y_series, n_perm=1000, seed=42,
**wtc_kw):
rng_local = [Link].default_rng(seed)
# canh thẳng hàng một lần
xy = [Link]([x_series.rename('x'), y_series.rename('y')],
axis=1).dropna()
times = [Link]
x_vals = xy['x'].values
y_vals = xy['y'].values
coh_obs, phase, period = compute_wtc_arrays(x_vals, y_vals,
**wtc_kw)
ge_counts = np.zeros_like(coh_obs, dtype=np.int32)
T = len(y_vals)
for _ in range(n_perm):
shift = rng_local.integers(0, T)
y_perm = [Link](y_vals, shift)
coh_perm, _, _ = compute_wtc_arrays(y_perm, x_vals, **wtc_kw)
# coherence đối xứng
ge_counts += (coh_perm >= coh_obs)
pvals = (ge_counts + 1) / (n_perm + 1) # add-one smoothing
return coh_obs, phase, period, times, pvals
# ==== TE / AME tools ====
def quantile_digitize(z, n_bins):
z = [Link](z, float)
mask = [Link](z); zv = z[mask]
if [Link] < n_bins + 5:
mn, mx = [Link](zv), [Link](zv)
edges = [Link](mn, mx + 1e-12, n_bins + 1)
else:
q = [Link](0, 1, n_bins + 1)
edges = [Link](zv, q)
edges = [Link](edges)
if [Link] - 1 < n_bins:
mn, mx = [Link](zv), [Link](zv)
edges = [Link](mn, mx + 1e-12, n_bins + 1)
bins = np.full_like(z, -1, dtype=int)
bins[mask] = [Link]([Link](zv, edges[1:-1], right=False),
0, n_bins - 1)
return bins
def transfer_entropy_discrete(x_s, y_s, lag=1, n_bins=5, n_perm=500,
rng=None):
y_t1 = y_s[lag:]; y_t = y_s[:-lag]; x_t = x_s[:-lag]
bx = quantile_digitize(x_t, n_bins)
by = quantile_digitize(y_t, n_bins)
by1 = quantile_digitize(y_t1, n_bins)
m = (bx >= 0) & (by >= 0) & (by1 >= 0)
bx, by, by1 = bx[m], by[m], by1[m]
if [Link] < 30:
return 0.0, 1.0
K = n_bins
C = [Link]((K, K, K), float) # [y1,y,x]
[Link](C, (by1, by, bx), 1.0)
P = C / [Link]()
Py1y = [Link](2); Py = [Link](0); Pyx = [Link](0)
Py1_yx = P / (Pyx[None, :, :] + 1e-12)
Py1_y = Py1y / (Py[None, :] + 1e-12)
TE_obs = float([Link](P * [Link]((Py1_yx + 1e-12) /
(Py1_y[:, :, None] + 1e-12))))
greater = 0; n_valid = [Link]
rng_local = rng if rng is not None else [Link].default_rng(0)
for _ in range(n_perm):
k = int(rng_local.integers(1, n_valid))
bx_p = [Link](bx, k)
Cp = np.zeros_like(C); [Link](Cp, (by1, by, bx_p), 1.0)
Pp = Cp / [Link](); Py1y_p = [Link](2); Py_p = Py1y_p.sum(0);
Pyx_p = [Link](0)
Py1_yx_p = Pp / (Pyx_p[None, :, :] + 1e-12)
Py1_y_p = Py1y_p / (Py_p[None, :] + 1e-12)
TE_p = [Link](Pp * [Link]((Py1_yx_p + 1e-12) / (Py1_y_p[:,
:, None] + 1e-12)))
if TE_p >= TE_obs:
greater += 1
p_val = (greater + 1) / (n_perm + 1)
return TE_obs, float(p_val)
def ame_bootstrap(x_s, y_s, lag=1, n_boot=1000, rng=None):
y1 = y_s[lag:]; y0 = y_s[:-lag]; xx = x_s[:-lag]
m = [Link](y1) & [Link](y0) & [Link](xx)
y1, y0, xx = y1[m], y0[m], xx[m]
if [Link] < 30:
return 0.0, 0.5, ([Link], [Link]), 1.0
X = np.column_stack([np.ones_like(xx), y0, xx])
beta, *_ = [Link](X, y1, rcond=None); ame = float(beta[-
1])
ame_pos_share = float([Link]((xx * ame) > 0))
n = [Link]; B = min(n_boot, 1000)
rng_local = rng if rng is not None else [Link].default_rng(0)
bs = [Link](B)
for b in range(B):
idx = rng_local.integers(0, n, n)
betab, *_ = [Link](X[idx], y1[idx], rcond=None)
bs[b] = betab[-1]
lo, hi = [Link](bs, [2.5, 97.5])
p_boot = 2 * min([Link](bs <= 0), [Link](bs >= 0))
return ame, ame_pos_share, (float(lo), float(hi)), float(p_boot)
def _windows(mask, min_run=6):
out = []
i, n = 0, [Link]
while i < n:
if mask[i]:
j = i
while j + 1 < n and mask[j+1]:
j += 1
if j - i + 1 >= min_run:
[Link]((i, j))
i = j + 1
else:
i += 1
return out
def _fmt_windows(times_index, wins):
if (wins is None) or (len(wins) == 0):
return ""
segs = [f"{pd.to_datetime(times_index[a]).strftime('%Y-
%m')}~{pd.to_datetime(times_index[b]).strftime('%Y-%m')}"
for a, b in wins]
return "; ".join(segs)
# ====================================
# ==== WTC + Circular p-values RUN ====
# ====================================
# Convert to Series (đảm bảo cùng index thời gian)
t_index = pd.to_datetime(t)
x_ser = [Link]([Link](float), index=t_index)
y_ser = [Link]([Link](float), index=t_index)
coh, phase, periods, times_wtc, pvals_wtc = wtc_pvals_circular(
x_ser, y_ser,
n_perm=N_PERM,
seed=RANDOM_STATE,
dt=dt, wavelet=wavelet_name,
min_scale=min_scale, max_scale=max_scale, num_scales=num_scales,
smooth_t=3, smooth_s=3
)
# ==============================
# ==== Chuẩn bị Wx, Wy cho TE/AME (dùng real part theo từng scale
như bản gốc) ====
# ==============================
scales = [Link](min_scale, max_scale, num_scales)
x0 = x - [Link](x)
y0 = y - [Link](y)
Wx, _ = [Link](x0, scales, wavelet_name, dt)
Wy, _ = [Link](y0, scales, wavelet_name, dt)
# =========================
# ==== Tổng hợp kết quả ===
# =========================
rows = []
scale_range_str = f"{min_scale}-{max_scale}"
for j, (per, s) in enumerate(zip(periods, scales), start=1):
# series tại scale j (real part) để TE/AME
x_s = [Link](Wx[j-1, :])
y_s = [Link](Wy[j-1, :])
# coherence & phase tại scale j
coh_j = coh[j-1, :]
phase_j = phase[j-1, :]
sig_j = (pvals_wtc[j-1, :] < alpha_wtc) # ô có ý nghĩa theo
circular
# [NEW] lấy p-value trung bình và nhỏ nhất của circular test ở
scale j
wtc_p_mean = float([Link](pvals_wtc[j-1, :]))
wtc_p_min = float([Link](pvals_wtc[j-1, :]))
coh_mean = float([Link](coh_j))
coh_max = float([Link](coh_j))
# Cửa sổ theo chiều pha + ý nghĩa + ngưỡng thực dụng
mask_xy = ([Link](coh_j)) & sig_j & (coh_j >= coh_thr) &
(phase_j > 0) # EPU -> INF
mask_yx = ([Link](coh_j)) & sig_j & (coh_j >= coh_thr) &
(phase_j < 0) # INF -> EPU
win_xy = _windows(mask_xy, min_run=min_run)
win_yx = _windows(mask_yx, min_run=min_run)
# ----- EPU_MoM -> INF_MoM -----
TE_xy, p_xy = transfer_entropy_discrete(x_s, y_s, lag=LAG,
n_bins=N_BINS, n_perm=N_PERM, rng=rng)
ame_xy, share_xy, (lo_xy, hi_xy), p_ame_xy = ame_bootstrap(x_s,
y_s, lag=LAG, n_boot=N_PERM, rng=rng)
[Link]({
"Period": float(per), "N_BINS": N_BINS, "LAG": LAG,
"Wavelet": wavelet_name,
"Scale_Range": scale_range_str, "Scale_Level": j,
"Direction": f"{x_label}->{y_label}",
"TE": float(TE_xy), "p_value": float(p_xy),
"AME_mean": float(ame_xy), "AME_pos_share": float(share_xy),
"AME_CI95": (float(lo_xy), float(hi_xy)), "AME_p":
float(p_ame_xy),
"coh_mean": coh_mean, "coh_max": coh_max,
"WTC_p_mean": wtc_p_mean, "WTC_p_min": wtc_p_min, # [NEW] 2
cột p-value circular
"Time_Windows": _fmt_windows(times_wtc, win_xy),
"x_label": x_label, "y_label": y_label
})
# ----- INF_MoM -> EPU_MoM -----
TE_yx, p_yx = transfer_entropy_discrete(y_s, x_s, lag=LAG,
n_bins=N_BINS, n_perm=N_PERM, rng=rng)
ame_yx, share_yx, (lo_yx, hi_yx), p_ame_yx = ame_bootstrap(y_s,
x_s, lag=LAG, n_boot=N_PERM, rng=rng)
[Link]({
"Time_Windows": _fmt_windows(times_wtc, win_yx),
"N_BINS": N_BINS, "LAG": LAG,
"Scale_Range": scale_range_str, "Scale_Level": j,
"Direction": f"{y_label}->{x_label}",
"TE": float(TE_yx), "p_value": float(p_yx),
"AME_mean": float(ame_yx), "AME_pos_share": float(share_yx),
"AME_CI95": (float(lo_yx), float(hi_yx)), "AME_p":
float(p_ame_yx),
"coh_mean": coh_mean, "coh_max": coh_max,
"WTC_p_mean": wtc_p_mean, "WTC_p_min": wtc_p_min, # [NEW]
giữ nguyên cho hướng ngược lại
"x_label": y_label, "y_label": x_label
})
# ============================================
# ==== Xuất chi tiết Wavelet Coherence (WTC) ====
# ============================================
n_s, n_t = [Link] # số scale và số thời điểm
grid = [Link]({
"scale_idx": [Link]([Link](n_s), n_t),
"time_idx": [Link]([Link](n_t), n_s),
"time": [Link](pd.to_datetime(times_wtc), n_s), # thời
gian gốc
"period": [Link](periods, n_t), # chu kỳ
tương ứng
"coh_value": [Link](order="C"), #
coherence từng ô
"WTC_p_value": pvals_wtc.ravel(order="C") # p-
value từng ô (circular test)
})
# Lưu file
grid.to_csv("WTC_full_detail.csv", index=False)
print(f"✅ Đã xuất {len(grid)} ô Wavelet Coherence (coh +
WTC_p_value) "
f"= {n_s} scales × {n_t} thời điểm")
# ==== Xuất chi tiết Average Marginal Effects (AME) ====
# ============================================
AME_df = [Link](rows)[[
"Scale_Level", "Period", "Direction",
"AME_mean", "AME_pos_share", "AME_CI95", "AME_p"
]]
AME_df.to_csv("AME_full_detail.csv", index=False)
print(f"✅ Đã xuất chi tiết AME: {len(AME_df)} dòng "
f"(bao gồm cả hai hướng {x_label}->{y_label} và {y_label}-
>{x_label})")
# Done: summary_df chứa kết quả đã có circular test cho WTC + TE/AME
+ Time_Windows
Xử lý và tính toán dữ liệu lọc kết quả
# ============================================
# Wavelet + Circular Test + TE + AME Pipeline
# ============================================
# ==== IMPORTS ====
import numpy as np
import pandas as pd
import pywt
from [Link] import gaussian_filter, uniform_filter
# ==== GLOBAL CONFIG (bạn có thể chỉnh) ====
RANDOM_STATE = 42
dt = 1.0
wavelet_name = "cmor1.5-1.0"
min_scale, max_scale, num_scales = 2, 128, 64
# TE/AME & Permutation
LAG = 1
N_BINS = 6
N_PERM = 500
# WTC significance + thực dụng
alpha_wtc = 0.05
coh_thr = 0.70
min_run = 6
# Nhãn (để ghi kết quả) — dùng đúng tên cột của bạn
x_label = "EPU_MoM"
y_label = "INF_MoM"
rng = [Link].default_rng(RANDOM_STATE)
df = pd.read_csv("")
# Chuẩn hóa thời gian & chọn đúng hai biến nghiên cứu
df = [Link]()
df["Time"] = pd.to_datetime(df["Time"], errors="coerce")
df =
[Link](subset=["Time"]).sort_values("Time").set_index("Time")
df = df[["EPU_MoM", "INF_MoM"]].apply(pd.to_numeric,
errors="coerce").dropna()
# Gán cho pipeline
t = [Link] # DatetimeIndex
x = df["EPU_MoM"].to_numpy() # nguồn
y = df["INF_MoM"].to_numpy() # đích
assert len(t) == len(x) == len(y) and len(x) > 30, "Độ dài chuỗi
không hợp lệ."
# ==== WTC CORE (NEW) ====
def _smooth2d(A, sigma_t=3, size_s=3):
B = gaussian_filter(A, sigma=(0, sigma_t)) # (scale, time)
B = uniform_filter(B, size=(size_s, 1))
return B
def compute_wtc_arrays(x_vals, y_vals, dt=1.0, wavelet='cmor1.5-
1.0',
min_scale=2, max_scale=128, num_scales=64,
smooth_t=3, smooth_s=3):
x0 = x_vals - [Link](x_vals)
y0 = y_vals - [Link](y_vals)
scales = [Link](min_scale, max_scale, num_scales)
Wx, freqs = [Link](x0, scales, wavelet, dt)
Wy, _ = [Link](y0, scales, wavelet, dt)
period = 1.0 / (freqs + 1e-12)
Wxy = Wx * [Link](Wy)
Px = [Link](Wx)**2
Py = [Link](Wy)**2
Sx = _smooth2d(Px / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
Sy = _smooth2d(Py / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
Sxy = _smooth2d(Wxy / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
coh = ([Link](Sxy)**2) / (Sx * Sy + 1e-12)
coh = [Link](coh, 0, 1)
phase = [Link](Wxy) # pha từ XWT
return coh, phase, period
def wtc_pvals_circular(x_series, y_series, n_perm=500, seed=42,
**wtc_kw):
rng_local = [Link].default_rng(seed)
# canh thẳng hàng một lần
xy = [Link]([x_series.rename('x'), y_series.rename('y')],
axis=1).dropna()
times = [Link]
x_vals = xy['x'].values
y_vals = xy['y'].values
coh_obs, phase, period = compute_wtc_arrays(x_vals, y_vals,
**wtc_kw)
ge_counts = np.zeros_like(coh_obs, dtype=np.int32)
T = len(y_vals)
for _ in range(n_perm):
shift = rng_local.integers(0, T)
y_perm = [Link](y_vals, shift)
coh_perm, _, _ = compute_wtc_arrays(y_perm, x_vals, **wtc_kw)
# coherence đối xứng
ge_counts += (coh_perm >= coh_obs)
pvals = (ge_counts + 1) / (n_perm + 1) # add-one smoothing
return coh_obs, phase, period, times, pvals
# ==== TE / AME tools ====
def quantile_digitize(z, n_bins):
z = [Link](z, float)
mask = [Link](z); zv = z[mask]
if [Link] < n_bins + 5:
mn, mx = [Link](zv), [Link](zv)
edges = [Link](mn, mx + 1e-12, n_bins + 1)
else:
q = [Link](0, 1, n_bins + 1)
edges = [Link](zv, q)
edges = [Link](edges)
if [Link] - 1 < n_bins:
mn, mx = [Link](zv), [Link](zv)
edges = [Link](mn, mx + 1e-12, n_bins + 1)
bins = np.full_like(z, -1, dtype=int)
bins[mask] = [Link]([Link](zv, edges[1:-1], right=False),
0, n_bins - 1)
return bins
def transfer_entropy_discrete(x_s, y_s, lag=1, n_bins=5,
n_perm=1000, rng=None):
y_t1 = y_s[lag:]; y_t = y_s[:-lag]; x_t = x_s[:-lag]
bx = quantile_digitize(x_t, n_bins)
by = quantile_digitize(y_t, n_bins)
by1 = quantile_digitize(y_t1, n_bins)
m = (bx >= 0) & (by >= 0) & (by1 >= 0)
bx, by, by1 = bx[m], by[m], by1[m]
if [Link] < 30:
return 0.0, 1.0
K = n_bins
C = [Link]((K, K, K), float) # [y1,y,x]
[Link](C, (by1, by, bx), 1.0)
P = C / [Link]()
Py1y = [Link](2); Py = [Link](0); Pyx = [Link](0)
Py1_yx = P / (Pyx[None, :, :] + 1e-12)
Py1_y = Py1y / (Py[None, :] + 1e-12)
TE_obs = float([Link](P * [Link]((Py1_yx + 1e-12) /
(Py1_y[:, :, None] + 1e-12))))
greater = 0; n_valid = [Link]
rng_local = rng if rng is not None else [Link].default_rng(0)
for _ in range(n_perm):
k = int(rng_local.integers(1, n_valid))
bx_p = [Link](bx, k)
Cp = np.zeros_like(C); [Link](Cp, (by1, by, bx_p), 1.0)
Pp = Cp / [Link](); Py1y_p = [Link](2); Py_p = Py1y_p.sum(0);
Pyx_p = [Link](0)
Py1_yx_p = Pp / (Pyx_p[None, :, :] + 1e-12)
Py1_y_p = Py1y_p / (Py_p[None, :] + 1e-12)
TE_p = [Link](Pp * [Link]((Py1_yx_p + 1e-12) / (Py1_y_p[:,
:, None] + 1e-12)))
if TE_p >= TE_obs:
greater += 1
p_val = (greater + 1) / (n_perm + 1)
return TE_obs, float(p_val)
def ame_bootstrap(x_s, y_s, lag=1, n_boot=1000, rng=rng):
y1 = y_s[lag:]; y0 = y_s[:-lag]; xx = x_s[:-lag]
m = [Link](y1) & [Link](y0) & [Link](xx)
y1, y0, xx = y1[m], y0[m], xx[m]
if [Link] < 30:
return 0.0, 0.5, ([Link], [Link]), 1.0
X = np.column_stack([np.ones_like(xx), y0, xx])
beta, *_ = [Link](X, y1, rcond=None); ame = float(beta[-
1])
ame_pos_share = float([Link]((xx * ame) > 0))
n = [Link]; B = min(n_boot, 1000)
rng_local = rng if rng is not None else [Link].default_rng(0)
bs = [Link](B)
for b in range(B):
idx = rng_local.integers(0, n, n)
betab, *_ = [Link](X[idx], y1[idx], rcond=None)
bs[b] = betab[-1]
lo, hi = [Link](bs, [2.5, 97.5])
p_boot = 2 * min([Link](bs <= 0), [Link](bs >= 0))
return ame, ame_pos_share, (float(lo), float(hi)), float(p_boot)
def _windows(mask, min_run=6):
out = []
i, n = 0, [Link]
while i < n:
if mask[i]:
j = i
while j + 1 < n and mask[j+1]:
j += 1
if j - i + 1 >= min_run:
[Link]((i, j))
i = j + 1
else:
i += 1
return out
def _fmt_windows(times_index, wins):
if (wins is None) or (len(wins) == 0):
return ""
segs = [f"{pd.to_datetime(times_index[a]).strftime('%Y-
%m')}~{pd.to_datetime(times_index[b]).strftime('%Y-%m')}"
for a, b in wins]
return "; ".join(segs)
# ====================================
# ==== WTC + Circular p-values RUN ====
# ====================================
# Convert to Series (đảm bảo cùng index thời gian)
t_index = pd.to_datetime(t)
x_ser = [Link]([Link](float), index=t_index)
y_ser = [Link]([Link](float), index=t_index)
coh, phase, periods, times_wtc, pvals_wtc = wtc_pvals_circular(
x_ser, y_ser,
n_perm=N_PERM,
seed=RANDOM_STATE,
dt=dt, wavelet=wavelet_name,
min_scale=min_scale, max_scale=max_scale, num_scales=num_scales,
smooth_t=3, smooth_s=3
)
# ==============================
# ==== Chuẩn bị Wx, Wy cho TE/AME (dùng real part theo từng scale
như bản gốc) ====
# ==============================
scales = [Link](min_scale, max_scale, num_scales)
x0 = x - [Link](x)
y0 = y - [Link](y)
Wx, _ = [Link](x0, scales, wavelet_name, dt)
Wy, _ = [Link](y0, scales, wavelet_name, dt)
# =========================
# ==== Tổng hợp kết quả ===
# =========================
rows = []
scale_range_str = f"{min_scale}-{max_scale}"
for j, (per, s) in enumerate(zip(periods, scales), start=1):
# series tại scale j (real part) để TE/AME
x_s = [Link](Wx[j-1, :])
y_s = [Link](Wy[j-1, :])
# coherence & phase tại scale j
coh_j = coh[j-1, :]
phase_j = phase[j-1, :]
sig_j = (pvals_wtc[j-1, :] < alpha_wtc) # ô có ý nghĩa theo
circular
# [NEW] lấy p-value trung bình và nhỏ nhất của circular test ở
scale j
wtc_p_mean = float([Link](pvals_wtc[j-1, :]))
wtc_p_min = float([Link](pvals_wtc[j-1, :]))
coh_mean = float([Link](coh_j))
coh_max = float([Link](coh_j))
# Cửa sổ theo chiều pha + ý nghĩa + ngưỡng thực dụng
mask_xy = ([Link](coh_j)) & sig_j & (coh_j >= coh_thr) &
(phase_j > 0) # EPU -> INF
mask_yx = ([Link](coh_j)) & sig_j & (coh_j >= coh_thr) &
(phase_j < 0) # INF -> EPU
win_xy = _windows(mask_xy, min_run=min_run)
win_yx = _windows(mask_yx, min_run=min_run)
# ----- EPU_MoM -> INF_MoM -----
TE_xy, p_xy = transfer_entropy_discrete(x_s, y_s, lag=LAG,
n_bins=N_BINS, n_perm=N_PERM, rng=rng)
ame_xy, share_xy, (lo_xy, hi_xy), p_ame_xy = ame_bootstrap(x_s,
y_s, lag=LAG, n_boot=N_PERM, rng=rng)
[Link]({
"Period": float(per), "N_BINS": N_BINS, "LAG": LAG,
"Wavelet": wavelet_name,
"Scale_Range": scale_range_str, "Scale_Level": j,
"Direction": f"{x_label}->{y_label}",
"TE": float(TE_xy), "p_value": float(p_xy),
"AME_mean": float(ame_xy), "AME_pos_share": float(share_xy),
"AME_CI95": (float(lo_xy), float(hi_xy)), "AME_p":
float(p_ame_xy),
"coh_mean": coh_mean, "coh_max": coh_max,
"WTC_p_mean": wtc_p_mean, "WTC_p_min": wtc_p_min, # [NEW] 2
cột p-value circular
"Time_Windows": _fmt_windows(times_wtc, win_xy),
"x_label": x_label, "y_label": y_label
})
# ----- INF_MoM -> EPU_MoM -----
TE_yx, p_yx = transfer_entropy_discrete(y_s, x_s, lag=LAG,
n_bins=N_BINS, n_perm=N_PERM, rng=rng)
ame_yx, share_yx, (lo_yx, hi_yx), p_ame_yx = ame_bootstrap(y_s,
x_s, lag=LAG, n_boot=N_PERM, rng=rng)
[Link]({
"Time_Windows": _fmt_windows(times_wtc, win_yx),
"N_BINS": N_BINS, "LAG": LAG,
"Scale_Range": scale_range_str, "Scale_Level": j,
"Direction": f"{y_label}->{x_label}",
"TE": float(TE_yx), "p_value": float(p_yx),
"AME_mean": float(ame_yx), "AME_pos_share": float(share_yx),
"AME_CI95": (float(lo_yx), float(hi_yx)), "AME_p":
float(p_ame_yx),
"coh_mean": coh_mean, "coh_max": coh_max,
"WTC_p_mean": wtc_p_mean, "WTC_p_min": wtc_p_min, # [NEW]
giữ nguyên cho hướng ngược lại
"x_label": y_label, "y_label": x_label
})
summary_df = [Link](rows)
# Sắp xếp cột (giữ nguyên format bạn yêu cầu)
cols =
["Time_Windows","N_BINS","LAG","Scale_Range","Scale_Level","Directio
n",
"TE","p_value","AME_mean","AME_pos_share","AME_CI95","AME_p",
"coh_mean","coh_max","WTC_p_mean","WTC_p_min","x_label","y_label"]
summary_df = summary_df[cols]
summary_df.to_csv("Wavelet_Circular_TE_AME_results.csv",
index=False)
print("✅ Đã lưu kết quả vào file:
Wavelet_Circular_TE_AME_results.csv")
# Done: summary_df chứa kết quả đã có circular test cho WTC + TE/AME
+ Time_Windows
Đồ thị EPU&INF
# ==== IMPORTS ====
import os, numpy as np, pandas as pd, [Link] as plt, pywt
from [Link] import gaussian_filter, uniform_filter
# ==== WTC CORE ====
def _smooth2d(A, sigma_t=3, size_s=3):
# làm mượt theo thời gian (Gaussian) + theo scale (Uniform)
B = gaussian_filter(A, sigma=(0, sigma_t)) # (scale, time)
B = uniform_filter(B, size=(size_s, 1))
return B
def compute_wtc_arrays(x_vals, y_vals, dt=1.0, wavelet='cmor1.5-
1.0',
min_scale=2, max_scale=128, num_scales=64,
smooth_t=3, smooth_s=3):
"""Tính Wavelet Coherence & phase cho 2 mảng cùng chiều dài."""
x = x_vals - [Link](x_vals)
y = y_vals - [Link](y_vals)
scales = [Link](min_scale, max_scale, num_scales)
Wx, freqs = [Link](x, scales, wavelet, dt)
Wy, _ = [Link](y, scales, wavelet, dt)
period = 1.0 / freqs
Wxy = Wx * [Link](Wy)
Px = [Link](Wx)**2
Py = [Link](Wy)**2
Sx = _smooth2d(Px / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
Sy = _smooth2d(Py / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
Sxy = _smooth2d(Wxy / scales[:, None], sigma_t=smooth_t,
size_s=smooth_s)
coh = ([Link](Sxy)**2) / (Sx * Sy + 1e-12)
coh = [Link](coh, 0, 1)
phase = [Link](Wxy)
return coh, phase, period
def wtc_pvals_circular(x_series, y_series, n_perm=500, seed=42,
**wtc_kw):
"""P-value theo từng ô (scale × time) bằng circular-shift
surrogates."""
rng = [Link].default_rng(seed)
# align một lần
xy = [Link]([x_series.rename('x'), y_series.rename('y')],
axis=1).dropna()
times = [Link]
x_vals = xy['x'].values
y_vals = xy['y'].values
coh_obs, phase, period = compute_wtc_arrays(x_vals, y_vals,
**wtc_kw)
n_s, n_t = coh_obs.shape
ge_counts = np.zeros_like(coh_obs, dtype=np.int32)
T = len(y_vals)
for i in range(n_perm):
shift = [Link](0, T)
y_perm = [Link](y_vals, shift)
coh_perm, _, _ = compute_wtc_arrays(y_perm, x_vals, **wtc_kw)
# thứ tự không quan trọng cho coherence
ge_counts += (coh_perm >= coh_obs)
pvals = (ge_counts + 1) / (n_perm + 1) # add-one smoothing
return coh_obs, phase, period, times, pvals
# ==== PLOT (R-style) ====
def plot_wtc_rstyle(coh, phase, period, times, title,
out_path=None, pvals=None, alpha=0.05,
cmap='jet', show_phase=True, dt=1.0, w0=6.0,
stride_t=8, stride_s=2, coi_factor=1.3,
y_log2=False, coh_thresh=None):
n_s, n_t = [Link]
fig, ax = [Link](figsize=(10, 5))
extent = [0, n_t - 1, [Link](), [Link]()]
im = [Link](coh, origin='lower', aspect='auto', extent=extent,
cmap=cmap, vmin=0, vmax=1)
# contour nhẹ giống R
levels = [Link](0.2, 0.9, 8)
[Link]([Link](n_t), period, coh, levels=levels,
colors='k', linewidths=0.35, alpha=0.5)
if y_log2:
ax.set_yscale('log', base=2)
ax.set_ylabel("Period (months)")
ax.set_xlabel("Time")
ax.set_title(title, fontsize=12, weight="bold")
[Link](im, ax=ax, label='Wavelet Coherence')
# nhãn năm
ticks = [Link](0, n_t - 1, 6).astype(int)
labels = pd.to_datetime(times).strftime('%Y')
ax.set_xticks(ticks)
ax.set_xticklabels(labels[ticks], rotation=0)
# ==== Viền theo p-value ====
if pvals is not None:
sig_mask = (pvals < alpha)
[Link]([Link](n_t), period, sig_mask.astype(int),
levels=[0.5], colors='black', linewidths=1.0,
zorder=4)
# ==== Vẽ mũi tên pha theo coherence ====
if coh_thresh is None:
coh_thresh = 0.8 # fallback nếu quên truyền
if show_phase:
r_idx = [Link](0, n_s, stride_s)
c_idx = [Link](0, n_t, stride_t)
X, Y = [Link](c_idx, period[r_idx])
PH = phase[np.ix_(r_idx, c_idx)]
U, V = [Link](PH), [Link](PH)
# chỉ hiển thị mũi tên ở vùng coherence >= ngưỡng
C = coh[np.ix_(r_idx, c_idx)]
keep = (C >= coh_thresh)
U = [Link](keep, U, [Link])
V = [Link](keep, V, [Link])
[Link](
X, Y, U, V,
angles='xy', scale_units='xy',
scale=0.25, width=0.002,
headwidth=3.5, headlength=4.5,
pivot='mid', color='k', zorder=5
)
# ==== Đường COI (Cone of Influence) ====
if (dt is not None) and (w0 is not None):
k = [Link](n_t)
edge = [Link](k + 1, n_t - k)
coi = (w0 / [Link](2.0)) * dt * edge
coi = [Link](coi, [Link]())
t_index = [Link](n_t)
[Link](t_index, coi, 'k--', linewidth=1.0, zorder=6)
ax.fill_between(
t_index, coi, [Link](),
color='none', edgecolor=None, hatch='//', alpha=0.15
)
# ==== Hoàn thiện khung hình ====
ax.invert_yaxis() # R-style: scale lớn ở dưới
plt.tight_layout()
if out_path:
[Link]([Link](out_path), exist_ok=True)
[Link](out_path, dpi=180, bbox_inches='tight')
[Link]()
print(f"✅ WTC plot saved to: {[Link](out_path)}")
return [Link](out_path)
else:
[Link]()
return None
# ==== RUN: EPU vs INF (đọc dữ liệu, tính & xuất file) ====
INPUT_PATH = "/Users/phamhuuhien/Downloads/[Link]"
OUTDIR = "/Users/phamhuuhien/PycharmProjects/Dulieu chứng
khoán /.venv/te_outputs_notebook"
[Link](OUTDIR, exist_ok=True)
df = pd.read_csv(INPUT_PATH, parse_dates=["Time"], index_col="Time")
[Link] = [Link]()
x = df["EPU_MoM"].dropna()
y = df["INF_MoM"].dropna()
# tham số WTC
wtc_kwargs = dict(dt=1.0, wavelet='cmor1.5-1.0',
min_scale=2, max_scale=128, num_scales=64,
smooth_t=3, smooth_s=3)
print("⏳ Computing WTC & p-values (circular-shift)...")
coh, phase, period, times, pvals = wtc_pvals_circular(x, y,
n_perm=500, seed=42, **wtc_kwargs)
out_file = [Link](OUTDIR, "WTC_EPU_INF_Rstyle.png")
plot_wtc_rstyle(coh, phase, period, times,
title="Wavelet coherence Europe: EPU_INF",
out_path=out_file, pvals=pvals, alpha=0.05,
cmap='jet', show_phase=True, stride_t=8, stride_s=2,
coi_factor=1.0, y_log2=False)
Đồ thị WTC
import os
import numpy as np
import pandas as pd
import [Link] as plt
import pywt
# ================== (BỔ SUNG) HÀM MONTE-CARLO CIRCULAR-SHIFT
==================
def _mc_circular_pvals_for_power(x, scales, wavelet, dt,
n_perm=1000, seed=42, use_coi=True):
x = [Link](x, float)
x = x - [Link](x)
n = len(x)
coef, freqs = [Link](x, scales, wavelet, dt) #
[n_scales, n_time]
power_obs = [Link](coef) ** 2
period = 1.0 / [Link](freqs, 1e-12)
# COI mask nhất quán với cách vẽ hiện tại của bạn (dựa trên
khoảng cách tới biên)
n_time = power_obs.shape[1]
t = [Link](n_time) * dt
dist = [Link]([Link](n_time), [Link](n_time)[::-1]) *
dt
# Trong code vẽ, bạn dùng "1.5 * dist" để vẽ đường cong COI
# Ta quy ước: ngoài COI khi PERIOD <= 1.5 * dist (tức nằm dưới
đường cong)
coi_threshold = 1.5 * dist # shape [n_time]
coi_mask = np.zeros_like(power_obs, dtype=bool)
for i in range(len(scales)):
coi_mask[i, :] = period[i] <= [Link](coi_threshold,
[Link](), [Link]())
# Monte-Carlo circular-shift
rng = [Link].default_rng(seed)
ks = [Link](1, n, size=n_perm)
ge = np.zeros_like(power_obs, dtype=int) # đếm số surrogate >=
observed
for k in ks:
x_s = [Link](x, k)
c_s, _ = [Link](x_s, scales, wavelet, dt)
p_s = [Link](c_s) ** 2
ge += (p_s >= power_obs).astype(int)
pvals_mc = (ge + 1.0) / (n_perm + 1.0)
if use_coi:
pvals_mc = [Link](coi_mask, pvals_mc, [Link])
return pvals_mc, None, freqs, period, power_obs, coi_mask
# ================== (GIỮ NGUYÊN + BỔ SUNG TUỲ CHỌN MONTE-CARLO)
==============
def plot_cwt_rstyle(series, wavelet='cmor1.5-1.0', dt=1.0,
min_scale=2, max_scale=128, num_scales=64,
title=None, out_path=None,
cmap='jet', show_coi=True,
# --------- (BỔ SUNG) TUỲ CHỌN MONTE-CARLO
----------
mc_enable=True, n_perm=1000, alpha=0.05,
mc_out_csv=None):
# --- Xử lý dữ liệu ---
x = [Link] - [Link]([Link])
t = [Link](len(x)) * dt
n_time = len(t)
# --- Tạo scales và CWT ---
scales = [Link](min_scale, max_scale, num_scales)
coef, freqs = [Link](x, scales, wavelet, dt)
power = [Link](coef) ** 2
period = 1.0 / freqs
# --- Biên độ theo log2 ---
power_log = np.log2(power + 1e-6)
# --- (BỔ SUNG) TÍNH p-VALUE MONTE-CARLO + MẶT NẠ Ý NGHĨA ---
pvals_mc = None
mask_sig = None
coi_mask = np.ones_like(power, dtype=bool)
if mc_enable:
pvals_mc, _, freqs_mc, period_mc, power_obs, coi_mask =
_mc_circular_pvals_for_power(
x, scales, wavelet, dt, n_perm=n_perm, seed=42,
use_coi=True
)
# p-value < alpha ⇒ có ý nghĩa
mask_sig = (pvals_mc < alpha)
# (tuỳ chọn) xuất CSV phẳng
if mc_out_csv is not None:
[Link]([Link](mc_out_csv), exist_ok=True)
idx_scale = [Link]([Link](len(scales)), n_time)
idx_time = [Link]([Link](n_time), len(scales))
df_out = [Link]({
"scale_idx": idx_scale,
"time_idx": idx_time,
"scale": scales[idx_scale],
"freq": freqs[idx_scale],
"period": period[idx_scale],
"power": [Link](),
"p_mc": (pvals_mc.ravel() if pvals_mc is not None else
[Link]),
"sig_mc": (mask_sig.ravel().astype(int) if mask_sig is
not None else 0)
})
df_out.to_csv(mc_out_csv, index=False)
# --- Tạo figure ---
fig, ax = [Link](figsize=(9.5, 5))
extent = [t[0], t[-1], [Link](period), [Link](period)]
# --- Màu (jet) ---
im = [Link](power_log, extent=extent, aspect='auto',
origin='lower',
cmap=cmap, interpolation='bilinear')
# --- Contour đường mức ---
levels = [Link](power_log.min(), power_log.max(), 10)
[Link](t, period, power_log, levels=levels, colors='k',
linewidths=0.4, alpha=0.5)
# --- (BỔ SUNG) VẼ CONTOUR Ý NGHĨA MONTE-CARLO p<alpha ---
if mc_enable and (mask_sig is not None):
# Vẽ viền trắng đứt nét cho vùng có ý nghĩa (ngoài COI)
# Lưu ý: mask_sig đang cùng shape với (scale×time); ta cần
contour theo (t, period)
[Link](t, period, mask_sig.astype(float), levels=[0.5],
colors='white', linewidths=1.2, linestyles='--')
# --- Log scale trục Y ---
ax.set_yscale('log', base=2)
ax.set_ylabel("Period (months)")
ax.set_xlabel("Time")
ax.set_title(title if title else "Continuous wavelet transform",
fontsize=12, weight='bold')
# --- Màu & colorbar ---
cbar = [Link](im, ax=ax, orientation='vertical')
cbar.set_label('Wavelet Power (log₂ scale)')
# --- Nhãn trục X theo năm ---
ticks = [Link](0, n_time - 1, 6).astype(int)
ax.set_xticks(ticks)
labels = pd.to_datetime([Link]).strftime('%Y')
ax.set_xticklabels(labels[ticks], rotation=0)
# --- Vẽ Cone of Influence (COI) chuẩn hình R ---
if show_coi:
# Độ sâu cong tỷ lệ 1.5 để giống R
dist = [Link]([Link](n_time), [Link](n_time)[::-1])
* dt
coi_curve = [Link](1.5 * dist, [Link](), [Link]())
[Link](t, coi_curve, color='k', lw=1.0)
[Link](t, coi_curve[::-1], color='k', lw=1.0)
# Tô vùng ngoài COI nhạt đi
ax.fill_between(t, coi_curve, [Link](), color='white',
alpha=0.4, hatch='//', lw=0)
ax.invert_yaxis() # R-style: scale lớn ở dưới
plt.tight_layout()
if out_path:
[Link]([Link](out_path), exist_ok=True)
[Link](out_path, dpi=180, bbox_inches='tight')
[Link]()
print(f"✅ Wavelet plot saved to: {[Link](out_path)}")
return [Link](out_path)
else:
[Link]()
return None
# === Đọc dữ liệu ===
df = pd.read_csv(
"/Users/phamhuuhien/Downloads/[Link]",
parse_dates=["Time"], index_col="Time"
)
[Link] = [Link]()
series = df["INF_MoM"].dropna()
# === Xuất đồ thị ===
OUTDIR = "/Users/phamhuuhien/PycharmProjects/Dulieu chứng
khoán /.venv/te_outputs_notebook"
[Link](OUTDIR, exist_ok=True)
out_file = [Link](OUTDIR, "CWT_INFMoM_USA_Rstyle.png")
out_csv_mc = [Link](OUTDIR, "Kiểm định power INF_USA.csv")
# --- GỌI HÀM (giữ nguyên mọi tham số cũ, chỉ bật Monte-Carlo) ---
plot_cwt_rstyle(
series,
wavelet='cmor1.5-1.0',
dt=1.0,
min_scale=2,
max_scale=128,
num_scales=64,
title="Continuous wavelet transform: USA_INF",
out_path=out_file,
cmap='jet', # giống màu R: xanh→vàng→đỏ
show_coi=True,
# ---- BẬT MONTE-CARLO ----
mc_enable=True, n_perm=1000, alpha=0.05,
mc_out_csv=out_csv_mc
)
Xuất kết quả WTC
def wtc_table_from_arrays(
coh, phase, period, times,
pvals=None, alpha=0.05, min_run=5,
x_label="EPU", y_label="INF"
):
import numpy as np, pandas as pd
n_s, n_t = [Link]
if len(period) != n_s:
raise ValueError("period length must match [Link][0]")
times = pd.to_datetime(times) # phòng khi là array thường
# Mặt nạ ý nghĩa: ưu tiên p-value, fallback theo ngưỡng coherence
if pvals is not None:
sig = (pvals < alpha) & [Link](coh)
else:
sig = (coh >= 0.7) & [Link](coh)
def _runs(row_bool, k=3):
out = []
i, n = 0, len(row_bool)
while i < n:
if row_bool[i]:
j = i
while j + 1 < n and row_bool[j + 1]:
j += 1
if j - i + 1 >= k:
[Link]((i, j))
i = j + 1
else:
i += 1
return out
rows = []
for s in range(n_s):
for c0, c1 in _runs(sig[s], k=min_run):
coh_seg = coh[s, c0:c1+1]
ph_seg = phase[s, c0:c1+1]
# circular mean of phase
C = float([Link]([Link](ph_seg)))
S = float([Link]([Link](ph_seg)))
phi = float(np.arctan2(S, C))
lead = f"{x_label}→{y_label}" if S < 0 else
(f"{y_label}→{x_label}" if S > 0 else "undetermined")
relation = "in-phase" if C >= 0 else "anti-phase"
[Link]({
"scale_idx": s,
"period": float(period[s]),
"period_band": None, # sẽ gán bên dưới
"time_start": pd.to_datetime(times[c0]),
"time_end": pd.to_datetime(times[c1]),
"n_points": int(c1 - c0 + 1),
"coh_mean": float([Link](coh_seg)),
"coh_max": float([Link](coh_seg)),
"phase_mean_deg": float([Link](phi)),
"relation": relation,
"lead_direction": lead,
"convention": "phi = phase_x − phase_y",
"x_label": x_label,
"y_label": y_label,
})
df_tbl = [Link](rows)
# Gắn nhãn band (kiểu 2–4, 4–8, 8–16, ...)
if not df_tbl.empty:
edges = [2, 4, 8, 16, 32, 64, 128, 256]
def _band(p):
for i in range(1, len(edges)):
if edges[i-1] < p <= edges[i]:
return f"{edges[i-1]}–{edges[i]}"
return f">{edges[-1]}"
df_tbl["period_band"] = df_tbl["period"].apply(_band)
df_tbl = df_tbl.sort_values(
["coh_mean", "coh_max", "n_points"],
ascending=[False, False, False]
).reset_index(drop=True)
return df_tbl
# TẠO BẢNG TỪ KẾT QUẢ VỪA TÍNH
table = wtc_table_from_arrays(
coh, phase, period, times,
pvals=pvals, alpha=0.05, min_run=5,
x_label="EPU", y_label="INF"
)
# In nhanh vài dòng đầu
print("=== WTC summary (top 20) ===")
print([Link](20).to_string(index=False))
# LƯU RA FILE
csv_path = [Link](OUTDIR, "WTC_summary_EPU_INF.csv")
xlsx_path = [Link](OUTDIR, "WTC_summary_EPU_INF.xlsx")
table.to_csv(csv_path, index=False, encoding="utf-8-sig")
with [Link](xlsx_path, engine="xlsxwriter") as writer:
table.to_excel(writer, sheet_name="WTC_summary", index=False)
print(f"📄 Saved CSV: {csv_path}")
print(f"📄 Saved XLSX: {xlsx_path}")
Statis + root
import pandas as pd
import numpy as np
# giữ nguyên các import của bạn; thêm statsmodels để chạy ADF/ZA
from [Link] import adfuller, zivot_andrews
# === Cấu hình ===
INPUT_PATH = r""
OUTPUT_XLSX = r""
# === Đọc dữ liệu ===
df = pd.read_csv(INPUT_PATH)
num_df = df.select_dtypes(include=[[Link]])
# === Tính ADF, ZA và điểm gãy ===
t = pd.to_datetime(df["Time"])
def star(p):
return "***" if p < 0.01 else "**" if p < 0.05 else "*" if p < 0.10 else
""
rows = []
for c in num_df.columns: # ví dụ: EPU, CPI, INF_MoM, EPU_MoM
s = [Link](pd.to_numeric(df[c], errors="coerce").values,
index=t).dropna()
adf_stat, adf_p, *_ = adfuller([Link], autolag="AIC")
za_stat, za_p, *_ , bp = zivot_andrews([Link], regression="c",
autolag="AIC")
[Link]({
"Variable": c,
"ADF": f"{adf_stat:.2f}{star(adf_p)}",
"ZA": f"{za_stat:.2f}{star(za_p)}",
"Structural Break": [Link][int(bp)].strftime("%Y:%B")
})
summary = [Link](rows, columns=["Variable", "ADF", "ZA", "Structural
Break"])
# === In ra màn hình ===
print(summary)
# === Xuất ra Excel ===
summary.to_excel(OUTPUT_XLSX, index=False, sheet_name="Summary")
print(f"\n✅ File đã được lưu tại: {OUTPUT_XLSX}")
import pandas as pd
import numpy as np
from [Link] import jarque_bera, skew, kurtosis
from [Link] import adfuller, zivot_andrews
# === Cấu hình ===
INPUT_PATH = r""
OUTPUT_XLSX = r""
# === Đọc dữ liệu ===
df = pd.read_csv(INPUT_PATH)
num_df = df.select_dtypes(include=[[Link]])
# === Tính thống kê mô tả ===
rows = []
for c in num_df.columns:
s = num_df[c].dropna().astype(float)
if len(s) < 3:
continue
jb_stat, jb_p = jarque_bera(s)
[Link]({
"Variable": c,
"Mean": round([Link](), 4),
"SD": round([Link](ddof=1), 4),
"JB": f"{jb_stat:.4f} [{jb_p:.4f}]",
"Skewness": round(skew(s, bias=False), 4),
"Kurtosis": round(kurtosis(s, fisher=False, bias=False), 4)
})
summary = [Link](rows, columns=["Variable", "Mean", "SD", "JB",
"Skewness", "Kurtosis"])
# === In ra màn hình ===
print(summary)
# === Xuất ra Excel ===
summary.to_excel(OUTPUT_XLSX, index=False, sheet_name="Summary")
print(f"\n✅ File đã được lưu tại: {OUTPUT_XLSX}")
prompt
Đại 23/10 : kiểm tra kết quả đầu ra
bây giờ bạn hãy là một nhà nghiên cứu khoa học,
hãy kiểm tra xem các công thức và các bước xử lý dữ liệu và tính toán của tôi có hợp lý để
cho ra kết qủa thực tế được không?
các số liệu đầu vào của tôi đã được xử lý sạch sẽ.
Hãy là một python coder chuyên nghiệp và là một nhà nghiên cứu về lĩnh vực kiểm định,
tính toán wavelet với kinh nghiệm 30 năm hãy giúp tôi làm điều sau:
+ giữ nguyên cách tính toán và trình bày của đoạn code của tôi và hãy thêm phần AME
( Average marginal effect ) và phần kiểm định cho AME đó để tôi có thể thấy được mức độ
tưởng quan giữa 2 biến EPU và INF là như thế nào.
+ Kết quả xuất ra bao gồm các biến: Scale_Range Scale_Level Direction TE
p_value AME_mean AME_pos_share AME_CI95 AME_p
24/10:
Hãy là một chuyên gia python coder chuyên nghiệp, hãy giúp tôi hoàn thiện đoạn code với
yêu cầu sau:
1. Dữ liệu đầu vào tôi đã xử lý sạch sẽ, gồm 3 biến đó là Time, EPU_MoM, INF_MoM. Các
dữ liệu được chạy theo thời gian Month to Month.
2. Khung của bài code sẽ thực hiện theo những bước sau:
CWT/XWT/WTC với Morlet, band chuẩn, COI.
Ý nghĩa WTC bằng AR(1)/surrogate, đánh dấu ô vượt ngưỡng.
Pha và tính nhất quán hướng trong ô ý nghĩa.
TE hai chiều theo band + permutation p, lấy Net TE và Direction.
AME từ mô hình hồi quy, báo AME_mean, CI95, p, pos_share.
FDR cho p vì test nhiều band.
Xuất CSV đúng schema bạn yêu cầu.
3. Code phải được tối ưu và ngắn gọn, trình bày logic và khoa học
4. Tôi cung cấp file dữ liệu đầu vào và thông tin ở đầu ra:
INPUT_PATH = "/Users/phamhuuhien/Downloads/[Link]"
OUTDIR = "/Users/phamhuuhien/PycharmProjects/Dulieu chứng khoán
/.venv/te_outputs_notebook"
[Link](OUTDIR, exist_ok=True)
# Tham số TE
N_BINS = 6
LAG = 1
N_PERM = 2000 # <--- nặng, điều chỉnh ở Cell 6 khi chạy year-grid
RANDOM_STATE = 42
# Tham số WTC
dt = 1.0
min_scale = 2
max_scale = 256
num_scales = 96
5. Khi viết hãy trình bày thành 3 cells, cell 1: Dữ liệu đầu vào, cell 2: Xử lý và tính toán dữ
liệu, cell 3: xuất dữ liệu. Ở cell 2 và cell 3 tôi cần những kết quả sau: Period N_BINS
LAG Wavelet Scale_Range Scale_Level Direction TE p_value
AME_mean AME_pos_share AME_CI95 AME_p coh_mean coh_max
x_label y_label
6. Chỉ nhận các kết quả quả thoả 1 trong các điều kiện sau: coh>0.7, pvalue<0.06
7. Tổng các khoảng thời gian tôi muốn chạy là toàn bộ giai đoạn trong file dữ liệu đầu vào
20h 24/10:
Hãy luôn trung thực và thể hiện tính chuyên nghiệp khi bắt đầu nghiên cứu với tôi Từ giờ
bạn là nhà khoa học chuyên nghiên cứu về kinh tế và là một chuyên gia python coder
chuyên nghiệp. Nhiệm vụ của bạn là giúp tôi hoàn thành một bài code để tính tương quan
về kinh tế. Sau khi bạn sẵn sàng tôi sẽ bắt đầu giao nhiệm vụ cho bạn
In dữ liệu
# ==== CELL 3: XUẤT DỮ LIỆU ====
out_csv = [Link](OUTDIR, "wtc_te_summary_china bin=[Link]")
summary_df.to_csv(out_csv, index=False)
# Gợi ý thêm: nếu muốn xem top scale có ý nghĩa nhất ở mỗi hướng
def top_scales(df, direction, k=10):
sub = df[df["Direction"] == direction].copy()
sub = sub.sort_values(["p_value", "TE"], ascending=[True, False])
return [Link](k)
print("Đã lưu:", out_csv)
print("Top EPU→INF:")
print(top_scales(summary_df, f"{x_label}->{y_label}", k=5))
print("\nTop INF→EPU:")
print(top_scales(summary_df, f"{y_label}->{x_label}", k=5))