通过调用Akshare提供的接口,可以得到当日的分笔成交明细,据此绘制当日的成交分价表,信息全面一些。
单独开一帖,希望能帮到那些需要的人。
看到有人需要打包后的软件,请自取。说明:下载的csv文件保存在D:\STOCKDETAIL目录下,生成的图像保存在:D:\DRAW目录下。
一个简单的界面,输入股票代码和股票名称,点击按钮“开始生成”即可。
通过网盘分享的文件:股票分价表软件
链接: https://pan.baidu.com/s/18CL60g49UX7xaOaT2djfMA?pwd=52pj 提取码: 52pj[i]
[Python] 纯文本查看 复制代码# !/usr/bin/env python
# coding=utf-8`
import asyncio
import os
import warnings
from datetime import datetime
import akshare as ak
import kaleido
import pandas as pd
import plotly.express as px
warnings.filterwarnings("ignore")
def get_stock_intraday_data(code, name):
stock_intraday_em_df = ak.stock_intraday_em(symbol=code)
pivot = pd.pivot_table(
stock_intraday_em_df,
values='手数',
index='成交价',
columns='买卖盘性质',
aggfunc='sum',
fill_value=0
)
pivot['总手数'] = pivot.sum(axis=1)
pivot.columns.name = None
if '中性盘' not in pivot.columns:
pivot.insert(3, '中性盘', 0)
if '买盘' not in pivot.columns:
pivot.insert(2, '买盘', 0)
result = pivot.reset_index()[['成交价', '总手数', '买盘', '中性盘', '卖盘']]
result.insert(0, '日期', datetime.now().strftime("%Y-%m-%d"))
file_name = f"D:\\stockdata\\stockdetail\\{code}.csv"
result.to_csv(file_name, mode="w", header=True, encoding="gbk", index=False)
return
def plot_stock_intraday(code, name):
file_name = f"D:\\stockdata\\stockdetail\\{code}.csv"
df = pd.read_csv(file_name, encoding="gbk", dtype={'成交价': float}, engine='pyarrow')
df['成交价'] = df['成交价'].round(2)
df['成交价'] = df['成交价'].apply(lambda x: ('%g' % x))
total_buy = df['买盘'].sum()
total_sell = df['卖盘'].sum()
total_neutral = df['中性盘'].sum()
# 根据买盘和卖盘占比大小,确定bar显示顺序
if total_buy >= total_sell:
df_long = df.melt(
id_vars='成交价',
value_vars=['买盘', '中性盘', '卖盘'],
var_name='买卖盘性质',
value_name='手数'
)
else:
df_long = df.melt(
id_vars='成交价',
value_vars=['卖盘', '中性盘', '买盘'],
var_name='买卖盘性质',
value_name='手数'
)
price_totals = (
df_long.groupby('成交价')['手数']
.sum()
.reset_index(name='price_hand')
)
day_total_hand = price_totals['price_hand'].sum()
buy_pct = round(total_buy/day_total_hand * 100, 2)
sell_pct = round(total_sell/day_total_hand * 100, 2)
neutral_pct = round(total_neutral/day_total_hand * 100, 2)
price_totals['ratio'] = price_totals['price_hand'] / day_total_hand * 100
price_totals['ratio_str'] = price_totals['ratio'].map(lambda x: f"{x:.2f}%")
price_totals = price_totals.sort_values(
by="成交价", key=lambda s: s.astype(float), ascending=False
).reset_index(drop=True)
valid_prices = sorted(price_totals['成交价'].unique())
price_order_str = price_totals['成交价'].astype(str).tolist()
fig = px.bar(
df_long,
y='成交价', # Y轴为成交价
x='手数', # X轴为手数
color='买卖盘性质',
orientation='h', # 水平方向
color_discrete_map={
'买盘': '#FF4500', # 红色
'中性盘': '#00BFFF', # 蓝色
'卖盘': '#228B22' # 绿色
},
category_orders={'成交价': price_order_str},
labels={'手数': '手数', '成交价': '成交价'},
title=f"{code} {name}" + ' 分价表 日期;' + df['日期'].iloc[-1].strftime('%Y-%m-%d') +
" 卖盘占比:" + str(sell_pct) + "%, 中性盘占比:" + str(neutral_pct) + "%, 买盘占比:" + str(buy_pct) + "%",
)
fig.update_yaxes(
type='category',
categoryorder='array',
categoryarray=price_order_str,
)
ratio_text_aligned = price_totals.set_index('成交价').loc[valid_prices, 'ratio_str'].tolist()
# 根据买盘和卖盘占比大小,确定文字显示位置
if total_buy >= total_sell:
fig.update_traces(
selector=dict(name='卖盘'),
text=ratio_text_aligned,
textposition='outside',
textfont=dict(color='black')
)
else:
fig.update_traces(
selector=dict(name='买盘'),
text=ratio_text_aligned,
textposition='outside',
textfont=dict(color='black')
)
fig.update_layout(
xaxis_title='手数',
yaxis_title='成交价',
bargap=0.15,
bargroupgap=0.1,
barmode='stack',
font=dict(family='SimHei', color="black"),
# yaxis_tickfont_size=6,
hovermode='y unified',
)
# fig.show() # 显示图片
# 输出目录, 请自行调整
output_path = os.path.join("D:\\akstock\\draw\\板块\\", f"{code}{name} 分价表.png")
# width, height 根据显示器的显示分辨率调整
asyncio.run(kaleido.write_fig(fig, path=output_path,
opts={"format": "png", "width": 3840, "height": 2160, "scale": 3}))
return
if __name__ == '__main__':
get_stock_intraday_data("002952", "亚世光电")
plot_stock_intraday("002952", "亚世光电")