尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A personal stock screener and portfolio management platform with quant-grade analytics:
The repo is split into two independently deployable services:
algo-trader/
├── frontend/ Next.js 16 app (App Router, Tailwind) — port 3000
│ ├── src/
│ ├── public/
│ ├── package.json
│ └── .env.example copy to .env.local
└── backend/ Flask quant/data API — port 5000
├── app.py
├── requirements.txt
└── .env.example copy to .env
They talk over HTTP only: the frontend's server-side BFF proxy reads FLINT_API_URL (see
frontend/src/app/api/backend) and the backend allows CORS on /api/*. There is no
shared code or build step between them, so either can be deployed on its own.
frontend/src/ — Next.js 16 (App Router, Tailwind) frontend on port 3000backend/ — Flask quant/data backend on port 5000
quant_models.py — multi-factor signal engine + trade levels + Kelly sizingrisk_analytics.py — VaR/CVaR, Sharpe/Sortino, drawdown, beta, correlationsnews_engine.py — Google News RSS + VADER sentiment (5-min cache)ai_assistant.py — Gemini chat grounded in live portfolio/signal contextml_models.py — news sentiment, Markowitz optimizationagents_desk.py — multi-agent trading desk: analyst team, bull/bear debate,
risk committee, PM sign-off, plus the alpha-scored decision journal that
feeds the reflection memorybacktest/ — event-driven backtester: engine.py (target-position fills,
costs, stops), riskengine.py (risk sizing, scale-outs, per-leg exits),
swingpro.py (the Pine v6 port), indicators.py (TradingView-equivalent,
Wilder's smoothing), metrics.py, analysis.py (out-of-sample,
walk-forward, Monte Carlo) and service.py (request → JSON)llm_router.py — OmniRoute fallback transport, engaged only once Gemini
reports its quota is gone (see "Surviving the Gemini rate limit" below)geotrade_layer.py — country macro analysisOne trading-desk run is roughly 10 + 2 x rounds model calls — 14 at the
default 2 rounds. A free-tier Gemini key will exhaust its per-minute quota
partway through, which used to leave the later seats empty.
Two mitigations, in order:
agents_desk.py) — handles the common case where the
quota is a per-minute window and the next attempt succeeds.llm_router.py, optional) — when Gemini says it is
out of quota, remaining seats are served by a local
OmniRoute gateway instead.The fallback is deliberately strict, so the desk does not quietly stop being a Gemini app:
RESOURCE_EXHAUSTED, and Gemini is benched
for exactly the retryDelay it asked for (falling back to 90s if it did not
say). A short per-minute 429 can never release a longer bench.done event
reports how many seats the fallback served.npm install -g omniroute # ~830 MB unpacked
omniroute serve # OpenAI-compatible gateway on :20128
Nothing else is required — OmniRoute ships with free keyless providers, so the
fallback works with no configuration. To pin it to your own keys and ordering,
use omniroute keys add and a priority combo. Settings live in
backend/.env (see .env.example); OMNIROUTE_ENABLED=0 disables it outright.
GET /api/agents/routing reports where desk calls are currently going, which
distinguishes "quota exhausted, rerouted" from "quota exhausted, no fallback
installed".
The engines are a direct port of a standalone desktop tester, and they are verified bar-for-bar against it — same fills, same costs, same trade log on the same frame. The conventions are all deliberately pessimistic:
process_orders_on_close), and the stop it places there only goes live next bar.ta.rma) is used for RSI, ATR and ADX, exactly as Pine does.
Using a simple mean here is the usual reason a Python port disagrees with TradingView.Three passes attack the result from different sides, because a single backtest over all available history answers the question least worth asking:
| Pass | What it does |
|---|---|
| Out-of-sample | Holds back the tail, fits nothing to it, looks once |
| Walk-forward | Re-optimises on a rolling window, trades the window after it, and stitches those untouched segments into one curve |
| Monte Carlo | Keeps the trades, resamples their order, and reports the spread rather than the one path that happened |
backtest/data.py draws bars from data_source rather than opening a second connection
to Yahoo, so a backtest shares the throttle, cache and stale-if-error fallback the rest of
the backend uses. Full daily history goes through data_source.get_ohlc_max: asking Yahoo
for range=max&interval=1d quietly returns coarsened bars (~170 quarterly candles for
AAPL rather than 11,500 daily ones), so that path asks with an explicit date window instead.
cd backend
(Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned) ; (& c:\Users\asus\Desktop\algo-trader-backend\venv\Scripts\Activate.ps1)
./venv/bin/pip install -r requirements.txt
cp .env.example .env # then fill in GEMINI_API_KEY
./run.sh
run.sh handles a macOS quirk: on machines behind a TLS-intercepting corporate proxy it
exports the system keychain CAs so Yahoo Finance / Google News / Gemini requests don't fail
with certificate errors. (./venv/bin/python app.py also works on a normal network.)
Secrets live in backend/.env (gitignored; template in backend/.env.example). The Gemini
key powers the AI assistant, deep analysis and Geotrade:
GEMINI_API_KEY=your_key_here
cd frontend
npm install
cp .env.example .env.local
npm run dev
Open http://localhost:3000. Run this in a second terminal — the two services are separate processes.
.env.local holds FLINT_API_URL (defaults to http://127.0.0.1:5000) and the Clerk
keys; template in frontend/.env.example. FLINT_API_URL is server-only: the Next.js
server calls the API, so the browser never sees it.
Vercel builds one directory, so point it at the frontend rather than the repo root:
frontend (Project Settings → General)FLINT_API_URL, NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEYThe Flask backend is not deployed by this — it needs its own host (Render, Railway, Fly,
a VPS) with GEMINI_API_KEY set there, and its public URL becomes FLINT_API_URL.
| Endpoint | Description |
|---|---|
GET /api/quant-signals?symbol= | Multi-factor signal, entry/stop/targets, Kelly sizing |
POST /api/portfolio-analytics | VaR, CVaR, Sharpe, Sortino, drawdown, beta, sectors |
GET /api/news | Global news with per-headline sentiment + mood indices |
GET /api/news/ticker?symbol= | Ticker-specific headlines + sentiment |
POST /api/ai-chat | Portfolio-aware Gemini assistant |
GET /api/ml-insights?symbol= | Pivots, fear/greed |
POST /api/portfolio-optimization | Markowitz max-Sharpe weights + CAPM betas |
GET /api/backtest/strategies | Strategy catalogue with every parameter and its default |
POST /api/backtest/run | One backtest + out-of-sample split + Monte Carlo |
POST /api/backtest/optimize | Parameter sweep, streamed as SSE |
POST /api/backtest/walk-forward | Rolling optimise-then-trade folds, streamed as SSE |
All trading is paper trading. Signals and analytics are educational, not financial advice.