Free, open-source Next.js starter for a stock trading bot — wired to the Picckles Signals API, ships in paper-trading mode.
2
stars
4
commits
TypeScript
primary language
Aug 17, 2026
updated
A free, open-source Next.js starter for a stock trading bot — wired to a signals API, running itself on a daily cron. Ships in paper-trading mode.
Most "build a trading bot" tutorials either hand-wave the strategy ("insert your alpha here") or bury you in backtesting before you've written a line. This does the opposite: it treats the strategy as an external input (the Picckles Signals API, a read-only REST endpoint of daily buy/sell signals) and focuses on the engineering that actually trips people up — scheduling, persistence, idempotency, and deploy.
It ships in paper-trading mode so you can watch it work with zero broker setup. Going live is one function to swap (runTick in src/lib/bot.ts).
Vercel Cron (weekdays, 21:05 UTC — just after the US close)
│
▼
GET /api/run ──► runTick(strategy)
│
├─► picckles.ts fetch SELL/HOLD on held positions, then today's BUY signals
├─► bot.ts resolve exits, size new entries to budget, skip symbols already held
└─► store.ts persist positions + trade ledger to Upstash Redis
▲
│
Dashboard ( / ) ──► "Run now" button triggers a manual tick
Each tick (GET /api/run, hit by Vercel Cron or your own scheduler):
The dashboard (/) shows open positions and recent trades, with a Run now button to fire a tick manually — handy for trying it out without waiting for the cron.
| File | Role |
|---|---|
src/app/api/run/route.ts | The cron/HTTP entry point — one tick per request |
src/lib/bot.ts | runTick() — the whole trading loop (exits → entries → persist) |
src/lib/picckles.ts | Thin fetch client for the signals API |
src/lib/store.ts | Upstash Redis: positions + trade ledger |
src/app/page.tsx + RunButton.tsx | The dashboard and manual-run button |
vercel.json | The daily cron schedule |
git clone https://github.com/rkang30/open-trade-bot
cd open-trade-bot
npm install
cp .env.example .env.local
# - free API key: https://picckles.com/api-pricing
# - free Upstash Redis (so positions persist): https://upstash.com
npm run dev
Open localhost:3000 and click Run now.
.env.example (PICCKLES_API_KEY, UPSTASH_REDIS_REST_URL / _TOKEN, a random CRON_SECRET).vercel.json already schedules /api/run for 5 21 * * 1-5 (21:05 UTC, weekdays — shortly after the US close). Adjust to taste.Set STRATEGY in your env to either:
| Strategy | Style | Typical hold |
|---|---|---|
double7-guarded (default) | Buy a strong uptrend on a short-term low, with a VIX crash gate | ~2–3 weeks |
rs-pullback | Buy a relative-strength leader on a fast capitulation dip | ~2–5 days |
Full entry/exit rules: picckles.com/api-docs#strategies.
Everything routes through runTick() in src/lib/bot.ts, which currently only records paper trades via logTrade(). Add a real broker call (Alpaca, Interactive Brokers, etc.) alongside it and the rest of the bot — signal fetching, exit checks, position tracking — is unchanged. The signals client is a plain fetch, so pointing it at a different endpoint is a small edit too.
Is it free? The code is MIT. The signals API and Upstash Redis both have free tiers, so you can run the whole thing at $0.
Do I need to know a trading strategy? No — that's the point. The API supplies the entry/exit decisions; this repo is the runnable wiring around them.
Does it place real trades? No. It's paper-trading by default — no broker keys, no real orders. Wiring a real broker is opt-in and on you (see Going live).
Can I use a different signals source or broker?
Yes. src/lib/picckles.ts is a thin fetch client and runTick() is broker-agnostic — swap either without touching the core loop.
How does it avoid double-buying if a cron tick retries?
Before buying, runTick() loads current positions from Redis and skips any symbol it already holds, and signals only change once per trading day — so re-running a tick (cron retry or the manual button) won't double-buy.
Why Redis instead of a database?
Serverless functions are stateless; positions need to survive between invocations. Redis is the smallest thing that does that. Swap src/lib/store.ts for Postgres if you'd rather.
Step-by-step tutorial with the reasoning behind each piece: How to Build a Stock Trading Bot with Next.js and a Trading Signals API
Signals are informational only and identical for every API subscriber — not personalized investment advice. This bot trades paper money by default; you are responsible for anything you connect to a real broker. Past performance does not predict future results.
4 commits
TypeScript
93.5%
JavaScript
3.5%
CSS
3.0%
Free, open-source Next.js starter for a stock trading bot — wired to the Picckles Signals API, ships in paper-trading mode.
2
stars
4
commits
TypeScript
primary language
Aug 17, 2026
updated
A free, open-source Next.js starter for a stock trading bot — wired to a signals API, running itself on a daily cron. Ships in paper-trading mode.
Most "build a trading bot" tutorials either hand-wave the strategy ("insert your alpha here") or bury you in backtesting before you've written a line. This does the opposite: it treats the strategy as an external input (the Picckles Signals API, a read-only REST endpoint of daily buy/sell signals) and focuses on the engineering that actually trips people up — scheduling, persistence, idempotency, and deploy.
It ships in paper-trading mode so you can watch it work with zero broker setup. Going live is one function to swap (runTick in src/lib/bot.ts).
Vercel Cron (weekdays, 21:05 UTC — just after the US close)
│
▼
GET /api/run ──► runTick(strategy)
│
├─► picckles.ts fetch SELL/HOLD on held positions, then today's BUY signals
├─► bot.ts resolve exits, size new entries to budget, skip symbols already held
└─► store.ts persist positions + trade ledger to Upstash Redis
▲
│
Dashboard ( / ) ──► "Run now" button triggers a manual tick
Each tick (GET /api/run, hit by Vercel Cron or your own scheduler):
The dashboard (/) shows open positions and recent trades, with a Run now button to fire a tick manually — handy for trying it out without waiting for the cron.
| File | Role |
|---|---|
src/app/api/run/route.ts | The cron/HTTP entry point — one tick per request |
src/lib/bot.ts | runTick() — the whole trading loop (exits → entries → persist) |
src/lib/picckles.ts | Thin fetch client for the signals API |
src/lib/store.ts | Upstash Redis: positions + trade ledger |
src/app/page.tsx + RunButton.tsx | The dashboard and manual-run button |
vercel.json | The daily cron schedule |
git clone https://github.com/rkang30/open-trade-bot
cd open-trade-bot
npm install
cp .env.example .env.local
# - free API key: https://picckles.com/api-pricing
# - free Upstash Redis (so positions persist): https://upstash.com
npm run dev
Open localhost:3000 and click Run now.
.env.example (PICCKLES_API_KEY, UPSTASH_REDIS_REST_URL / _TOKEN, a random CRON_SECRET).vercel.json already schedules /api/run for 5 21 * * 1-5 (21:05 UTC, weekdays — shortly after the US close). Adjust to taste.Set STRATEGY in your env to either:
| Strategy | Style | Typical hold |
|---|---|---|
double7-guarded (default) | Buy a strong uptrend on a short-term low, with a VIX crash gate | ~2–3 weeks |
rs-pullback | Buy a relative-strength leader on a fast capitulation dip | ~2–5 days |
Full entry/exit rules: picckles.com/api-docs#strategies.
Everything routes through runTick() in src/lib/bot.ts, which currently only records paper trades via logTrade(). Add a real broker call (Alpaca, Interactive Brokers, etc.) alongside it and the rest of the bot — signal fetching, exit checks, position tracking — is unchanged. The signals client is a plain fetch, so pointing it at a different endpoint is a small edit too.
Is it free? The code is MIT. The signals API and Upstash Redis both have free tiers, so you can run the whole thing at $0.
Do I need to know a trading strategy? No — that's the point. The API supplies the entry/exit decisions; this repo is the runnable wiring around them.
Does it place real trades? No. It's paper-trading by default — no broker keys, no real orders. Wiring a real broker is opt-in and on you (see Going live).
Can I use a different signals source or broker?
Yes. src/lib/picckles.ts is a thin fetch client and runTick() is broker-agnostic — swap either without touching the core loop.
How does it avoid double-buying if a cron tick retries?
Before buying, runTick() loads current positions from Redis and skips any symbol it already holds, and signals only change once per trading day — so re-running a tick (cron retry or the manual button) won't double-buy.
Why Redis instead of a database?
Serverless functions are stateless; positions need to survive between invocations. Redis is the smallest thing that does that. Swap src/lib/store.ts for Postgres if you'd rather.
Step-by-step tutorial with the reasoning behind each piece: How to Build a Stock Trading Bot with Next.js and a Trading Signals API
Signals are informational only and identical for every API subscriber — not personalized investment advice. This bot trades paper money by default; you are responsible for anything you connect to a real broker. Past performance does not predict future results.
4 commits
TypeScript
93.5%
JavaScript
3.5%
CSS
3.0%