背景
本文讲述的场景是,在获得股票或期货的行情数据以及自行分析出的额外数据后,进行数据分析并生成更直观的图表。
具体需求如下:
- 生成简单的K线蜡烛图。
- 对单独的K线进行着色:默认情况下,涨幅用红色表示,跌幅用绿色表示;对于拐点或异常点,需要用特殊颜色标记,以引起特别关注。
- 使用额外的数据生成图形,以观察拟合度,寻找潜在的规律。
说明
使用的开发语言主要是 Python,用的包主要有 pandas 和 mplfinance。
代码
日线行情数据说明
随便在网上下载一份日线数据,我这里下载的期货市场螺纹钢的日线数据,整理成rb.csv 文件,格式如下:
date,open,high,low,close,volume
20241029,3450,3460,3411,3422,1928067
20241028,3380,3479,3372,3451,2997381
20241025,3332,3389,3329,3376,2617330
20241024,3307,3340,3290,3330,2641100
20241023,3342,3362,3308,3316,2479153
20241022,3358,3367,3300,3349,2735345
20241021,3350,3376,3335,3358,2416552
20241018,3311,3384,3284,3336,3902945
20241017,3450,3486,3300,3300,4903326
20241016,3470,3502,3444,3447,3479402
20241015,3499,3512,3461,3467,3584093
20241014,3472,3534,3436,3502,4049131
读取数据
import pandas as pd
daily = pd.read_csv('./data/rb.csv', index_col=0, parse_dates=True)
# 方便演示,按日期过滤
daily = daily.loc['2024-07-01':'2024-10-28'].iloc[::-1]
daily.info
设置中文环境
import matplotlib.pyplot as plt
import matplotlib as mpl
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['PingFang HK', 'Heiti TC']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.size'] = 12
mpl.rcParams['font.weight'] = 'normal'
自定义样式
import mplfinance as mpf
custom_style = mpf.make_mpf_style(
marketcolors=mpf.make_marketcolors(
up='red',
down='green',
edge='inherit',
wick='inherit',
volume='in',
ohlc='inherit'
),
gridstyle=':',
gridcolor='gray',
rc={
'font.family': plt.rcParams['font.family'],
'font.sans-serif': plt.rcParams['font.sans-serif']
}
)
画K线图
代码
mpf.plot(
daily,
type='candle',
title='螺纹钢期货日线趋势图',
ylabel='价格',
ylabel_lower='成交量',
volume=True,
style=custom_style,
figscale=1.5, # 图形尺寸缩放
figratio=(16,9), # 图形比例
panel_ratios=(3,1), # 主图与成交量图的高度比例为3:1
datetime_format='%Y-%m-%d', # 日期格式
xrotation=0, # x轴标签旋转角度
show_nontrading=False, # 不显示非交易日
tight_layout=False, # 自动调整布局
update_width_config=dict( # 控制蜡烛图的宽度
candle_linewidth=0.8, # 蜡烛图线宽
candle_width=0.6, # 蜡烛图宽度
volume_width=0.6 # 成交量柱宽度
),
mav=(5,10,20), # 均线
)
图形
给K线标颜色
代码
df_color = pd.DataFrame({
'index': daily.index,
'color': [None] * len(daily.index)
})
# 给 10-24,09-24,10-08,10-17 这四天分别设置不同的颜色
df_color.loc[df_color['index'] == '2024-10-24', 'color'] = 'black'
df_color.loc[df_color['index'] == '2024-09-24', 'color'] = 'purple'
df_color.loc[df_color['index'] == '2024-10-08', 'color'] = 'fuchsia'
df_color.loc[df_color['index'] == '2024-10-17', 'color'] = 'blue'
moc = df_color['color'].tolist()
mpf.plot(
daily,
type='candle',
title='螺纹钢期货日线趋势图',
ylabel='价格',
ylabel_lower='成交量',
volume=True,
style=custom_style,
figscale=1.5, # 图形尺寸缩放
figratio=(16,9), # 图形比例
panel_ratios=(3,1), # 主图与成交量图的高度比例为3:1
datetime_format='%m-%d', # 日期格式
xrotation=45, # x轴标签旋转角度
show_nontrading=False, # 不显示非交易日
tight_layout=False, # 自动调整布局
update_width_config=dict( # 控制蜡烛图的宽度
candle_linewidth=0.8, # 蜡烛图线宽
candle_width=0.6, # 蜡烛图宽度
volume_linewidth=0.8, # 成交量线宽
volume_width=0.6 # 成交量柱宽度
),
# mav=(5,10,20),
marketcolor_overrides=moc,
mco_faceonly=False,
)
图形
给K线加图形
准备额外的数据
from scipy import stats
import numpy as np
# 加载数据
# df_industry = pd.read_csv('./data/industry.csv', index_col=0, parse_dates=True)
# df_industry = df_industry.loc['2024-07-01':'2024-11-01']
# 生成模拟数据
df_industry = pd.DataFrame({
'date': daily.index,
'data': [None] * len(daily.index)
})
df_industry.set_index('date', inplace=True)
df_industry['data'] = np.random.randint(1, 101, size=len(daily.index))
清洗数据
# 清洗数据
df_industry['data'] = df_industry['data'].fillna(0)
# 找出异常值
# 利用标准差来衡量数据点与均值的偏离程度
z_scores = stats.zscore(df_industry['data'])
threshold = 1.5
outliers = df_industry[(z_scores > threshold) | (z_scores < -threshold)]
# 排除掉异常值
df_no_outliers = df_industry[(z_scores < threshold) & (z_scores > -threshold)]
# 计算上下限
threshold_outliers = threshold * 2
mean = df_no_outliers['data'].mean()
std_dev = df_no_outliers['data'].std()
lower_bound = mean - threshold_outliers * std_dev
upper_bound = mean + threshold_outliers * std_dev
# 限制图形的上下限范围,不限制的话可能会波动很大,这个逻辑看具体情况而设计
df_industry['data'] = df_industry['data'].clip(lower_bound, upper_bound)
print(lower_bound, upper_bound)
设置个别K线的颜色
df_color = pd.DataFrame({
'index': daily.index,
'color': [None] * len(daily.index)
})
# 设置异常值对应的K线颜色为蓝色
df_color.loc[df_color['index'].isin(outliers.index), 'color'] = 'blue'
moc = df_color['color'].tolist()
添加图形
# 添加根据额外数据生成的图形
apd = mpf.make_addplot(df_industry['data'], color='magenta', secondary_y=True)
生成
mpf.plot(
daily,
type='candle',
title='螺纹钢期货日线趋势图',
ylabel='价格',
ylabel_lower='成交量',
volume=True,
style=custom_style,
figscale=1.5, # 图形尺寸缩放
figratio=(16,9), # 图形比例
panel_ratios=(3,1), # 主图与成交量图的高度比例为3:1
datetime_format='%m-%d', # 日期格式
xrotation=45, # x轴标签旋转角度
show_nontrading=False, # 不显示非交易日
tight_layout=False, # 自动调整布局
update_width_config=dict( # 控制蜡烛图的宽度
candle_linewidth=0.8, # 蜡烛图线宽
candle_width=0.6, # 蜡烛图宽度
volume_linewidth=0.8, # 成交量线宽
volume_width=0.6 # 成交量柱宽度(与蜡烛图宽度保持一致)
),
# mav=(5,10,20),
marketcolor_overrides=moc,
mco_faceonly=False,
addplot=apd,
)
图形
总结
本文通过对股票和期货行情数据的简单分析和使用,详细描述如何用 Python 代码生成更直观的图形。通过简单的K线蜡烛图,可以清晰地展示市场走势,同时通过标色机制识别关键拐点和异常现象,帮助投资者做出更明智的决策。此外,结合额外数据进行拟合度分析,为探索潜在规律提供了有效的工具。然而,这一简单场景的分析在转向动态或更高级的功能时,将变得非常复杂和困难。因此,在设计和实现这些高级功能时,可能不再适合用这种实现方案,更多的可能是考虑用前端技术来实现比较合适。