← All tools · Guides

After the close: an AI review note for holdings and a watchlist

Local review series, part 3. After the close, your computer reads the database, calls a model, and pushes one note to your phone.

This is part 3 of the Chinese series on a local AI review system. The previous part, writing China A-share daily bars into local SQLite and catching up on boot, is the Chinese local-sync note. The note reads that database. That note is not this article. The Python and SQLite setup before it is the Chinese environment note, also Chinese-only.

Short answer: after the 18:00 ingest, query holdings and the watchlist from local SQLite, send only those rows to an OpenAI-compatible model, write four parts, save briefs/YYYY-MM-DD.md, and schedule the push at 18:30.

How to choose: An after-close review note is a four-part recap you read yourself. It is not a buy or sell signal. Build it only after the local SQLite file from the previous note already holds today's bars. The model interprets rows you queried. It does not fetch prices, news, or filings. The four parts are fixed. Today's market is the index move and the count of advancers and decliners, in a sentence or two. Each holding gets today's move, where it sits over the last five sessions relative to your cost or a recent high, and one status line, in at most two sentences. The watchlist part names only the symbols whose return or volume is clearly out of line. Tomorrow's list is something worth a look, not a recommendation. Call an OpenAI-compatible client. The Chinese page uses DeepSeek at https://api.deepseek.com with model deepseek-chat, and a real project reads the key from the environment. If that database has no index, pull the last few days with ak.stock_zh_index_daily(symbol="sh000001") and append those rows to the same fact text. Save the note under briefs/, for example briefs/2025-09-01.md. Push it to WeChat with ServerChan or pushplus, the same path as the morning-brief note. That note is not this article. On Windows Task Scheduler, run weekdays at 18:30, half an hour after the 18:00 ingest, so the file you read is today's. Feed the last 5 to 10 sessions, not the whole history. If you do not want a vendor to see a cost basis, leave that field on the machine and send codes and returns only. This page is not the tool-order guide, not the site FAQ, not the morning brief, not the intraday alert note, and not the AKShare SQLite walkthrough.

Who it is for: Someone who already stores China A-share daily bars in a local SQLite file and wants a short written review of holdings and a watchlist after the close, then a push to a phone. The numbers come from that database, not from the model's memory.

Who it is not for: Someone who still needs Python, SQLite, or the daily ingest. Those are the first two notes in this Chinese series, and they do not have an English edition. Someone who wants an alert during the session wants the next note, which is also Chinese-only. Someone who wants a pre-market brief wants a different series. This page does not say what to buy or sell. It is not the tool-order guide, and it is not the site FAQ.

The same walkthrough in Chinese is an after-close AI review note. Storing China A-share bars on a schedule, including column names and adjustment, is AKShare into SQLite. That walkthrough is not this article. The push itself, ServerChan, pushplus, mail, or a Telegram bot, is written out in the morning brief. Reuse that function. That note is not this article. The next part of this series, an alert while the market is open, is the Chinese watchlist-alert note. That note is not this article either.

Facts below follow the Chinese walkthrough. The commands were not re-run for this English page. The Chinese page does not publish a model price, and this page does not add one. Usage and prices follow the vendor's own site. This is not investment advice. The model output is a research note, not a reason to trade.

01 · What the note looks like

Four parts, fixed, readable in about five minutes:

If a section has nothing to say, say that in one line. Padding is how a daily note turns into something you stop opening.

02 · Query the database, then hand the model the facts

The rule: the model interprets. It does not supply the numbers. Read the facts out of the database and put them in the prompt.

import sqlite3, pandas as pd

conn = sqlite3.connect("D:/quant/astock.db")
codes = "('600519','000858','300750')"      # holdings and the watchlist
df = pd.read_sql_query(f"""
  SELECT code, date, close, volume FROM daily
  WHERE code IN {codes} ORDER BY date""", conn)
conn.close()

# Today's change, the change across the last six bars, and a volume ratio, one line per code.
facts = []
for code, g in df.groupby("code"):
    g = g.tail(6).reset_index(drop=True)
    if len(g) < 6: continue
    chg1 = (g.close.iloc[-1]/g.close.iloc[-2]-1)*100
    chg5 = (g.close.iloc[-1]/g.close.iloc[0]-1)*100
    vol_ratio = g.volume.iloc[-1] / g.volume.iloc[:-1].mean()
    facts.append(f"{code} today {chg1:+.1f}% 5d {chg5:+.1f}% vol_ratio {vol_ratio:.1f}")
data_text = "\n".join(facts)

Six bars is the minimum. The one-day change uses the last two closes. The five-session change uses the first and the last of those six rows, which is five steps. The volume ratio is today's volume divided by the mean of the earlier bars in that window. A code with fewer than six rows is skipped. Do not ask the model to fill the gap.

What to include, and what to leave on disk:

03 · Call the model through an OpenAI-compatible API

# pip install openai   (major China model APIs accept this client)
from openai import OpenAI

client = OpenAI(
    base_url="https://api.deepseek.com",     # swap in your provider
    api_key="sk-xxxx",                       # a real project reads this from the environment
)
resp = client.chat.completions.create(
    model="deepseek-chat",
    messages=[{"role": "user", "content": PROMPT + data_text}],
)
note = resp.choices[0].message.content

Put the rules in the prompt before the data:

PROMPT = """You are a careful review assistant. Rules:
1) Use only the data I provide. Do not invent any number, news item, or filing.
2) Do not give buy or sell advice. Describe what happened and name the risk.
3) Write four parts: today's market (I will also give you index rows) / holdings / watchlist movers / what to look at tomorrow.
4) At most two sentences per name.

Today's data:
"""

The index is the same idea. If the database from the first note has no index series, pull the last few days with ak.stock_zh_index_daily(symbol="sh000001") and append those rows to data_text. That symbol is the Shanghai Composite in AKShare's index helper. Do not type the index move from memory. Column names, rate limits, and adjustment are covered in AKShare into SQLite, which is a different article.

Swap the base_url and the model name for another OpenAI-compatible provider if you already have an account. Do not add a second client "for a better opinion." One model, one prompt, one file per day is the version you can compare with last month.

04 · Archive, then push

Write the note to a dated file such as briefs/2025-09-01.md. A few months later, the useful question is what the model said on that day, next to what the prices actually did. A chat window does not keep that.

Then push it to WeChat with ServerChan or pushplus. The request and the failure log are the same as in the morning brief. Copy that function. Do not invent a second push stack for this one job. That note also lists mail and a Telegram bot if WeChat is the wrong channel. Whichever you pick, a failed send has to land in a log. A silent failure looks like a quiet market.

05 · Schedule it after the ingest

schtasks /Create /TN "ai-review" /SC WEEKLY /D MON,TUE,WED,THU,FRI /ST 18:30 ^
  /TR "D:\quant\run_review.bat" /F
# 18:30 is half an hour after the 18:00 ingest, so the database already has today

Three checks before you trust the clock:

06 · Pitfalls

The note waits for the close. The last part of the series pushes while the market is open:

Next: watchlist alerts →

This is not investment advice. The model output is a research note, not a reason to trade.

Frequently asked questions

How to choose an after-close AI review note?

An after-close review note is a four-part recap you read yourself. It is not a buy or sell signal. Build it only after the local SQLite file from the previous note already holds today's bars. The model interprets rows you queried. It does not fetch prices, news, or filings. The four parts are fixed. Today's market is the index move and the count of advancers and decliners, in a sentence or two. Each holding gets today's move, where it sits over the last five sessions relative to your cost or a recent high, and one status line, in at most two sentences. The watchlist part names only the symbols whose return or volume is clearly out of line. Tomorrow's list is something worth a look, not a recommendation. Call an OpenAI-compatible client. The Chinese page uses DeepSeek at https://api.deepseek.com with model deepseek-chat, and a real project reads the key from the environment. If that database has no index, pull the last few days with ak.stock_zh_index_daily(symbol="sh000001") and append those rows to the same fact text. Save the note under briefs/, for example briefs/2025-09-01.md. Push it to WeChat with ServerChan or pushplus, the same path as the morning-brief note. That note is not this article. On Windows Task Scheduler, run weekdays at 18:30, half an hour after the 18:00 ingest, so the file you read is today's. Feed the last 5 to 10 sessions, not the whole history. If you do not want a vendor to see a cost basis, leave that field on the machine and send codes and returns only. This page is not the tool-order guide, not the site FAQ, not the morning brief, not the intraday alert note, and not the AKShare SQLite walkthrough.

Who it is for?

Someone who already stores China A-share daily bars in a local SQLite file and wants a short written review of holdings and a watchlist after the close, then a push to a phone. The numbers come from that database, not from the model's memory.

Who it is not for?

Someone who still needs Python, SQLite, or the daily ingest. Those are the first two notes in this Chinese series, and they do not have an English edition. Someone who wants an alert during the session wants the next note, which is also Chinese-only. Someone who wants a pre-market brief wants a different series. This page does not say what to buy or sell. It is not the tool-order guide, and it is not the site FAQ.

What are the four parts of the note?

Keep the note to four parts you can read in about five minutes. Today's market is the index move plus how many names rose and fell, in one or two sentences. Holdings: for each name, today's move, where it sits over the last five sessions relative to your cost or a recent high, and one status line. Watchlist movers: only the symbols whose return or volume is clearly unusual. Tomorrow: observations the model pulled from the rows you supplied, phrased as something worth a look. That last part is not a recommendation. The prompt caps each name at two sentences.

Why must the numbers come from your database?

The model writes the reading. You supply the facts. Query SQLite, compute today's percent change, the change across the last six bars, and a volume ratio, and paste those lines into the prompt. A figure the model did not receive is a figure you cannot check. The rule in the prompt is explicit: use only the data provided, and do not invent a number, a news item, or a filing. When you spot-check, compare the note with the database. One invented figure is a reason to tighten the prompt.

Which model API do you call?

Any provider that speaks the OpenAI API. The Chinese page installs the openai package and points base_url at https://api.deepseek.com, model deepseek-chat. The snippet shows sk-xxxx and says a real project reads the key from the environment. The prompt states the four rules before the data: no invented figures, no buy or sell advice, four sections, at most two sentences per name. This page does not publish a dollar price. Usage and prices follow the vendor's own site.

Why is the scheduled task at 18:30?

The previous note in the series writes the daily bars with Windows Task Scheduler at 18:00 on weekdays. The review job is a second task, ai-review, Monday to Friday at 18:30, running D:\quant\run_review.bat. The half hour is there so the database you read already contains today. An earlier clock reads yesterday's file and the note looks finished while it is stale. This is the local Windows job. It is not the cloud cron in the morning-brief note, and it is not the AKShare walkthrough.

What pitfalls does this walkthrough call out?

Four. Invented numbers: you provide every figure, the prompt forbids invention, and a spot-check goes back to the database. Privacy: codes and a cost basis leave your machine for the model vendor. If that bothers you, keep cost local and send only the code and the return. Token cost stays small for a few hundred words a day and blows up when you paste the whole history, so send the last 5 to 10 sessions. A fluent note can still be useless. The value is that it shows up every day and that you can read last month's file. Judge it after 30 days, not after one clever paragraph. This is not investment advice. The model output is a research note, not a reason to trade.