Open-Dev-Society/OpenStock
摘要
OpenStock 是一个开源股票市场平台,提供实时价格跟踪、个性化提醒和公司洞察,使用 Next.js 和 TypeScript 构建。
查看缓存全文
缓存时间: 2026/05/26 12:30
Open-Dev-Society/OpenStock
来源:https://github.com/Open-Dev-Society/OpenStock
也请查看其他精彩项目,OpenReadme 现已上线。
© Open Dev Society。本项目基于 AGPL-3.0 许可证;如果您修改、重新分发或部署本项目(包括作为网络服务),您必须在相同许可证下发布您的源代码,并注明原作者。
OpenStock
OpenStock 是一个开源的替代昂贵市场平台的工具。追踪实时价格、设置个性化提醒、探索详细的公司洞察 —— 公开构建,面向所有人,永远免费。
注意:OpenStock 由社区构建,并非券商。市场数据可能根据提供商规则和您的配置有所延迟。此处内容不构成任何财务建议。
📋 目录
- ✨ 简介
- 🌍 Open Dev Society 宣言
- ⚙️ 技术栈
- 🔋 功能特性
- 🤸 快速开始
- 🐳 Docker 部署
- 🔐 环境变量
- 🧱 项目结构
- 📡 数据与集成
- 🧪 脚本与工具
- 🤝 贡献指南
- 🛡️ 安全
- 📜 许可证
- 🙏 致谢
✨ 简介
OpenStock 是一个现代化的股票市场应用,基于 Next.js(App Router)、shadcn/ui 和 Tailwind CSS 构建,使用 Better Auth 进行认证,MongoDB 进行持久化存储,Finnhub 提供市场数据,TradingView 小部件用于图表和市场视图。
🌍 Open Dev Society 宣言
我们生活在一个知识被隐藏在付费墙之后的世界里。工具被锁定在订阅中。信息被偏见扭曲。新人被告知他们“不够好”去构建。我们相信存在一种更好的方式。
- 我们的信念:技术应该属于每一个人。知识应该开放、免费、可访问。社区应该以信任欢迎新人,而不是设门槛。
- 我们的使命:建设真正有所作为的免费开源项目:
- 专业人士和学生可以无门槛使用的工具。
- 学习永远免费的开放知识平台。
- 每个初学者都被引导而非评判的社区。
- 基于信任而非盈利运行的资源。
- 我们的承诺:我们永远不会锁住知识,永远不会收取访问费用,永远不会用信任换取金钱。我们依靠透明度、捐赠以及社区的力量运转。
- 我们的号召:如果你曾觉得自己不属于这里、难以找到免费资源,或者想要构建有意义的东西——你属于这里。因为未来属于那些开放构建它的人。
⚙️ 技术栈
核心
- Next.js 15(App Router)、React 19
- TypeScript
- Tailwind CSS v4(通过 @tailwindcss/postcss)
- shadcn/ui + Radix UI 原语
- Lucide 图标
认证与数据
- Better Auth(邮箱/密码)搭配 MongoDB 适配器
- MongoDB + Mongoose
- Finnhub API(用于股票代码、公司简介、市场新闻)
- TradingView 嵌入式小部件
自动化与通信
- Inngest(事件、定时任务、通过 Gemini 进行 AI 推理)
- Nodemailer(Gmail 传输)
- next-themes、cmdk(命令面板)、react-hook-form
语言组成
- TypeScript(~93.4%)、CSS(~6%)、JavaScript(~0.6%)
🔋 功能特性
- 身份认证
- 使用 Better Auth + MongoDB 适配器的邮箱/密码认证
- 通过 Next.js 中间件强制保护路由
- 全局搜索与 Command + K 面板
- 由 Finnhub 支持的快速股票搜索
- 空闲时显示热门股票;支持防抖查询
- 自选股列表
- 每个用户的独立自选股列表存储在 MongoDB 中(每个用户每个股票代码唯一)
- 股票详情
- TradingView 股票代码信息、K 线图/高级图表、基线、技术指标
- 公司简介和财务数据小部件
- 可选的跨来源情绪洞察(Reddit、X.com、新闻、Polymarket)
- 市场概览
- 热力图、报价、头条新闻(TradingView 小部件)
- 个性化引导流程
- 收集国家、投资目标、风险承受能力、偏好行业
- 邮件与自动化
- AI 个性化欢迎邮件(通过 Inngest 使用 Gemini)
- 每日新闻摘要邮件(定时任务),根据用户自选股列表个性化
- 精美 UI
- shadcn/ui 组件、Radix 原语、Tailwind v4 设计令牌
- 默认深色主题
- 键盘快捷键
- Cmd/Ctrl + K 用于快速操作/搜索
🤸 快速开始
前提条件
- Node.js 20+ 和 pnpm 或 npm
- MongoDB 连接字符串(MongoDB Atlas 或通过 Docker Compose 本地运行)
- Finnhub API 密钥(支持免费套餐;实时数据可能需要付费)
- 用于发送邮件的 Gmail 账户(或更新 Nodemailer 传输方式)
- 可选:Google Gemini API 密钥(用于 AI 生成的欢迎介绍)
克隆并安装
git clone https://github.com/Open-Dev-Society/OpenStock.git
cd OpenStock
# 选择其一:
pnpm install
# 或
npm install
配置环境
- 创建
.env文件(参见环境变量)。 - 验证数据库连接:
pnpm test:db
# 或
npm run test:db
运行开发环境
# Next.js 开发(Turbopack)
pnpm dev
# 或
npm run dev
本地运行 Inngest(工作流、定时任务、AI)
npx inngest-cli@latest dev
构建并启动(生产模式)
pnpm build && pnpm start
# 或
npm run build && npm start
打开 http://localhost:3000 查看应用。
🐳 Docker 部署
你可以通过 Docker Compose 轻松运行 OpenStock 和 MongoDB。
- 确保已安装 Docker 和 Docker Compose。
docker-compose.yml包含两个服务:openstock(本应用)mongodb(MongoDB 数据库,带持久化卷)
- 创建你的
.env文件(参见下方示例)。对于 Docker 部署,使用类似如下本地连接字符串:
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin
- 启动服务栈:
# 在仓库根目录下
docker compose up -d mongodb && docker compose up -d --build
- 访问应用:
- 应用:http://localhost:3000
- MongoDB 在 Docker 网络内可通过 host
mongodb:27017访问。
注意事项
- 应用服务依赖于 mongodb 服务。
- 凭据在 Compose 文件中为 MongoDB root 用户定义;连接字符串需使用
authSource=admin用于 root 用户。 - 数据通过 Docker 卷持久化,重启后保留。
可选:本项目使用的 MongoDB 服务定义示例:
services:
mongodb:
image: mongo:7
container_name: mongodb
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mongo-data:
🔐 环境变量
在项目根目录创建 .env 文件。选择托管 MongoDB(Atlas)URI 或本地 Docker URI。
托管(MongoDB Atlas):
# 核心
NODE_ENV=development
# 数据库(Atlas)
MONGODB_URI=mongodb+srv://<用户名>:<密码>@<集群地址>/<数据库名>?retryWrites=true&w=majority
# Better Auth
BETTER_AUTH_SECRET=你的BetterAuth密钥
BETTER_AUTH_URL=http://localhost:3000
# Finnhub
# 注意:Vercel部署需要NEXT_PUBLIC_FINNHUB_API_KEY
NEXT_PUBLIC_FINNHUB_API_KEY=你的Finnhub密钥
FINNHUB_BASE_URL=https://finnhub.io/api/v1
# 情绪洞察(可选)
ADANOS_API_KEY=你的Adanos密钥
# ADANOS_API_BASE_URL=https://api.adanos.org
# AI 提供商(可选,默认:"gemini")
# 支持:"gemini", "minimax", "siray"
# AI_PROVIDER=gemini
# Gemini
GEMINI_API_KEY=你的Gemini密钥
# MiniMax(可选,当AI_PROVIDER=minimax时使用,或作为后备)
# 在 https://platform.minimaxi.com 获取密钥
# MINIMAX_API_KEY=你的MiniMax密钥
# Inngest 签名密钥(Vercel部署必需)
# 在 Inngest 仪表盘获取:https://app.inngest.com/env/settings/keys
INNGEST_SIGNING_KEY=你的Inngest签名密钥
# 邮件(通过Gmail的Nodemailer;如果启用两步验证,考虑使用应用专用密码)
[email protected]
NODEMAILER_PASSWORD=你的Gmail应用专用密码
本地(Docker Compose)MongoDB:
# 核心
NODE_ENV=development
# 数据库(Docker)
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin
# Better Auth
BETTER_AUTH_SECRET=你的BetterAuth密钥
BETTER_AUTH_URL=http://localhost:3000
# Finnhub
# 注意:Vercel部署需要NEXT_PUBLIC_FINNHUB_API_KEY
NEXT_PUBLIC_FINNHUB_API_KEY=你的Finnhub密钥
FINNHUB_BASE_URL=https://finnhub.io/api/v1
# 情绪洞察(可选)
ADANOS_API_KEY=你的Adanos密钥
# ADANOS_API_BASE_URL=https://api.adanos.org
# AI 提供商(可选,默认:"gemini")
# 支持:"gemini", "minimax", "siray"
# AI_PROVIDER=gemini
# Gemini
GEMINI_API_KEY=你的Gemini密钥
# MiniMax(可选,当AI_PROVIDER=minimax时使用,或作为后备)
# 在 https://platform.minimaxi.com 获取密钥
# MINIMAX_API_KEY=你的MiniMax密钥
# Inngest 签名密钥(Vercel部署必需)
# 在 Inngest 仪表盘获取:https://app.inngest.com/env/settings/keys
INNGEST_SIGNING_KEY=你的Inngest签名密钥
# 邮件(通过Gmail的Nodemailer;如果启用两步验证,考虑使用应用专用密码)
[email protected]
NODEMAILER_PASSWORD=你的Gmail应用专用密码
注意事项
- 尽可能将私密密钥保留在服务端。
- 如果使用
NEXT_PUBLIC_变量,请记住它们会暴露给浏览器。 - 生产环境中,建议使用专门的 SMTP 提供商而非个人 Gmail。
- 不要将密钥硬编码到 Dockerfile 中;需使用
.env和 Compose 文件。
🧱 项目结构
app/
(auth)/
layout.tsx
sign-in/page.tsx
sign-up/page.tsx
(root)/
layout.tsx
page.tsx
help/page.tsx
stocks/[symbol]/page.tsx
api/inngest/route.ts
globals.css
layout.tsx
components/
ui/... # shadcn/radix 原语(button, dialog, command, input 等)
forms/... # InputField, SelectField, CountrySelectField, FooterLink
Header.tsx, Footer.tsx, SearchCommand.tsx, WatchlistButton.tsx, ...
database/
models/watchlist.model.ts
mongoose.ts
lib/
actions/... # 服务端动作(auth, finnhub, user, watchlist)
better-auth/...
inngest/... # 客户端、函数、提示词
nodemailer/... # 传输器、邮件模板
constants.ts, utils.ts
scripts/
test-db.mjs
types/
global.d.ts
next.config.ts # i.ibb.co 图片域名白名单
postcss.config.mjs # Tailwind v4 postcss 配置
components.json # shadcn 配置
public/assets/images/ # 图标和截图
📡 数据与集成
- Finnhub
- 股票搜索、公司简介、市场新闻。
- 设置
NEXT_PUBLIC_FINNHUB_API_KEY和FINNHUB_BASE_URL(默认为 https://finnhub.io/api/v1)。 - 免费套餐可能返回延迟行情;请遵守速率限制和条款。
- Adanos 情绪洞察(可选)
- 跨 Reddit、X.com、新闻和 Polymarket 的结构化股票情绪快照。
- 设置
ADANOS_API_KEY;可通过ADANOS_API_BASE_URL覆盖 API 主机。 - 仅用于股票详情中的情绪卡片,不替代 Finnhub 或 TradingView。
- TradingView
- 用于图表、热力图、报价和时间线的嵌入式小部件。
- 来自
i.ibb.co的外部图片已在next.config.ts中列入白名单。
- Better Auth + MongoDB
- 邮箱/密码认证,使用 MongoDB 适配器。
- 通过中间件进行会话验证;大部分路由受保护,公开例外包括
sign-in、sign-up、静态资源和 Next.js 内部路由。
- Inngest
- 工作流:
app/user.created→ AI 个性化欢迎邮件- 定时任务
0 12 * * *→ 每个用户的每日新闻摘要
- 本地开发:
npx inngest-cli@latest dev。
- 工作流:
- 邮件(Nodemailer)
- Gmail 传输方式。可更新凭据或切换至自己的 SMTP 提供商。
- 包含欢迎邮件和新闻摘要邮件的模板。
🧪 脚本与工具
包脚本
dev:使用 Turbopack 的 Next.js 开发服务器build:生产构建(Turbopack)start:运行生产服务器lint:ESLinttest:db:验证数据库连接
开发者体验
- TypeScript 严格模式
- Tailwind CSS v4(无需独立的 tailwind.config)
- shadcn/ui 组件搭配 Radix 原语
- cmdk 命令面板、next-themes、lucide-react 图标
🤝 贡献指南
你属于这里。无论你是学生、自学成才的开发者,还是经验丰富的工程师 —— 欢迎贡献。
- 提出问题讨论思路和缺陷
- 查找“good first issue”或“help wanted”
- 保持 PR 聚焦;UI 变更请附截图
- 友善待人,指导初学者,不设门槛 —— 这是 ODS 的方式。
🛡️ 安全
如果你发现漏洞:
- 不要公开提交问题
- 发送邮件至:[email protected]
- 我们将协调负责任披露并迅速修复
📜 许可证
OpenStock 将永远保持对所有人免费和开放。本项目基于 AGPL-3.0 许可证 —— 详见 LICENSE 文件。
🙏 致谢
- Finnhub 提供可访问的市场数据
- TradingView 提供可嵌入的市场小部件
- shadcn/ui、Radix UI、Tailwind CSS、Next.js 社区
- Inngest 提供可靠的背景任务和工作流
- Better Auth 提供简单安全的认证
- 所有使开放工具成为可能的贡献者 —— 公开构建,面向所有人,永远免费。
Open Dev Society.
© Open Dev Society。本项目基于 AGPL-3.0 许可证;如果您修改、重新分发或部署本项目(包括作为网络服务),您必须在相同许可证下发布您的源代码,并注明原作者。
我们光荣的贡献者
- ravixalgorithm (https://github.com/ravixalgorithm)
- 从零开始开发了整个应用,包括认证、UI 设计、API 和 AI 集成以及部署。
- Priyanshuu00007 (https://github.com/Priyanshuu00007)
- 制作了 OpenStock 官方 Logo,并贡献了项目的视觉识别。
- chinnsenn (https://github.com/chinnsenn)
- 为仓库配置了 Docker,确保开发和部署流程顺畅。
- koevoet1221 (https://github.com/koevoet1221)
- 解决了 MongoDB Docker 构建问题,提高了项目的整体稳定性和可靠性。
- ettoreciolli1 (https://github.com/ettoreciolli1)
- 更新了 Readme。
❤️ 合作伙伴与支持者
Siray.ai (https://www.siray.ai/) —— 支撑 OpenStock 的强大 AI 基础设施。Siray.ai 确保我们的市场洞察永不停歇。
特别感谢
衷心感谢 Adrian Hajdin (JavaScript Mastery) (https://github.com/adrianhajdin) —— 他出色的股市应用教程对在 Open Dev Society 下为开源社区构建 OpenStock 起到了重要作用。
- GitHub:adrianhajdin (https://github.com/adrianhajdin)
- YouTube 教程:Stock Market App Tutorial (https://www.youtube.com/watch?v=gu4pafNCXng)
- YouTube 频道:JavaScript Mastery (https://www.youtube.com/@javascriptmastery)
相似文章
@SusChan444: 兄弟们,股票数据终于不用后端了! chengzuopeng/stock-sdk —— 纯 JS/TS 股票行情 SDK,零Python、零后端,直接浏览器/Node.js拿实时数据!真香点: · 支持 A股/港股/美股/公募基金,实时行情…
Stock-SDK 是一个纯 JavaScript/TypeScript 的股票行情 SDK,支持浏览器和 Node.js 获取 A 股/港股/美股/基金实时数据,提供 CLI 和 MCP 接入 AI 工具,专为前端和量化开发设计。
为股票、基金和投资交易构建的开源反方辩手
一个多智能体开源工具,使用 OpenAI 智能体和 Valyu 金融搜索构建,通过扮演多头、空头、内部观点检查者、综合者和具有约束力的反方辩手来压力测试投资论点。
hello245m/free-stockdb
A local quantitative engine for A-share stock and ETF minute/day K-line data, with incremental sync, local cache, batch query, backtesting, and indicator calculation.
facebook/astryx
Meta开源了Astryx,一个基于React和StyleX的可定制设计系统,拥有150多个可访问组件、CLI工具和AI友好的API。
oblien/openship
Openship 是一个开源、可自托管的部署平台,内置 CI/CD,支持任何技术栈、数据库、域名、SSL 等,可通过桌面应用、网页仪表盘或 CLI 访问。