python股票股价、正态分布检验,绘制直方图和正态分布曲线

#股价移动平均线系统,股价正态分布检验,绘制直方图和正态分布曲线
import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
from scipy import stats

# 设置字体
font_path = 'C:/Windows/Fonts/simhei.ttf'  # 黑体字体路径,根据实际情况修改
my_font = fm.FontProperties(fname=font_path)
plt.rcParams['font.family'] = my_font.get_name()
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False

# Get Kweichow Moutai data
stock_code = "600938"  # 贵州茅台
start_date = "20241201"
end_date = "20250523"
# ma_periods=[5, 10, 20, 30]
df = ak.stock_zh_a_hist(symbol=stock_code, period="daily", start_date=start_date, end_date=end_date, adjust="qfq")
df['日期'] = pd.to_datetime(df['日期'])
df.set_index('日期', inplace=True)
# Check if data retrieval failed or the DataFrame is empty
if df is None or df.empty:
    print("Failed to retrieve data or data is empty")
    # Exit the program early if data retrieval fails
    quit()

print(df.tail())
print(df.columns)
print(df['收盘'].describe())

# Calculate moving averages
windows = [5, 10, 20, 60, 120]
for w in windows:
    df[f'MA{w}'] = df['收盘'].rolling(window=w).mean()

df.fillna(method='ffill', inplace=True)

# Create a canvas
plt.figure(figsize=(12, 6))

# Plot the price and moving averages
plt.plot(df.index, df['收盘'], label='收盘价', alpha=0.5)
plt.plot(df.index, df['MA5'], label='5日均线', linestyle='--', linewidth=1)
plt.plot(df.index, df['MA10'], label='10日均线', linestyle=':', linewidth=1.5)
plt.plot(df.index, df['MA20'], label='20日均线', color='purple')
plt.plot(df.index, df['MA60'], label='60日均线', color='orange')
plt.plot(df.index, df['MA120'], label='120日均线', color='red')

# Add chart elements
plt.title(f'{stock_code} 股票价格移动平均线系统')
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

# Automatically rotate date labels
plt.gcf().autofmt_xdate()

# Display the chart
plt.show()

# 检验收盘价是否正态分布
_, p_value = stats.normaltest(df['收盘'])
alpha = 0.05
if p_value < alpha:
    print("收盘价不服从正态分布,进行对数变换")
    data = np.log(df['收盘'])
else:
    print("收盘价服从正态分布")
    data = df['收盘']

# 绘制直方图叠加正态分布曲线
plt.figure(figsize=(12, 6))
n, bins, patches = plt.hist(data, bins=30, density=True, alpha=0.5, label='直方图')

# 拟合正态分布
mu, std = stats.norm.fit(data)
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = stats.norm.pdf(x, mu, std)
plt.plot(x, p, 'k', linewidth=2, label='正态分布曲线')

# Add chart elements
plt.title(f'{stock_code} 股票价格{"对数" if p_value < alpha else ""}收盘价分布')
plt.xlabel(f'{"对数" if p_value < alpha else ""}股价')
plt.ylabel('概率密度')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.1)

# Automatically rotate date labels
plt.gcf().autofmt_xdate()

# Display the chart
plt.show()