标签归档:日历

Exchange_calendars 一个能获取全世界所有市场交易日历的Python模块

Exchange_calendars 是一个用于查询证券交易日历的 Python 库。开箱即用,内含世界50+个交易所的交易日历,包括中国市场和港股市场,非常方便。

同时,如果你找到了Exchange_calendars 上没有的市场的交易日历,可以向他们提交PR,创建一个新的交易所日历

注意,本模块最低支持的Python版本为3.8.

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install exchange_calendars

2.Exchange_calendars 基本使用

获取可用日历的列表:

import exchange_calendars as xcals
print(xcals.get_calendar_names(include_aliases=False))

结果如下:

['24/5', '24/7', 'AIXK', 'ASEX', 'BVMF', 'CMES', 'IEPA', 'XAMS', 'XASX', 'XBKK', 'XBOG', 'XBOM', 'XBRU', 'XBSE', 'XBUD', 'XBUE', 'XCBF', 'XCSE', 'XDUB', 'XETR', 'XFRA', 'XHEL', 'XHKG', 'XICE', 'XIDX', 'XIST', 'XJSE', 'XKAR', 'XKLS', 'XKRX', 'XLIM', 'XLIS', 'XLON', 'XMAD', 'XMEX', 'XMIL', 'XMOS', 'XNYS', 'XNZE', 'XOSL', 'XPAR', 'XPHS', 'XPRA', 'XSES', 'XSGO', 'XSHG', 'XSTO', 'XSWX', 'XTAE', 'XTAI', 'XTKS', 'XTSE', 'XWAR', 'XWBO', 'us_futures']

其中,XSHG就是中国的沪市、XHKG就是港股。

获取沪市日历:

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")

查询某个区间日程是否有开盘:

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.schedule.loc["2021-12-29":"2022-08-12"])
                                open               break_start                 break_end                     close
2021-12-29 2021-12-29 01:30:00+00:00 2021-12-29 03:30:00+00:00 2021-12-29 05:00:00+00:00 2021-12-29 07:00:00+00:00
2021-12-30 2021-12-30 01:30:00+00:00 2021-12-30 03:30:00+00:00 2021-12-30 05:00:00+00:00 2021-12-30 07:00:00+00:00
2021-12-31 2021-12-31 01:30:00+00:00 2021-12-31 03:30:00+00:00 2021-12-31 05:00:00+00:00 2021-12-31 07:00:00+00:00
2022-01-04 2022-01-04 01:30:00+00:00 2022-01-04 03:30:00+00:00 2022-01-04 05:00:00+00:00 2022-01-04 07:00:00+00:00
2022-01-05 2022-01-05 01:30:00+00:00 2022-01-05 03:30:00+00:00 2022-01-05 05:00:00+00:00 2022-01-05 07:00:00+00:00
...                              ...                       ...                       ...                       ...
2022-08-08 2022-08-08 01:30:00+00:00 2022-08-08 03:30:00+00:00 2022-08-08 05:00:00+00:00 2022-08-08 07:00:00+00:00
2022-08-09 2022-08-09 01:30:00+00:00 2022-08-09 03:30:00+00:00 2022-08-09 05:00:00+00:00 2022-08-09 07:00:00+00:00
2022-08-10 2022-08-10 01:30:00+00:00 2022-08-10 03:30:00+00:00 2022-08-10 05:00:00+00:00 2022-08-10 07:00:00+00:00
2022-08-11 2022-08-11 01:30:00+00:00 2022-08-11 03:30:00+00:00 2022-08-11 05:00:00+00:00 2022-08-11 07:00:00+00:00
2022-08-12 2022-08-12 01:30:00+00:00 2022-08-12 03:30:00+00:00 2022-08-12 05:00:00+00:00 2022-08-12 07:00:00+00:00

[151 rows x 4 columns]

可见,他直接返回了这个区间中所有开盘的日期作为index,并附带了开盘和收盘的UTC时间(需要+8)。

如果你只需要开市的日期,可以这样:

# 公众号:二七阿尔量化
import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
xshg_range = xshg.schedule.loc["2021-12-29":"2022-08-12"]
print(xshg_range.index.strftime("%Y-%m-%d").tolist())

效果如下:

['2021-12-29', '2021-12-30', '2021-12-31', '2022-01-04', '2022-01-05', '2022-01-06', '2022-01-07', '2022-01-10', '2022-01-11', '2022-01-12', '2022-01-13', '2022-01-14', '2022-01-17', '2022-01-18', '2022-01-19', '2022-01-20', '2022-01-21', '2022-01-24', '2022-01-25', '2022-01-26', '2022-01-27', '2022-01-28', '2022-02-07', '2022-02-08', '2022-02-09', '2022-02-10', '2022-02-11', '2022-02-14', '2022-02-15', '2022-02-16', '2022-02-17', '2022-02-18', '2022-02-21', '2022-02-22', '2022-02-23', '2022-02-24', '2022-02-25', '2022-02-28', '2022-03-01', '2022-03-02', '2022-03-03', '2022-03-04', '2022-03-07', '2022-03-08', '2022-03-09', '2022-03-10', '2022-03-11', '2022-03-14', '2022-03-15', '2022-03-16', '2022-03-17', '2022-03-18', '2022-03-21', '2022-03-22', '2022-03-23', '2022-03-24', '2022-03-25', '2022-03-28', '2022-03-29', '2022-03-30', '2022-03-31', '2022-04-01', '2022-04-06', '2022-04-07', '2022-04-08', '2022-04-11', '2022-04-12', '2022-04-13', '2022-04-14', '2022-04-15', '2022-04-18', '2022-04-19', '2022-04-20', '2022-04-21', '2022-04-22', '2022-04-25', '2022-04-26', '2022-04-27', '2022-04-28', '2022-04-29', '2022-05-05', '2022-05-06', '2022-05-09', '2022-05-10', '2022-05-11', '2022-05-12', '2022-05-13', '2022-05-16', '2022-05-17', '2022-05-18', '2022-05-19', '2022-05-20', '2022-05-23', '2022-05-24', '2022-05-25', '2022-05-26', '2022-05-27', '2022-05-30', '2022-05-31', '2022-06-01', '2022-06-02', '2022-06-06', '2022-06-07', '2022-06-08', '2022-06-09', '2022-06-10', '2022-06-13', '2022-06-14', '2022-06-15', '2022-06-16', '2022-06-17', '2022-06-20', '2022-06-21', '2022-06-22', '2022-06-23', '2022-06-24', '2022-06-27', '2022-06-28', '2022-06-29', '2022-06-30', '2022-07-01', '2022-07-04', '2022-07-05', '2022-07-06', '2022-07-07', '2022-07-08', '2022-07-11', '2022-07-12', '2022-07-13', '2022-07-14', '2022-07-15', '2022-07-18', '2022-07-19', '2022-07-20', '2022-07-21', '2022-07-22', '2022-07-25', '2022-07-26', '2022-07-27', '2022-07-28', '2022-07-29', '2022-08-01', '2022-08-02', '2022-08-03', '2022-08-04', '2022-08-05', '2022-08-08', '2022-08-09', '2022-08-10', '2022-08-11', '2022-08-12']

3.高级使用

判断某一天是否为交易日:

# 公众号:二七阿尔量化

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.is_session("2022-12-30"))
# True

获取某一天后的N个交易日:

# 公众号:二七阿尔量化

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.sessions_window("2022-12-30", 7))
# DatetimeIndex(['2022-12-30', '2023-01-03', '2023-01-04', '2023-01-05',
#               '2023-01-06', '2023-01-09', '2023-01-10'],
#              dtype='datetime64[ns]', freq='C')

获取某一天后的下一个交易日:

# 公众号:二七阿尔量化

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.date_to_session("2022-01-01", direction="next"))
# 2022-01-04 00:00:00

获取某一天后的上一个交易日:

# 公众号:二七阿尔量化

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.date_to_session("2022-01-01", direction="previous"))
# 2021-12-31 00:00:00

获取分钟级交易区间:

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.session_minutes("2022-01-04"))
# DatetimeIndex(['2022-01-04 01:30:00+00:00', '2022-01-04 01:31:00+00:00',
#                '2022-01-04 01:32:00+00:00', '2022-01-04 01:33:00+00:00',
#                '2022-01-04 01:34:00+00:00', '2022-01-04 01:35:00+00:00',
#                '2022-01-04 01:36:00+00:00', '2022-01-04 01:37:00+00:00',
#                '2022-01-04 01:38:00+00:00', '2022-01-04 01:39:00+00:00',
#                ...
#                '2022-01-04 06:50:00+00:00', '2022-01-04 06:51:00+00:00',
#                '2022-01-04 06:52:00+00:00', '2022-01-04 06:53:00+00:00',
#                '2022-01-04 06:54:00+00:00', '2022-01-04 06:55:00+00:00',
#                '2022-01-04 06:56:00+00:00', '2022-01-04 06:57:00+00:00',
#                '2022-01-04 06:58:00+00:00', '2022-01-04 06:59:00+00:00'],
#               dtype='datetime64[ns, UTC]', length=240, freq=None)

交易时间按指定数字分割:

import exchange_calendars as xcals
xshg = xcals.get_calendar("XSHG")
print(xshg.trading_index(
    "2021-12-30", "2021-12-31", period="30T", force=True
))
# IntervalIndex([[2021-12-30 01:30:00, 2021-12-30 02:00:00), [2021-12-30 02:00:00, 2021-12-30 02:30:00), [2021-12-30 02:30:00, 2021-12-30 03:00:00), [2021-12-30 03:00:00, 2021-12-30 03:30:00), [2021-12-30 05:00:00, 2021-12-30 05:30:00) ... [2021-12-31 03:00:00, 2021-12-31 03:30:00), [2021-12-31 05:00:00, 2021-12-31 05:30:00), [2021-12-31 05:30:00, 2021-12-31 06:00:00), [2021-12-31 06:00:00, 2021-12-31 06:30:00), [2021-12-31 06:30:00, 2021-12-31 07:00:00)],
#               closed='left',
#               dtype='interval[datetime64[ns, UTC]]')

我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

给作者打赏,选择打赏金额
¥1¥5¥10¥20¥50¥100¥200 自定义

​Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典

Excel+Python=精美壁纸日历 任意DIY

广东的太阳还是那么大,隔着玻璃都能感受到热浪。

明明前不久才立夏(明明已经过去三个月!!)

时间跑,日程赶。

昨日又迎来了立秋,正在放暑假的童靴是不是有点忘记时间了呢~

什么?真的忘记了?没关系,今日小编为大家带来一款由Excel简易DIY的小日历

给自己10分钟(滑稽),python回你一个智慧与美貌并存的备忘小神器 相信它会给你带来不少方便(滑稽)

一、环境说明

开始之前,当然要跟小伙伴们交代一下运行环境咯

我们使用的python版本为 Python3.6,需要使用到的包为 openpyxlcalendar,后者是python自带的,而前者则需要小伙伴们打开Cmd/Terminal,运行以下指令安装,如果你还没有安装python,请看这篇文章

pip install openpyxl

安装完成后我们就可以正式开始啦!

二、代码说明

我们会给大家先讲解一些细节的东西,等大家都理解明白了原理,最后会献上完整的源代码~

1. 首先,绘制一份日历,我们得先知道每个月份有多少天,每天都是星期几,我们使用calendar包获得这些信息:
calendar.monthcalendar(2019, i)

通过这个函数,我们能得到 2019年i月的日历,它类似一个j*k的矩阵,因此我们可以这样遍历得到每一个日期:

    for j in range(len(calendar.monthcalendar(2019, i))):
        for k in range(len(calendar.monthcalendar(2019, i)[j])):
            value = calendar.monthcalendar(2019, i)[j][k]
2. 其次,我们怎么样绘制得到日历呢?

openpyxl包给予了我们答案,最方便的做法是我们先将日历绘制到Excel中,然后再从Excel中提取图片出来。openpyxl怎么用?给大家一个设置单元格字体的例子:

sheet.cell(row=j + 4 + count, column=k + 2).font = Font(u'微软雅黑', color=text_color , size=14)

sheet是对应的表格,row和column就是某个单元格的位置,然后对font属性进行设置,调用Font类并设置参数,如果大家不知道Font类有什么参数,可以参考openpyxl官方文档:https://openpyxl.readthedocs.io/en/stable/,你可以看到里面大部分单元格的属性都是这样设置的,非常简单。

3. 我们的作品是每个月份都有一个图在旁边做装饰,其添加方法如下:
imgs = ['12/1.jpg','12/2.jpg','12/3.jpg','12/4.jpg','12/5.jpg','12/6.jpg','12/7.jpg','12/8.jpg','12/9.jpg','12/10.jpg','12/11.jpg','12/12.jpg']

img = Image(imgs[i-1])        
sheet.add_image(img, 'J2')

imgs是每个图的相对路径,如12/1.jpg 是名字为12的文件夹下的1.jpg. 图像路径要导入到openpyxl的Image对象中: img=Image(’12/1.jpg’),然后将该变量放置到某个单元格上:sheet.add_image(img, ‘J2).

这样看你可能会有点糊涂, i-1是哪里来的?sheet是哪里来的?没关系,其实是因为讲解的时候只能给大家献上部分代码,看完下面的完整代码你们就懂啦:

from openpyxl.styles import Alignment, PatternFill, Font, Border, Side
from openpyxl.utils import get_column_letter
from openpyxl.drawing.image import Image
import openpyxl
import calendar

def set_information(date, text):
    t = {}
    t['month'] = date.split('-')[1]
    t['day'] = date.split('-')[2]
    t['text'] = text
    flex_text.append(t)

def set_month_value(i, sheet, border_color, text_color, color_one, color_two):
    # i: 月份
    # sheet: 该月份的excel
    # border_color: 边框颜色
    count = 0
    # render_color 用来设定单元格背景色,交替进行
    render_color_1 = 1
    render_color_2 = 0

    for j in range(len(calendar.monthcalendar(2019, i))):
        for k in range(len(calendar.monthcalendar(2019, i)[j])):
            value = calendar.monthcalendar(2019, i)[j][k]
            # 将0值变为空值
            bd = Border(right=Side(color=border_color, style='thick'),
                        top=Side(color=border_color, style='thick'),
                        left=Side(color=border_color, style='thick'))
            right_bd = Border(right=Side(color=border_color, style='thick'),
                              left=Side(color=border_color, style='thick'),
                              bottom=Side(color=border_color, style='thick'))
            
            if value == 0:
                value = ''
                sheet.cell(row=j + 4 + count, column=k + 2).value = value
                sheet.cell(row=j + 4 + count, column=k + 2).border = bd
                sheet.cell(row=j + 5 + count, column=k + 2).border = right_bd
            else:
                sheet.cell(row=j + 4 + count, column=k + 2).value = value
                sheet.cell(row=j + 4 + count, column=k + 2).border = bd
                sheet.cell(row=j + 4 + count, column=k + 2).font = Font(u'微软雅黑', color=text_color , size=14)
                sheet.cell(row=j + 5 + count, column=k + 2).border = right_bd
                # 单元格文字设置,右对齐,垂直居中

            if render_color_1 > render_color_2:
                sheet.cell(row=j + 4 + count, column=k + 2).fill = PatternFill("solid", fgColor=color_one)
                sheet.cell(row=j + 5 + count, column=k + 2).fill = PatternFill("solid", fgColor=color_one)
                render_color_2 += 1
            else:
                sheet.cell(row=j + 4 + count, column=k + 2).fill = PatternFill("solid", fgColor=color_two)
                sheet.cell(row=j + 5 + count, column=k + 2).fill = PatternFill("solid", fgColor=color_two)
                render_color_1 += 1

            # 提取当天所有事件
            text = ''
            for t in flex_text:
                if int(t['day']) == value and int(t['month']) == i:
                    print(t)
                    text = text + t['text']+'\n'

            # 设置事件信息
            if text != '':
                sheet.cell(row=j + 5 + count, column=k + 2).value = text
                sheet.cell(row=j + 5 + count, column=k + 2).font = Font(u'宋体',color=text_color, size=13)
                align = Alignment(horizontal='right', vertical='center', wrapText=True)
                # wrapText 设置单元格可包含多行字符
                sheet.cell(row=j + 5 + count, column=k + 2).alignment = align
        count += 1

def set_week_line(sheet, border_color, workday_color, otherday_color, text_color):
    # 设置星期栏
    align = Alignment(horizontal='center', vertical='center')
    days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
    bd_day = Border(right=Side(color=border_color, style='thick'), 
                      top=Side(color=border_color, style='thick'),
                      left=Side(color=border_color, style='thick'))
    num = 0
    # 单元格填充色属性设置
    for day in range(2, 9):
        sheet.cell(row=3, column=day).value = days[num]
        sheet.cell(row=3, column=day).alignment = align
        sheet.cell(row=3, column=day).border = bd_day
        sheet.cell(row=3, column=day).font = Font(u'微软雅黑', color=text_color, bold=True , size=12)
        # 设置列宽12
        c_char = get_column_letter(day)
        sheet.column_dimensions[get_column_letter(day)].width = 12
        # 行高27
        sheet.row_dimensions[day].height = 27
        num += 1
        if day == 2 or day == 8:
            for r in range(3, 14):
                sheet.cell(row=r, column=day).fill = PatternFill("solid", fgColor=otherday_color)
        else:
            sheet.cell(row=3, column=day).fill = PatternFill("solid", fgColor=workday_color)

def set_month_year(i, sheet, year_color, month_color):
    # 添加年份及月份
    sheet.cell(row=2, column=8).value = '2019'
    sheet.cell(row=2, column=8).font = Font(u'微软雅黑', size=30, color=year_color)
    sheet.cell(row=2, column=2).value = str(i) + '月'
    sheet.cell(row=2, column=2).font = Font(u'微软雅黑', size=25, color=month_color)
    sheet.row_dimensions[2].height = 35

def get_month_xlsx(wb, imgs, flex_text):
    for i in range(1, 13):
        sheet = wb.create_sheet(index=0, title=str(i) + '月')
        # 添加工作表

        text_color = '000000'
        # 日历文字颜色
        text_color_week = '000000'
        # 星期栏文字颜色
        BorderCorlor = 'B7E0E8'
        # 边框颜色
        backgroundColor = 'FFFFFF'
        # 背景颜色
        workday_color = 'CBEEEE'
        # 工作日背景颜色
        otherday_color = '7FD4D2'
        # 其他日背景颜色
        year_color = '000000'
        # 年份颜色
        month_color = '000000'
        # 月份颜色
        s_color = 'CBEEEE'
        # 单数颜色
        d_color = 'A5E1E0'
        # 双数颜色
        
        # 单元格的背景色
        for k1 in range(1, 15):
            for k2 in range(1, 16):
                sheet.cell(row=k1, column=k2).fill = PatternFill("solid", fgColor=backgroundColor)

        set_month_value(i, sheet, BorderCorlor, text_color, s_color, d_color)
        # 设定月份的值,参数:月份, 表, 边框颜色

        set_week_line(sheet, BorderCorlor, workday_color, otherday_color, text_color_week)
        # 设定星期栏

        set_month_year(i, sheet, year_color, month_color)
        # 设定年份和月份的格式

        # 设置日历主体行高
        for row in range(3, 19):
            if row % 2 == 0 or row == 3:
                sheet.row_dimensions[row].height = 28
            else:
                sheet.row_dimensions[row].height = 56

        # 合并单元格
        sheet.merge_cells('I1:P14')

        # 添加图片
        img = Image(imgs[i-1])
        sheet.add_image(img, 'J2')

        # 添加二维码
        img = Image('2.png')
        sheet.add_image(img, 'O2')

calendar.setfirstweekday(firstweekday=6)
wb = openpyxl.Workbook()
flex_text = []

imgs = ['12/1.jpg','12/2.jpg','12/3.jpg','12/4.jpg','12/5.jpg','12/6.jpg','12/7.jpg','12/8.jpg','12/9.jpg','12/10.jpg','12/11.jpg','12/12.jpg']
# 每个月的图片

set_information('2019-12-1', '考试')
set_information('2019-12-1', '约会')
# 需要添加的信息

get_month_xlsx(wb, imgs, flex_text)
# 得到文档

wb.save('my_calendary.xlsx')
# 保存文档
4. 我们还有一个神秘功能

差点忘了告诉大家了,我们的日历能支持备注哦,在调用get_month_xlsx得到文档前,通过set_information()放入你某一天想做的事情即可。如:

set_information('2019-12-5', '面试')

三、运行代码

终于到了激动人心的运行代码部分了,运行这份代码,你只需要把你想要的图片变量名改一下即可,即imgs. 然后在本地cmd/terminal运行:

python 这份代码的文件名(滑稽.py

会自动生成一个Excel表格叫my_calendary.xlsx. 怎样从里面把日历提取成图片呢?很简单,复制拉取你想要的部分,粘贴到聊天窗口就能变成一个图片!这里给大家献上源代码里的12张图,希望大家喜欢!

下载地址:https://pythondict-1252734158.file.myqcloud.com/home/www/pythondict/wp-content/uploads/2019/08/2019080909262065.zip


根据大家的喜好,大家可以自己设置背景色、边框色、交替色和图片,还有把这个讨厌的好看的二维码去掉。如果有阅读完注释还是不懂的地方,欢迎在下方留言区讨论,我们会抽空回答的~


Python实用宝典 (pythondict.com)

不只是一个宝典

欢迎关注公众号:Python实用宝典