如何判断当天是否是交易日(工作日)

309 阅读3分钟

背景

最近在阿里云函数上运行了几个定时任务,下载一些股票数据。很明显,这些任务在非交易日是不需要运行的,那如何判断当天是否是交易日呢?笔者试着给出 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_dateend_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 这个砍啊……

最后提醒一句,因为这个判断是否是交易日的方法还是存在一定的不确定性。所以建议业务代码里加入容错的逻辑,当判断是否是交易日的逻辑运行异常时,就当是交易日来执行。尤其是像笔者这种定时同步数据的,数据宁可有冗余,也不能少了。