Dymay
Dymay
发布于 2024-12-08 / 19 阅读
0
0

【技术】数据的获取与简单分析:以上证指数为例

一个简单的入门尝试

数据的获取

以同花顺软件为例,进入上证指数或者你选择的个股页面,在分时走势这一列切换到日走势(这决定了之后获取的数据时间间隔):

然后按 F1 进入如下界面(按 F3 可切回走势页面):

记录了每日的开盘收盘价、最高最低价、涨跌振幅以及总手数和成交金额,右键导出输出数据选择路径即可。自动保存的格式为.xls,但实际上是.csv,所以会跳出格式与文件后缀不符合,可以先以.xls打开检查一下如上图即正常。

那么有了数据可以先试着自己简单可视化一下,采用 mplfinance 库可以简单绘制K线图:

import pandas as pd
import mplfinance as mpf
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties

# 设置中文字体
font = FontProperties(fname='C:/Windows/Fonts/simsun.ttc')  

# 读取csv文件
file_path = 'data/000001.csv'
df = pd.read_csv(file_path, encoding='gbk', sep='\t')

# 去除列名中的空格
df.columns = df.columns.str.strip()

# 提取日期信息并去除星期信息
df['日期'] = df['时间'].str.split(',').str[0]

# 将日期列转换为日期格式
df['日期'] = pd.to_datetime(df['日期'], format='%Y-%m-%d')

# 设置日期为索引
df.set_index('日期', inplace=True)

# 重命名列以符合mplfinance的要求
df.rename(columns={'收盘': 'Close', '最高': 'High', '最低': 'Low', '开盘': 'Open', '总手(万)': 'Volume'}, inplace=True)

# 筛选并打印从2024年开始的数据
df_2024 = df[df.index >= '2024-01-01']

# 自定义样式
mc = mpf.make_marketcolors(up='red', down='green', edge='i', wick='i', volume='in', inherit=True)
s = mpf.make_mpf_style(marketcolors=mc, gridstyle='-', gridcolor='gray', facecolor='lightgray')

# 绘制K线图和成交量
fig, axes = plt.subplots(3, 1, sharex=True, gridspec_kw={'height_ratios': [3, 1, 1]})

mpf.plot(df_2024, type='candle', style=s, ax=axes[0], volume=axes[1], show_nontrading=False)

# 设置标题和标签的字体
axes[0].set_title('K线图', fontproperties=font)
axes[0].set_ylabel('价格', fontproperties=font)
axes[1].set_ylabel('成交量', fontproperties=font)
axes[1].set_xlabel('日期', fontproperties=font)

axes[0].grid(True)
axes[1].grid(True)

plt.show()

以2024年1月1日开始的数据绘制,效果如下:

接着可以试着加入简单计算移动平均线(MA)、相对强弱指数(RSI)和布林带(Bollinger Bands)并打印在图标中。

移动平均线(MA)

移动平均线(Moving Average, MA)是一种技术分析工具,用于平滑价格数据,以便更容易识别价格趋势。它通过计算特定时间段内价格的平均值来实现这一点。常见的移动平均线包括简单移动平均线(SMA)和指数移动平均线(EMA)。

  • 简单移动平均线(SMA):计算特定时间段内价格的算术平均值。例如,20日简单移动平均线(MA20)是过去20天收盘价的平均值。

  • 加权移动平均线(WMA):对最近的价格数据赋予更高的权重,权重按线性降低

  • 指数移动平均线(EMA):对最近的价格数据赋予更高的权重,权重按指数降低

通常所说的五日均线(M5)、十日均线(M10)等等就是指五日、十日的简单移动均线。

# 计算移动平均线
df_2024['MA20'] = df_2024['Close'].rolling(window=20).mean()

简单的移动平均线有时过于简单,当价格出现剧烈波动时效果不佳。加权移动平均线则赋予最近时期更多的权重。

故权重通常是一个递增的序列。例如,对于一个窗口大小为 n 的WMA,权重可以是 1, 2, 3, ..., n

计算加权和:将每个数据点乘以其对应的权重,然后求和。

计算权重总和:将所有权重相加。

计算加权平均:将加权和除以权重总和,得到加权移动平均值。

# 计算加权移动平均线(WMA)
def weighted_moving_average(values, window):
    weights = np.arange(1, window + 1)
    return np.convolve(values, weights[::-1], 'valid') / weights.sum()

df_2024['WMA20'] = np.nan
df_2024['WMA20'].iloc[19:] = weighted_moving_average(df_2024['Close'], 20)

np.convolve(a, v, mode='full')

  • a:第一个输入数组。

  • v:第二个输入数组(通常是权重数组)。

  • mode:指定卷积的模式,可以是以下值之一:

    • 'full':返回完整的卷积结果,长度为 len(a) + len(v) - 1

    • 'valid':返回有效的卷积结果,长度为 len(a) - len(v) + 1

    • 'same':返回与输入数组 a 长度相同的卷积结果。

weights[::-1] 是一种使用切片操作来反转数组的方式。

假设有一个权重数组 weights,其值为 [1, 2, 3]。反转这个数组后,你会得到 [3, 2, 1]。这样,当你使用 np.convolve 进行卷积操作时,最近的数据点会乘以最大的权重,而最早的数据点会乘以最小的权重。

EMA的计算公式如下:

\text{EMA}_t = \alpha \cdot P_t + (1 - \alpha) \cdot \text{EMA}_{t-1}

其中:

  • \text{EMA}_t 是当前时刻的EMA值。

  • P_t 是当前时刻的价格。

  • \alpha 是平滑系数,通常计算为 \displaystyle\alpha = \frac{2}{N+1},其中 N 是时间窗口大小。

# 计算指数移动平均线(EMA)
def exponential_moving_average(values, window):
    alpha = 2 / (window + 1)
    ema = [values[0]]  # 初始值为第一个价格
    for price in values[1:]:
        ema.append(alpha * price + (1 - alpha) * ema[-1])
    return np.array(ema)

df_2024['EMA20'] = exponential_moving_average(df_2024['Close'], 20)

以今年十月的大涨就可以看出简单20日均线(蓝色)和加权20日均线(橙色)以及指数20日均线(紫色)的对于价格剧烈变化的效果区别:

相对强弱指数(RSI)

相对强弱指数(Relative Strength Index, RSI)是一种动量振荡指标,用于衡量价格变动的速度和变化。RSI的值在0到100之间波动,通常用来识别超买或超卖的市场条件。

  • 计算方法:RSI通常基于14个交易日的价格数据计算。公式如下:

    RSI = 100 - \left( \frac{100}{1 + RS} \right)

    其中,RS(相对强弱)是平均上涨幅度与平均下跌幅度的比值:

    RS = \frac{\text{平均上涨幅度}}{\text{平均下跌幅度}}
  • RSI值超过70通常被认为是超买(即RS>2.333,上涨幅度大),可能意味着价格即将回调;RSI值低于30通常被认为是超卖(RS<0.426,下跌幅度大),可能意味着价格即将反弹。

# 计算相对强弱指数(RSI)
delta = df_2024['Close'].diff() # 计算价格变化差值
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() # 上涨量十四天滑动平均
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() # 下跌量十四天滑动平均
rs = gain / loss # 计算RS 
df_2024['RSI'] = 100 - (100 / (1 + rs)) # 计算 RSI

布林带(Bollinger Bands)

布林带(Bollinger Bands)由约翰·布林格(John Bollinger)发明,用于衡量市场的波动性。布林带由三条线组成:中轨线、上轨线和下轨线。

  • 中轨线:通常是特定时间段的简单移动平均线(SMA)。

  • 上轨线:中轨线加上两倍的标准差。

  • 下轨线:中轨线减去两倍的标准差。

  • 布林带的宽度反映了市场的波动性。当价格接近上轨线时,市场可能处于超买状态;当价格接近下轨线时,市场可能处于超卖状态。

# 计算布林带
df_2024['BB_Middle'] = df_2024['Close'].rolling(window=20).mean()
df_2024['BB_Upper'] = df_2024['BB_Middle'] + 2 * df_2024['Close'].rolling(window=20).std()
df_2024['BB_Lower'] = df_2024['BB_Middle'] - 2 * df_2024['Close'].rolling(window=20).std()

同时绘制到一张图表:


评论