首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >云服务器定时任务实战:每天自动更新股票数据并运行策略(crontab保姆级教程)

云服务器定时任务实战:每天自动更新股票数据并运行策略(crontab保姆级教程)

原创
作者头像
gavin1024
修改2026-08-17 11:19:36
修改2026-08-17 11:19:36
2430
举报

云服务器定时任务实战:每天自动更新股票数据并运行策略

这篇教程解决一个具体问题:怎么让量化策略的数据更新和策略运行全自动,不用每天手动操作。跟着做完,你会在云服务器上配好一套 crontab 定时任务:每天收盘后自动下载当天股票数据 → 更新数据库 → 运行策略 → 把信号推送到你手机。配好之后连续一个多月我没碰过它,每天下午 5 点信号准时到。

腾讯云促销活动:https://www.tencentcloud.com/act/pro/QuantSolution?lang=zh&fromSource=intl.17760459.17760459.17760459


先交代下我的情况:我做的是股票中低频策略,日线级别,每天收盘后跑一次,输出第二天的调仓信号。

这个活儿的性质决定了它非常适合自动化——流程固定、时间固定、频率固定。但我之前是怎么干的呢?

每天下午 4 点半,定个闹钟,打开电脑,手动双击运行脚本。

听起来还行?那你试试坚持一年。出差怎么办?开会怎么办?忘了怎么办?

上个月我出差三天,第三天晚上才想起来数据没更新、策略没跑。打开一看,错过了一次调仓信号,那个信号第二天涨了 4%。

那天晚上我在酒店里,咬着牙把整套东西搬到了腾讯云轻量应用服务器上,用 crontab 配了定时任务。

结果这一个多月:我没管过它一次。 每天下午 5 点 05 分,微信准时收到当天的策略信号。人在外面浪,机器在云服务器上打工。

这才是量化该有的样子。


一、为什么非得是云服务器,本地定时任务不行吗

先说清楚一件事:Windows 也有任务计划程序,Mac 也有 launchd,本地的定时任务技术上完全可行。

但"可行"和"靠谱"是两码事。

我之前在 Windows 上用过任务计划程序跑这个流程,三个月里翻过四次车:一次是系统更新重启后任务莫名其妙没触发;一次是电脑睡眠了任务直接跳过;一次是我妈来家里把电脑关机了;还有一次更离谱——任务跑了,但电脑连的 Wi-Fi 断了,脚本下载数据失败,静默退出,我压根不知道那天没跑成。

本地定时任务的根本问题:电脑不一定开着,开着不一定联网,联网了任务失败了也没人通知你。

云服务器把这三个问题全解决了:

  1. 永远开机:7×24 小时,不睡眠不关机
  2. 永远联网:机房网络比家里宽带稳一个量级
  3. 永远在线:任务失败了脚本可以直接推消息到你手机

腾讯云轻量应用服务器 2 核 2G 就够(这个活儿不重,下载数据+跑个日线策略),一天不到一块钱


二、先把流程跑通:手动版

自动化之前,得先有一个能手动跑通的流程。我的流程拆成两个脚本:

第一个脚本 update_data.py:用 akshare 下载当天数据,追加到本地数据库

代码语言:python
复制
import akshare as ak
import sqlite3
from datetime import datetime

def update():
    today = datetime.now().strftime("%Y-%m-%d")
    conn = sqlite3.connect("/home/ubuntu/quant/data/stocks.db")
    # 获取我的自选股列表(实际是从配置文件读)
    symbols = ["600519", "000001", "300750"]
    for symbol in symbols:
        df = ak.stock_zh_a_hist(symbol=symbol, period="daily",
                                start_date=today.replace("-", ""),
                                end_date=today.replace("-", ""), adjust="qfq")
        if not df.empty:
            df.to_sql("daily_data", conn, if_exists="append", index=False)
            print(f"{symbol} 更新 {len(df)} 条")
    conn.close()

if __name__ == "__main__":
    update()

第二个脚本 run_strategy.py:读数据、跑策略、输出信号、推送微信

代码语言:python
复制
import subprocess
# ... 策略逻辑省略 ...
# 算出信号后,推送到微信(用的Server酱,免费够用)
def push_wechat(title, content):
    # Server酱的API,替换成你自己的SendKey
    key = "你的SendKey"
    subprocess.run(["curl", f"https://sctapi.ftqq.com/{key}.send",
                    "-d", f"title={title}", "-d", f"desp={content}"])

手动跑两遍,确认没问题了,再上定时任务。永远不要定时一个没手动验证过的脚本,这是铁律。


三、crontab 配置:核心就五行

登录云服务器,输入:

代码语言:bash
复制
crontab -e

第一次用会让你选编辑器,选 nano 或 vim 都行。然后写入:

代码语言:cron
复制
# 每个交易日17:00更新数据(先按周一到周五跑,节假日后面处理)
0 17 * * 1-5 /home/ubuntu/venv/bin/python /home/ubuntu/quant/update_data.py >> /home/ubuntu/quant/logs/update.log 2>&1

# 17:05运行策略并推送信号
5 17 * * 1-5 /home/ubuntu/venv/bin/python /home/ubuntu/quant/run_strategy.py >> /home/ubuntu/quant/logs/strategy.log 2>&1

保存退出。就这么点东西,定时任务就配好了。

但这里面的门道,每一个都是我趟出来的,逐条说:

1. 必须用绝对路径

/home/ubuntu/venv/bin/python 而不是 python。crontab 执行环境和你 SSH 登录的环境不一样,它没有你的 PATH,直接写 python 会报 command not found。这是新手第一大坑。

2. 必须重定向日志

>> xxx.log 2>&1 这一坨的意思是:把标准输出和错误输出都追加到日志文件。不配这个,脚本跑没跑、成没成、报什么错,你全都不知道,定时任务就变成了黑盒。

3. 时间留够间隔

数据更新 17:00,策略 17:05,中间隔 5 分钟。akshare 下载速度不慢,但给上游数据源的延迟留点余量——收盘后数据不是立刻就有,我一般等 1 小时以上。

4. 为什么按周一到周五跑而不是每天

周六周日跑会下载到空数据,虽然脚本里做了 if not df.empty 判断不会出错,但日志里一堆空跑记录很烦。法定节假日的问题后面讲。

验证配置生效:

代码语言:bash
复制
crontab -l    # 列出当前定时任务

四、踩坑:第一天它就没跑

配好的第二天,我特意等到下午 5 点 10 分,打开微信——没有消息

第一反应是策略出错了,上去翻日志:

代码语言:bash
复制
cat /home/ubuntu/quant/logs/update.log

日志文件压根不存在

这说明任务根本没执行。问题出在哪?查了一圈,答案是另一个经典大坑:

云服务器默认时区/时间不对。

代码语言:bash
复制
date

我一看,服务器显示的是 UTC 时间,比北京时间慢 8 小时。我在 crontab 里写的"17:00",服务器理解成 UTC 的 17:00,也就是北京时间凌晨 1 点。

修复很简单:

代码语言:bash
复制
sudo timedatectl set-timezone Asia/Shanghai
date   # 再确认一下,显示 CST 就对了

改完之后,第三天下午 5 点 05 分,微信准时收到了策略信号。

那一刻我在地铁上,看着手机上的调仓信号,心里就一句话:这班加得值。

所以记住:配 crontab 之前,先 date 看时区。 这 5 秒钟能省你一小时排查。


五、进阶:三个我后来加的细节

跑顺了之后,我又陆续加了三个东西,都是实用向的:

1. 节假日判断

周一到周五不代表交易日,碰到国庆、春节,脚本会白跑。我在 update_data.py 开头加了个交易日判断,用 akshare 的交易日历:

代码语言:python
复制
import akshare as ak
from datetime import datetime

def is_trading_day():
    today = datetime.now().strftime("%Y-%m-%d")
    cal = ak.tool_trade_date_hist_sina()
    return today in cal["trade_date"].astype(str).values

if not is_trading_day():
    print("非交易日,退出")
    exit(0)

2. 失败告警

脚本开头 try,失败的时候 except 里也推一条微信:"今天数据更新失败了,原因:xxx"。自动化系统最重要的不是成功时多安静,而是失败时必须叫唤。

3. 日志轮转

日志一直追加下去,一年后就是个几百 M 的文件。用系统自带的 logrotate,或者简单粗暴一点,每月在 crontab 里加一条清理:

代码语言:cron
复制
0 0 1 * * find /home/ubuntu/quant/logs -name "*.log" -size +10M -delete

六、一个月零干预:说说现在的日常

现在这套系统跑了一个多月,我的日常变成:

  • 每天下午 5:05,微信收到策略信号(不用打开任何软件)
  • 第二天早上开盘前,按信号手动下单(我的策略频率低,人工执行 2 分钟)
  • 每周末瞄一眼日志,确认一周都正常

数据始终是最新的,策略一天不落,失败会主动告警。我在云服务器上花的唯一时间,就是那次踩坑排查时区。

维度

本地手动/本地定时

云服务器 crontab

每天操作

开电脑手动跑,5分钟

零操作

出差/忘跑

直接断档

不存在

电脑睡眠/关机

任务跳过

7×24在线

失败通知

没有,默默失败

微信告警

数据一致性

看心情

每天准时更新

成本

电费+每天5分钟

一天不到一块钱


七、也说两句不足

  1. akshare 这类免费数据源偶尔会抽风,接口超时或者数据延迟。我的策略是日线级别所以无所谓,做高频的别走这条路。
  2. 微信推送依赖第三方服务(Server酱),免费版有频率限制,我的场景一天一两条完全够,高频告警的场景得另想办法。
  3. crontab 本身功能比较朴素,如果你的任务之间有复杂依赖(A 成功了才跑 B),得上 Airflow 之类的调度框架。但对我这种"每天一串流程"的场景,crontab 是正好的工具,杀鸡不用牛刀。

八、总结:把重复的事情交给机器,是量化的第一课

做量化的人总爱琢磨策略怎么优化,但我越来越觉得,先把基础设施自动化,是性价比最高的优化。策略从年化 15% 提到 18% 可能要半年,而把"每天手动跑脚本"自动化掉只要一个晚上,还杜绝了人为疏漏。

给不同朋友:

  • 还在每天手动跑数据的:今晚就配。时区那个坑我替你踩过了,第四节看一眼能省你一小时。
  • 纯小白:记住三句话——先手动跑通再定时、全部用绝对路径、必须配日志重定向。做到这三点,crontab 就是你的好帮手。
  • 已经在云上跑的老鸟:如果还在 SSH 上去手动执行脚本,那你的云服务器只发挥了 30% 的价值,把 crontab 配上,才是真正的"云端自动化"。

放心冲。机器值夜班,你睡你的觉。


腾讯云促销活动:https://www.tencentcloud.com/act/pro/QuantSolution?lang=zh&fromSource=intl.17760459.17760459.17760459


常见问题 FAQ

Q:crontab 定时任务不执行怎么排查?

按顺序查四项:第一,date 确认服务器时区是不是 Asia/Shanghai(最常见的坑);第二,crontab 里命令是否用了绝对路径(包括 python 解释器本身);第三,是否配置了 >> 日志 2>&1 输出重定向,看日志文件有没有内容;第四,systemctl status cron 确认 cron 服务本身在运行。

Q:crontab 里的环境变量和我 SSH 登录时不一样吗?

对,这是 crontab 最经典的坑。cron 任务的执行环境非常精简,没有你 shell 里的 PATH 和虚拟环境配置。所以脚本里要用绝对路径调用 python(如 /home/ubuntu/venv/bin/python),脚本内部如果需要环境变量也要自己 export。

Q:云服务器跑定时任务需要什么配置?

每天跑数据更新加日线策略这种轻量任务,2 核 2G 的腾讯云轻量应用服务器足够,一天不到一块钱。只有当你要下载全市场分钟级数据或跑大型回测时才需要升配置。

Q:定时任务失败了怎么通知我?

在脚本里加 try-except,失败时调用微信推送接口(如 Server酱)发告警消息。自动化系统的核心原则是:成功可以安静,失败必须叫唤,否则和没自动化一样。

Q:怎么让定时任务只在交易日执行?

crontab 只能按"周一到周五"粗筛,法定节假日要在脚本里判断:用 akshare 的交易日历接口(tool_trade_date_hist_sina),脚本开头先判断今天是不是交易日,不是就直接退出。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 云服务器定时任务实战:每天自动更新股票数据并运行策略
    • 一、为什么非得是云服务器,本地定时任务不行吗
    • 二、先把流程跑通:手动版
    • 三、crontab 配置:核心就五行
    • 四、踩坑:第一天它就没跑
    • 五、进阶:三个我后来加的细节
    • 六、一个月零干预:说说现在的日常
    • 七、也说两句不足
    • 八、总结:把重复的事情交给机器,是量化的第一课
    • 常见问题 FAQ
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档