背景
最近在阿里云函数上运行了几个定时任务,下载一些股票数据。很明显,这些任务在非交易日是不需要运行的,那如何判断当天是否是交易日呢?笔者试着给出 2 种方法(思路),一种直接的,一种间接的。
当然,这里说的交易日,肯定特指中国 A 股的交易日。
正文
我们都知道,交易日基本上就是工作日,还排除倒休。理论上,每年的假期是需要等政府公布的,这就意味着假期列表必须要手动维护。所以也不可能是静态的,那么就只能是动态的 API 了。
间接获取工作日
所谓间接方法,就是找一些能够获取工作日、法定节假日的接口。这里给出一个笔者找到的个人服务 提莫的神秘小站。
请求接口为 http://timor.tech/api/holiday/info/:date
,其中 date 的格式为 2024-4-5
,若不传,则默认为当天。返回的结构如下:
{
"code": 0, // 0服务正常。-1服务出错
"type": {
"type": enum(0, 1, 2, 3), // 节假日类型,分别表示 工作日、周末、节日、调休。
"name": "周六", // 节假日类型中文名,可能值为 周一 至 周日、假期的名字、某某调休。
"week": enum(1 - 7) // 一周中的第几天。值为 1 - 7,分别表示 周一 至 周日。
},
"holiday": { // 普通工作日为 null
"holiday": false, // true表示是节假日,false表示是调休
"name": "国庆前调休", // 节假日的中文名。如果是调休,则是调休的中文名,例如'国庆前调休'
"wage": 1, // 薪资倍数,1表示是1倍工资
"after": false, // 只在调休下有该字段。true表示放完假后调休,false表示先调休再放假
"target": "国庆节" // 只在调休下有该字段。表示调休的节假日
}
}
所以,如果 response.type.type === 0
,那就表示当天是工作日,也就基本上表示当天是交易日了。
另外还有批量查询的接口,有兴趣的话可以看 原文。
直接获取交易日历
私人维护的接口,稳定性其实还是有点存疑的。所以最好是稍微正规一些的服务会更靠谱一些,这里我们用 tushare 的服务来直接获取交易日历,但是需要收费。获取交易日历的请求如下:
URL: http://api.tushare.pro
METHOD: POST
BODY:
{
"api_name": "trade_cal",
"token": "xxxxxx",
"params": {
"exchange": "SSE",
"start_date": "20240405",
"end_date": "20240405"
},
"fields": ""
}
RESPONSE:
{
"request_id": "xxxxxx",
"code": 0,
"msg": "",
"data": {
"fields": [
"exchange",
"cal_date",
"is_open",
"pretrade_date"
],
"items": [
[
"SSE",
"20240405",
0,
"20240403"
]
],
"has_more": false
}
}
如果只要判断今天是否开盘,那么只需要将 start_date
和 end_date
设置为今天,fields
设置为 is_open
,返回值就会简化成:
{
"request_id": "xxxxxxx",
"code": 0,
"msg": "",
"data": {
"fields": [
"is_open"
],
"items": [
[
0
]
],
"has_more": false
}
}
这时候只要满足 response.data.items[0][0] === 1
那么就表示当天开盘。
总结
间接方法的核心思想是找工作日,这个毫无疑问是需要手动维护 API 的,目前笔者还没有找到比较靠谱的稳定的 API,如果有更好选择的同学,请留言。
直接方法嘛,就是花钱了,tushare 的这个 API,需要 2000 积分才能访问,具体积分规则可见 平台积分。
感觉做量化好像绕不过 tushare 这个砍啊……
最后提醒一句,因为这个判断是否是交易日的方法还是存在一定的不确定性。所以建议业务代码里加入容错的逻辑,当判断是否是交易日的逻辑运行异常时,就当是交易日来执行。尤其是像笔者这种定时同步数据的,数据宁可有冗余,也不能少了。