记录一下常用的代码。
获取当前正在交易的合约。
前提:安装有掘金的客户端和相应的库。
目前,掘金支持上交所和深交所的股票交易标的查询以及从2005-01-01以来的交易数据。
安装好后,打开是这样的:
导入模块
如果仅仅是获取数据,那么只导入pandas和MyKlines(自定义的)模块就可以了。
其他模块,都是为了绘图而服务的。
'''
导入相关模块
==========================================================================================
'''
'''
导入相关模块
==========================================================================================
'''
print('开始运行...导入相关模块...')
import matplotlib.pyplot as plt # 绘图
import pandas as pd # 处理数据
import numpy as np # 处理数据
import datetime # 获取时间
import talib as tl # 计算指标
import os # 打开文件用
from pylab import mpl # 在图表中显示中文字体
import math # 取近似值
from MyKlines import * # 自定义的画K线、获取数据模块
#------------------------------------------------------------------
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 以黑体显示中文
mpl.rcParams['axes.unicode_minus'] = False # 解决负号-显示错误问题
#-----------------------------------------------------------------------------------------
print('-' * 78)
根据掘金的get_instruments()函数获取期货信息
主要用到掘金API里面的get_instruments()函数,获取在交易的所有数据,然后再自定义个函数,只返回需要的数据。
获取数据:
# 获取当前的时间
now = datetime.datetime.now()
now_str = now.strftime('%Y年%m月%d日 %H:%M:%S %A')
print(f'当前的时间是:{now_str}')
#-----------------------------------------------------------------------------------------
symbols = get_instruments(
symbols=None,
exchanges=None, # 上期所 默认None表示所有
sec_types=4, # 期货
names=None, # 默认None 表示所有
skip_suspended=True,
skip_st=True,
fields=None,
df=True #是否返回dataframe格式, 默认False, 返回list[dict]
)
# 上交所 SHSE
# 深交所 SZSE
# 中金所 CFFEX
# 上期所 SHFE
# 大商所 DCE
# 郑商所 CZCE
# 上海国际能源交易中心 INE
print(symbols)
print('-' * 80)
结果:
当前的时间是:2022年12月15日 11:12:14 Thursday
position symbol ... listed_date conversion_price
0 0 CFFEX.IC1902 ... 2018-12-24 00:00:00+08:00 0.0
1 0 CFFEX.IC1903 ... 2018-07-23 00:00:00+08:00 0.0
2 0 CFFEX.IC1904 ... 2019-02-18 00:00:00+08:00 0.0
3 0 CFFEX.IC1905 ... 2019-03-18 00:00:00+08:00 0.0
4 0 CFFEX.IC1906 ... 2018-10-22 00:00:00+08:00 0.0
... ... ... ... ... ...
3200 0 SHFE.zn2307 ... 2022-07-18 00:00:00+08:00 0.0
3201 0 SHFE.zn2308 ... 2022-08-16 00:00:00+08:00 0.0
3202 0 SHFE.zn2309 ... 2022-09-16 00:00:00+08:00 0.0
3203 0 SHFE.zn2310 ... 2022-10-18 00:00:00+08:00 0.0
3204 0 SHFE.zn2311 ... 2022-11-16 00:00:00+08:00 0.0
[3205 rows x 24 columns]
自定义函数:
def transform_data(data, contain='沥青', column_list=['sec_id', 'sec_name', 'listed_date', 'delisted_date']):
"""
说明:筛选合约
------------------------------------
变量:
data:pandas dataframe
contain:包含的字符串
column_list:需要的列
------------------------------------
返回:
data_choose:转换后的dataframe
------------------------------------
"""
# 筛选条件,返回True或False
# 包含BU的数据
choose = data['sec_name'].str.contains(contain)
data_choose = data[choose]
# 筛选需要的列
data_choose = data_choose[['sec_id', 'sec_name', 'listed_date', 'delisted_date']]
# 把日期改为字符串
# 把时间列转为字符串
data_choose.listed_date = data_choose.listed_date.apply(lambda x: x.strftime("%Y-%m-%d %H:%M:%S"))
data_choose.delisted_date = data_choose.delisted_date.apply(lambda x: x.strftime("%Y-%m-%d %H:%M:%S"))
# 把时间列转为时间格式
data_choose.listed_date = pd.to_datetime(data_choose.listed_date)
data_choose.delisted_date = pd.to_datetime(data_choose.delisted_date)
# 修改时间一列的列名
data_choose.rename(columns={
"sec_id": "ID",
"sec_name": "合约名称",
"listed_date": "上市日期",
"delisted_date": "退市日期",
},
inplace=True)
return data_choose
data = transform_data(data=symbols, contain='沥青')
print(data)
结果:
--------------------------------------------------------------------------------
ID 合约名称 上市日期 退市日期
2473 bu1902 石油沥青1902 2018-08-16 2019-02-15
2474 bu1903 石油沥青1903 2017-03-16 2019-03-15
2475 bu1904 石油沥青1904 2018-10-16 2019-04-15
2476 bu1905 石油沥青1905 2018-11-16 2019-05-15
2477 bu1906 石油沥青1906 2017-06-16 2019-06-17
... ... ... ... ...
2530 bu2311 石油沥青2311 2022-11-16 2023-11-15
2531 bu2312 石油沥青2312 2021-12-16 2023-12-15
2532 bu2403 石油沥青2403 2022-03-16 2024-03-15
2533 bu2406 石油沥青2406 2022-06-16 2024-06-17
2534 bu2409 石油沥青2409 2022-09-16 2024-09-18
[62 rows x 4 columns]
再筛选出当前正在交易的合约:
data = data[data['上市日期'].apply(lambda x: x < now)]
data = data[data['退市日期'].apply(lambda x: x > now)]
bu_list = data.ID.values
print(data)
print('-' * 80)
print(bu_list)
这样就获取到当前正在交易的期货合约的列表了。我这里选择的合约是石油沥青。
结果:
[62 rows x 4 columns]
ID 合约名称 上市日期 退市日期
2520 bu2301 石油沥青2301 2022-03-16 2023-01-16
2521 bu2302 石油沥青2302 2022-03-16 2023-02-15
2522 bu2303 石油沥青2303 2021-03-16 2023-03-15
2523 bu2304 石油沥青2304 2022-04-18 2023-04-17
2524 bu2305 石油沥青2305 2022-05-17 2023-05-15
2525 bu2306 石油沥青2306 2021-06-16 2023-06-15
2526 bu2307 石油沥青2307 2022-07-18 2023-07-17
2527 bu2308 石油沥青2308 2022-08-16 2023-08-15
2528 bu2309 石油沥青2309 2021-09-16 2023-09-15
2529 bu2310 石油沥青2310 2022-10-18 2023-10-16
2530 bu2311 石油沥青2311 2022-11-16 2023-11-15
2531 bu2312 石油沥青2312 2021-12-16 2023-12-15
2532 bu2403 石油沥青2403 2022-03-16 2024-03-15
2533 bu2406 石油沥青2406 2022-06-16 2024-06-17
2534 bu2409 石油沥青2409 2022-09-16 2024-09-18
--------------------------------------------------------------------------------
['bu2301' 'bu2302' 'bu2303' 'bu2304' 'bu2305' 'bu2306' 'bu2307' 'bu2308'
'bu2309' 'bu2310' 'bu2311' 'bu2312' 'bu2403' 'bu2406' 'bu2409']
绘图
下面,就是获取列表里的数据,然后根据数据绘制图表了。
获取数据,如果返回为empty
,说明这个合约没有交易,或者不存在,那么就忽略它。
# ==========================================================================================
# 确定数据开始的时间
time_delta = datetime.timedelta(days=0, hours=1, minutes=0, seconds=0)
time_start = (now - time_delta).strftime("%Y-%m-%d %H:%M:%S")
# 获取数据
close = []
future = []
position = []
for bu in bu_list:
data = get_data_juejin(symbol=bu, start=time_start, end=now, frequency="1m")
if not data.empty:
print(data)
c = data['close'].values[-1]
p = data['position'].values[-1]
close.append(c)
future.append(bu)
position.append(p)
print(future, close)
结果:
['bu2301', 'bu2302', 'bu2303', 'bu2304', 'bu2305', 'bu2306', 'bu2307', 'bu2309', 'bu2312', 'bu2406'] [3577.0, 3576.0, 3587.0, 3588.0, 3588.0, 3595.0, 3578.0, 3531.0, 3492.0, 3435.0]
可视化一下:
# 获取价格并画图
fig = plt.figure(figsize=(16, 9), dpi=100)
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
# line = mlines.Line2D(future, close, lw=2, ls='-', alpha=1, color='red')
# # 设置图层顺序
# line.set_zorder(1)
# ax1.add_line(line)
# 在不同的绘图区域,zorder不生效
ax2.bar(future, position, color='g', linewidth=0.2, zorder=1)
ax1.plot(future, close, marker='o', color='red', linewidth=2, zorder=2)
ax1.grid()
ax2.grid(
which='major',
axis='both',
alpha=0.5,
color='r',
linestyle='--',
)
# zorder 用来控制绘图顺序,其值越大,越在上面。
plt.savefig('各期价格.jpg')
# plt.show()
os.popen('各期价格.jpg')
os.popen()
函数用来打开保存的图片。
用到此函数,是因为VS Code默认的绘图方式使用矢量绘画引擎,导致绘图结果显示不完美。
通过保存图片到本地,然后打开的方式,可以完美解决这个问题。
图中的折线是价格,Bar是持仓量: