尚未检测到更新。GitHub 发布版本后会显示在这里。
Stocks App
翻译准备中
正在加载完整 README。 以下为已保存的摘录。
A warm-up pen for trading. Bullpen is a phone-first PWA that sits on top of
the Alpaca paper-trading API so you can learn how
markets and order mechanics actually behave without risking real money —
and, if you ever decide to, switch the same app to a live account by changing
one environment variable.
Milestone 1 (this commit): watchlist with live quotes, candlestick chart,
manual order ticket, account/positions/orders view, and a trade journal —
all routed through a single order pipeline with a risk guard.查看完整 README ↗A warm-up pen for trading. Bullpen is a phone-first PWA that sits on top of the Alpaca paper-trading API so you can learn how markets and order mechanics actually behave without risking real money — and, if you ever decide to, switch the same app to a live account by changing one environment variable.
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request. In particular, all orders must go through pipeline.submit() so the risk guard and journal can't be bypassed.
Milestone 1 (this commit): watchlist with live quotes, candlestick chart, manual order ticket, account/positions/orders view, and a trade journal — all routed through a single order pipeline with a risk guard.
manual ticket ─┐
├──► OrderIntent ──► riskGuard ──► journal ──► BrokerAdapter ──► Alpaca
strategies ────┘ (pure, unit-tested) (always) (only if guard OK)
(later)
src/pipeline/orderPipeline.ts is the only
thing allowed to call broker.submitOrder(). The manual ticket and every
future automated strategy call pipeline.submit(intent), so the risk limits
and the journal can never be bypassed.src/pipeline/riskGuard.ts, limits in src/config/risk.ts):
max order value, max position per symbol, daily-loss stop, no shorting,
optional market-hours check, blocklist. Pure function with unit tests.client_order_id starts with its source
(manual-…, sma-cross-…), so the Account screen can show whose order it
was even after a reload, and strategies will only ever manage their own
positions.src/broker/types.ts knows nothing about Alpaca;
src/broker/alpaca/AlpacaAdapter.ts is the only Alpaca-specific file.See BETA.md — the one-page getting-started guide to send people.
The hosted app lives on GitHub Pages and talks to Alpaca through the small
Cloudflare Worker in relay/ (paper-only). Testers bring
their own free Alpaca paper keys via ☰ → Settings, so nothing secret ships
with the build.
The pieces: GitHub Pages serves the static PWA; the Cloudflare Worker in
relay/ forwards /api/* to Alpaca. The app only learns the relay's URL at
build time, through the VITE_API_BASE variable — forget it and the
hosted app shows "Can't reach the API (404)".
wrangler login
opens the browser to create/sign in — GitHub login works):
cd C:\projects\Bullpen\relay
npx wrangler login
npx wrangler deploy
npx wrangler secret put FINNHUB_KEY
The first deploy asks you to register a workers.dev subdomain
(mikecostarella). It prints the relay URL:
https://bullpen-relay.mikecostarella.workers.dev. A new subdomain's TLS
certificate takes 5–15 minutes; until then the browser shows
ERR_SSL_VERSION_OR_CIPHER_MISMATCH. Check <url>/health afterwards.react-app/.env.local, and make sure .env.example holds only
placeholders. Then Settings → General → Danger Zone → Change visibility.VITE_API_BASE, Value the relay URL with no trailing slash → Add
variable. deploy.yml reads it as vars.VITE_API_BASE.main, or Actions → Deploy to GitHub Pages → Run
workflow. Any time the variable changes, re-run the workflow — the value
is baked into the bundle.Later changes: app code → just push (Pages redeploys). Relay code or
ALLOWED_ORIGINS → npx wrangler deploy from relay/. Ending the beta →
remove VITE_BETA from deploy.yml.
Create a free Alpaca account at https://app.alpaca.markets, open Paper Trading, and generate an API key + secret.
Copy react-app/.env.example to react-app/.env.local and paste the keys in.
.env.local is git-ignored.
Install and run:
cd C:\projects\Bullpen\react-app
npm install
npm run dev
Alpaca's API has no CORS headers, so the browser can't call it directly. In
development the Vite dev server proxies /api/trading and /api/data to
Alpaca and injects the keys server-side (they never reach the browser
bundle). To use it from your phone on the same Wi-Fi:
cd C:\projects\Bullpen\react-app
npm run dev:lan
then open the Network: URL Vite prints (e.g. http://192.168.1.20:5173/Bullpen/)
on the phone and "Add to Home Screen". You may need to allow port 5173 through
Windows Firewall the first time.
The GitHub Pages deploy (.github/workflows/deploy.yml) publishes the static
shell, but it has no proxy behind it — the app will show a "can't reach the
API" banner there until the Bullpen backend exists. That backend will serve the
same two /api/* routes, and VITE_API_BASE points the PWA at it.
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗