← All tools · Guides

Schedule a pre-market brief: weekday 08:00 cron and a push to your phone

Agent series, part 4. The last pipe in the series: a weekday 08:00 brief that reaches WeChat or email with nobody at the keyboard.

This is part 4 of the Chinese series on deploying a research agent. The previous part, connecting a model API and a market-data source, is market data and an LLM API. Installing the agent with Docker is the Docker deploy of TradingAgents-CN. Neither of those is this article.

Short answer: save morning_brief.py, schedule 0 8 * * 1-5 with absolute paths, push through one free channel you already read, and accept the job only after three mornings arrive and a bad API key fails in the log.

How to choose: A pre-market brief is useful only if it arrives at 08:00 on a weekday and the numbers in it came from the data source you already connected. Four things have to be true before you add features. The server clock is Asia/Shanghai. The cron line uses absolute paths for Python, the working directory, and the script. The prompt says to use only the data you pass in. A failed model call writes a log line and sends one short failure notice, never a blank message. Then pick the push channel by where you already look before the open. ServerChan or PushPlus if that place is WeChat: bind with a QR code and send one HTTP request, which fits a single short note a day. Email if the note is long or you want a mailbox you can search later: the Python standard library smtplib, plus an authorization code from QQ Mail or 163, which is not the login password. A Telegram bot if you want to reply to it and this server can reach Telegram. That path is a poor default on a network in mainland China. Ship one data point and about 100 words first, store each day as markdown, and add a section a week. This page is the schedule and the push. It is not the Docker install, not the model and data connection, not the tool-order guide, and not the site FAQ.

Who it is for: Someone who already has a research agent running on a cloud server, with a model API and a market-data source connected, and who wants the brief on a phone at 08:00 without opening a laptop. What you need is a script of about twenty lines, one cron line for Monday to Friday, one free push channel, and a check that it arrived on three mornings in a row.

Who it is not for: Someone who has not opened the server, installed the agent, or connected a data source and a model key. Docker deploy is still the Chinese note. Connecting the model and the data source is the previous part, in English. This page is also not the tool-order guide and not the site FAQ. A brief that invents prices, or a cron line that uses a bare python and a relative path, is out of scope. Skipping holidays can wait. An extra run on a weekday holiday is fine.

The same walkthrough in Chinese is a pre-market brief on a weekday schedule. The clock was set to Asia/Shanghai in opening a cloud server. The model key and the data source this script calls are market data and an LLM API. That connection is not this article. The Docker install is the Docker deploy of TradingAgents-CN, and it is not this article either.

The cron line and the script skeleton follow the Chinese walkthrough. They were not re-run for this English page. Free-tier quotas and request bodies follow each vendor's own page. This is not investment advice.

01 · What shows up at 08:00

On a trading morning the phone gets one note: overnight US indexes, yesterday's China A-share session, news on the names you watch, and what is on the calendar today (a data release, a lockup expiry, a listing). Nobody opens a laptop. That is the reason the server exists.

02 · One brief script

Turn "fetch, call the model, store" into morning_brief.py. The skeleton is under twenty lines. A model can fill the helpers. The shape is the part that must not change:

# Skeleton. Helpers use the data source and the model client from the previous part.
data = fetch_overnight()          # overnight indexes and the watchlist snapshot
news = fetch_my_watchlist_news()  # optional
prompt = "You are the pre-market editor. Use only the data below. Write about 300 words. Do not invent a price. " + data + news
brief = call_llm(prompt)          # OpenAI-compatible API. base_url is your vendor.
save("briefs/" + today() + ".md", brief)
push_to_phone(brief)              # section 04

Two rules. Numbers come only from the data source. The prompt says "use only the data I gave you." Archive every day as dated markdown. Reading what it said on a morning that later mattered is the point of keeping the files.

After call_llm, look at the result. An empty body or an exception is a failure. Push one line, "Today's brief failed," and write the traceback to brief.log. A blank note looks like a quiet market. It is a dead key.

03 · Cron, so the server remembers

crontab -e
# Monday to Friday at 08:00. Append stdout and stderr to the log.
0 8 * * 1-5 cd /home/lab/brief && /usr/bin/python3 morning_brief.py >> brief.log 2>&1

04 · Three free ways onto the phone

Choose with three questions. Stop at the first yes.

The token lives in .env, next to the model key from the previous part. The request body is whatever that vendor's page shows today. Copy it once. Do not commit it. Whichever channel you pick, the push function writes a log line when the send fails. A failure you cannot see will look like a morning with no news.

05 · Accept it over three mornings

06 · Pitfalls

Path 1 ends here. You have a machine, an open-source agent, and a morning note that reaches the phone. To write a strategy and backtest it, the English pages are the cloud quant desk, AKShare into SQLite, a first backtrader strategy, and paper trading after a backtest. A local China A-share review desk, without the cloud server, stays on the Chinese guides.

This is not investment advice. Free push quotas and rules follow each vendor's own page.

Frequently asked questions

How to choose a morning-brief schedule and a push channel?

A pre-market brief is useful only if it arrives at 08:00 on a weekday and the numbers in it came from the data source you already connected. Four things have to be true before you add features. The server clock is Asia/Shanghai. The cron line uses absolute paths for Python, the working directory, and the script. The prompt says to use only the data you pass in. A failed model call writes a log line and sends one short failure notice, never a blank message. Then pick the push channel by where you already look before the open. ServerChan or PushPlus if that place is WeChat: bind with a QR code and send one HTTP request, which fits a single short note a day. Email if the note is long or you want a mailbox you can search later: the Python standard library smtplib, plus an authorization code from QQ Mail or 163, which is not the login password. A Telegram bot if you want to reply to it and this server can reach Telegram. That path is a poor default on a network in mainland China. Ship one data point and about 100 words first, store each day as markdown, and add a section a week. This page is the schedule and the push. It is not the Docker install, not the model and data connection, not the tool-order guide, and not the site FAQ.

Who it is for?

Someone who already has a research agent running on a cloud server, with a model API and a market-data source connected, and who wants the brief on a phone at 08:00 without opening a laptop. What you need is a script of about twenty lines, one cron line for Monday to Friday, one free push channel, and a check that it arrived on three mornings in a row.

Who it is not for?

Someone who has not opened the server, installed the agent, or connected a data source and a model key. Docker deploy is still the Chinese note. Connecting the model and the data source is the previous part, in English. This page is also not the tool-order guide and not the site FAQ. A brief that invents prices, or a cron line that uses a bare python and a relative path, is out of scope. Skipping holidays can wait. An extra run on a weekday holiday is fine.

What does the morning brief script do?

Save it as morning_brief.py. The skeleton is fetch the overnight snapshot from the data source you already connected, optionally fetch news for the watchlist, ask the model for about 300 words using only that text, write briefs/ plus today's date as markdown, then push. Two rules. Numbers come only from the data you passed in, and the prompt says so. Every day is archived, so you can later read what the model said that morning. If the model returns empty or raises, do not push a blank note. Push one line that today's brief failed, and leave the traceback in brief.log.

How do you schedule it with cron?

On the server, crontab -e, then one line: 0 8 * * 1-5 cd /home/lab/brief && /usr/bin/python3 morning_brief.py >> brief.log 2>&1. The five fields are minute, hour, day of month, month, and weekday. 1-5 is Monday to Friday. A run on a weekday holiday is harmless, and a trading-day check can live in the script later. Part 1 of the series set the clock to Asia/Shanghai. Confirm with date. Cron does not load your login shell, so Python, the directory, and the script are absolute paths. If python is not found, run which python3 and paste that path into the crontab.

Which free push channel should you use?

Pick by where you already read messages, not by which API looks clever. ServerChan or PushPlus: bind WeChat with a QR code, then one HTTP call. Best for one short note a day. Email: smtplib plus an authorization code from QQ Mail or 163, not the account password. No practical daily cap, and the inbox keeps the long version. Telegram: the most room to reply, and only if this server can reach it. A poor default in mainland China. Whichever you pick, the token lives in .env, and a failed send writes a log line. Free quotas and the request body follow that vendor's own page. This page does not publish a live URL.

How do you accept the job after three mornings?

Four checks, and all four have to pass. The note arrives at 08:00 on Tuesday, Wednesday, and Thursday, three mornings in a row. Spot-check two figures against a market app. Break the API key on purpose and run the script once: it must error and leave a log line, not send an empty brief. The briefs/ directory has a markdown file named by date. A script that only works when you are watching the terminal is not done.

What pitfalls does this walkthrough call out?

Four. The push arrives eight hours late because the server clock is UTC. Fix it with timedatectl set-timezone Asia/Shanghai, then run date. The balance hits zero and the job still sends an empty brief. After the model call, treat an empty body or an error as failure and send only one line that today's brief failed. Cron cannot find python. which python3, then put that absolute path in the crontab. The script grows until you abandon it. Ship one data point and about 100 words first. The brief is valuable because it arrives every day, not because one morning is elaborate. This is not investment advice. Push quotas follow each vendor's own page.