SaaS 行业发生了什么?别光看“蒸发 2 万亿美元”,自己搭个监控更靠谱
你可能也刷到过这种信息:
- Figma 从 52 周高点跌了 86.5%
- Duolingo 跌 83.3%
- Monday 跌 80.2%
- HubSpot 跌 69%
- 软件 ETF(IGV)从高点回撤 35%+
- 有研报直接写:“软件崩盘全面扩散,无处可藏。”
数字很吓人。更吓人的是:大多数人只会转发,然后继续焦虑。
咱们换个玩法:做一个“SaaS 崩盘雷达”。每天自动跑一遍:
- 每只股票离 52 周高点跌了多少(回撤)
- RSI 到底有没有“超卖到离谱”
- 把数据塞给大模型,生成一页式晨报(能直接发 Slack/飞书/邮箱)
你是做投资、做 SaaS 产品、做增长的都用得上。
⚠️ 免责声明:下面是数据分析与自动化教程,不是投资建议。
你要的效果长这样(每天一页,3 分钟看完)
- 板块体感:今天 SaaS 平均回撤 -X%,IGV 跌幅 -Y%
- 高危名单:回撤 >70% 的公司列表
- 情绪温度计:RSI < 20 的标的(通常是“极度超卖”区间)
- 一句人话总结:大模型用你的口吻写成晨报,顺便带上风险提示
想象一下场景:
你早上打开电脑,不用刷十个 App,不用等别人“解读”,你的系统已经把“谁在崩、崩到什么程度、是否极端”摆在你面前。😎
准备清单(10 分钟搞定)
- Python 3.10+
- 依赖:
yfinance、pandas、numpy、ta(算 RSI)、openai(可选,用来写晨报)
安装:
pip install yfinance pandas numpy ta openai
不想接大模型也行,先把指标跑起来,照样能用。
第一步:抓取股价数据(含 52 周高点)
下面用 yfinance 拉取近 1 年日线数据,然后算:
- 52 周最高价
- 当前价
- 从高点回撤(Drawdown)
import yfinance as yf
import pandas as pd
import numpy as np
TICKERS = [
"DUOL", # Duolingo
"MNDY", # monday.com
"HUBS", # HubSpot
"IGV" # iShares Expanded Tech-Software Sector ETF
]
def fetch_1y_history(ticker: str) -> pd.DataFrame:
df = yf.download(ticker, period="1y", interval="1d", auto_adjust=True, progress=False)
df = df.dropna()
return df
def calc_drawdown_from_52w_high(df: pd.DataFrame) -> dict:
high_52w = df["Close"].max()
last = df["Close"].iloc[-1]
dd = (last / high_52w - 1.0) * 100
return {"high_52w": high_52w, "last": last, "drawdown_pct": dd}
rows = []
for t in TICKERS:
df = fetch_1y_history(t)
m = calc_drawdown_from_52w_high(df)
rows.append({"ticker": t, **m})
out = pd.DataFrame(rows).sort_values("drawdown_pct")
print(out)
你会得到一个很直观的表。
drawdown_pct = -80就是离 52 周高点还差 80%- 表格按回撤从大到小排,谁最惨一眼看出来
第二步:加上 RSI(给“恐慌程度”一个量化刻度)
新闻里那种“RSI 跌到 18,几十年最超卖”到底是什么意思?
简单说:
- RSI 30 以下:偏超卖
- RSI 20 以下:很极端(别急着抄底,也别急着割肉,先看清楚)
用 ta 来算:
from ta.momentum import RSIIndicator
def calc_rsi(df: pd.DataFrame, window: int = 14) -> float:
rsi = RSIIndicator(close=df["Close"], window=window).rsi()
return float(rsi.iloc[-1])
rows = []
for t in TICKERS:
df = fetch_1y_history(t)
dd = calc_drawdown_from_52w_high(df)
rsi_last = calc_rsi(df)
rows.append({"ticker": t, **dd, "rsi14": rsi_last})
out = pd.DataFrame(rows)
out["risk_flag"] = np.where((out["drawdown_pct"] <= -70) | (out["rsi14"] < 20), "⚠️", "")
out = out.sort_values(["risk_flag", "drawdown_pct"], ascending=[False, True])
print(out)
这张表就是你的“雷达屏”。
你可以把阈值改成你自己的风格:
- 回撤 > 60% 就提醒
- RSI < 25 就提醒
- ETF 也加入监控,让你知道是“个股暴雷”还是“全板块下沉”
第三步:让大模型把表格写成“人话晨报”(可复制到飞书)
你不需要一堆指标解释。你需要一段能直接转发的文字:
- 今天最危险的是谁
- 板块是不是系统性下跌
- RSI 有没有到极端
- 提醒团队:别拍脑袋决策
示例:用 OpenAI API 生成晨报。
import os
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def generate_report(df: pd.DataFrame) -> str:
table = df[["ticker", "last", "high_52w", "drawdown_pct", "rsi14"]].to_csv(index=False)
prompt = f"""
你是一个说人话的市场观察员,语气克制但不无聊。
根据这份表格写一段晨报:
- 用 5~10 行短句
- 点名回撤最大的 3 个
- 点名 RSI 最低的 3 个
- 提醒:指标只代表情绪与位置,不等于反转
表格(CSV):
{table}
"""
resp = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{"role": "system", "content": "你写中文。少套话,多结论。"},
{"role": "user", "content": prompt}
],
temperature=0.4
)
return resp.choices[0].message.content
print(generate_report(out))
你会得到一段可直接发群里的文字。
如果你还想更“实用”一点:
- 加一行“IGV 今天回撤/RSI”,当作板块温度
- 加一句“如果你是做 SaaS 增长/采购的,预算和合同周期可能会被砍,现金流要盯紧”
第四步:每天自动跑(定时 + 输出到 Markdown)
你可以把结果输出成 report.md,再用任何方式发出去。
from datetime import datetime
def to_markdown_report(df: pd.DataFrame, text_summary: str) -> str:
ts = datetime.now().strftime("%Y-%m-%d")
md = []
md.append(f"# SaaS 崩盘雷达日报|{ts}\n")
md.append(text_summary + "\n")
md.append("## 指标表\n")
md.append(df[["ticker","last","high_52w","drawdown_pct","rsi14","risk_flag"]].to_markdown(index=False))
md.append("\n## 备注\n")
md.append("- 回撤=当前价相对 52 周最高价的跌幅\n- RSI 只是情绪与位置,不是反转按钮\n")
return "\n".join(md)
summary = "(这里放大模型生成的晨报文字)"
md = to_markdown_report(out, summary)
with open("report.md", "w", encoding="utf-8") as f:
f.write(md)
print("written: report.md")
定时方式你随便挑:
- Mac/Linux:
crontab - Windows:任务计划程序
- 云端:GitHub Actions 每天跑一次,顺便把报告推到仓库
你该怎么用这套东西(更贴近真实工作)
场景 A:你在做 SaaS 产品
股价不等于产品,但它会影响客户心态。
- 看到板块整体 RSI 逼近极端,你就要预期:客户 CFO 会更保守
- 你可以提前做两件事:
- 把“年度付费折扣/更灵活的合同”准备好
- 把回款周期、续费风险拉成看板,每周盯
场景 B:你在做增长/投放
当市场进入“风险厌恶”,获客成本的波动会更疯。
- 用你的雷达看板块情绪
- 情绪崩时,别跟算法硬刚
- 预算分配倾向:更偏向可归因、更偏向存量(续费/扩展),少做“赌增长”
场景 C:你在做投资/研究
你需要的是“系统性风险” vs “个股暴雷”的区别。
- IGV 也一起监控
- 看到 ETF 也下沉,别把一切归咎于某家公司
避坑清单(不想被指标带沟里)
- 只看 RSI 就抄底:RSI 能在低位待很久,尤其是系统性下跌时。
- 只看回撤就觉得“便宜”:回撤大可能是估值回归,也可能是基本面坏了。
- 数据源不校验:
yfinance偶尔会缺数据或复权异常。关键标的建议多源交叉验证。 - 拿 52 周高点当信仰:高点可能是泡沫顶,拿它当锚点会让你心理误判。
- 用单一阈值管所有公司:高波动 SaaS 和成熟软件巨头,阈值得分开。
你可以继续加码的升级点(更像专业团队在用)
- 加入 收入增速、毛利率、Rule of 40(需要财报数据源)
- 把“做空收益/空头仓位”接进来(数据更贵,但更刺激)
- 做一个小网页:点击某个 ticker,直接出价格曲线、RSI、回撤曲线
- 把研报标题、公司新闻丢给大模型,做“情绪标签”:裁员/下调指引/监管/并购
想让我把这套“崩盘雷达”扩展成一个可直接部署的项目(带 GitHub Actions + 飞书推送 + 多股票名单配置),把你关注的 ticker 列表发我就行。