Skip to content
AdityaKharmaleGoat7Public

About

A modular stock analysis and decision-support platform featuring live market data, configurable technical indicators, multi-timeframe signals, and paper trading.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

StockIt — Stock Decision Support Platform

A modular, plugin-based stock analysis terminal. Type a ticker, pick a position type (Intraday / Swing / Delivery / Long-term), and every enabled indicator runs against live market data — their weighted contributions roll up into one configurable recommendation signal.

Decision support only — not financial advice.

Stack

Layer Choice
Frontend React 19 + TypeScript + TailwindCSS 4 + Zustand (Vite)
Charts TradingView Lightweight Charts + custom SVG gauge
Backend Fastify 5 + TypeScript
Database SQLite via Prisma (swap the datasource for PostgreSQL in production)
Market data Yahoo Finance (yahoo-finance2 v3) — US + NSE/BSE symbols, no API key

Run it

You'll need Node 22 or newer. The whole thing runs locally on SQLite — no database server to install, no API keys to sign up for.

1. Install and create the database.

npm install
npm run db:push        # creates server/prisma/stockit.db from the Prisma schema

2. Set up your login.

This part matters, so don't skip it. Every API route is locked behind authentication, and the app deliberately won't invent an account for you — a default username and password baked into an open-source repo is a gift to anyone who port-scans your machine later. So you create the first account yourself, and it takes about thirty seconds:

cp server/.env.example server/.env
node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"

Open server/.env and fill in three lines — paste that random string as your JWT_SECRET, then pick an email and password for yourself:

JWT_SECRET=<the string you just generated>
ADMIN_EMAIL=you@example.com
ADMIN_PASSWORD=<a real password, not "admin">

Leave everything else in that file blank for now. It's all optional.

3. Start it.

npm run dev            # API on :4000, web on :5173

Open http://localhost:5173 and sign in with the email and password you just chose. The account is created automatically on first boot, as an admin, and only when the users table is empty — so it's safe to leave those two lines in .env afterwards.

Deep links work too: /?symbol=RELIANCE.NS&tf=delivery.

Stuck at the login screen with no account? That means the server started before ADMIN_EMAIL and ADMIN_PASSWORD were set, so it had nothing to create an account from. Fill them in and restart — it'll pick them up. (Look for the [auth] warning in the server logs; it's telling you the same thing.)

About your money

Nothing here touches real money until you explicitly go looking for it.

Out of the box the auto-trading engine is off, and when you turn it on it runs against a simulated paper-trading broker with a fake balance. Connecting a real brokerage account takes real Upstox API credentials plus a separate confirmed switch in the UI that validates the connection first. You cannot get there by accident.

Everything in server/.env besides those three lines is optional:

Variable What it unlocks Without it
UPSTOX_API_KEY / UPSTOX_API_SECRET Live order placement through Upstox Paper trading only
ANTHROPIC_API_KEY The LLM copilot Copilot is unavailable, everything else works

Market data comes from Yahoo Finance and needs no key at all, so analysis, charts, indicators, strategies, discovery, and paper trading all work the moment you log in.

Architecture

web/  (React SPA, /api proxied to :4000)
  src/stores/        Zustand stores (analysis, indicators, ui)
  src/components/    layout / search / dashboard / admin
  src/pages/         Dashboard · Indicators (admin) · Settings

server/
  src/indicators/
    plugins/         ← one file per indicator (the extension point)
    registry.ts      auto-discovers every plugin file at startup
    lib/math.ts      shared SMA/EMA/RSI/ATR/stddev helpers
  src/services/
    marketData/      MarketDataProvider interface + Yahoo implementation
    scoring.ts       weighted scoring, threshold bands, risk & trend derivation
    analysis.ts      orchestrates quote + history + indicators → response
  src/routes/        stocks · analysis · indicators · settings
  prisma/            IndicatorConfig · SeenPlugin · Setting · AnalysisRecord

How scoring works

Each plugin returns { signal, strength (-1..+1), value, explanation }.

contribution = strength × configured weight × timeframeAffinity[selected timeframe]
final score  = Σ contributions of enabled indicators

The score maps to the highest threshold band it clears (Strong Buy / Buy / Watch / Neutral / Avoid by default) — bands, labels, and colors are editable in Settings and stored in the database. Risk level is derived from recent volatility plus indicator disagreement; trend direction from the trend-category indicators.

The timeframe also selects the candle window: Intraday = 15-min bars × 10 days, Swing = daily × 6 months, Delivery = daily × 1 year, Long-term = weekly × 5 years.

Where the default weights come from

Default weights and timeframe affinities follow the academic evidence on each indicator class (each plugin's description cites its sources):

Weight Indicators Evidence
18 / 14 MA Crossover, Price vs MA Strongest support of any rule class — Brock, Lakonishok & LeBaron (1992, J. Finance); Park & Irwin (2007) survey
14 / 12 MACD, RSI Beat buy-and-hold on 60 yrs of FT30 — Chong & Ng (2008)
12 Rate of Change 3–12-month momentum — Jegadeesh & Titman (1993); Moskowitz, Ooi & Pedersen (2012). Short horizons reverse, so intraday affinity is low
12 Supertrend No direct studies; trend-following logic backed by time-series momentum literature
10 Support/Resistance Trading-range-break rules in Brock et al. (1992); intraday S/R predictive content in Osler (2000)
8 Volume, VWAP Volume is informative but only as confirmation — Blume, Easley & O'Hara (1994); VWAP is an execution benchmark, intraday only
6 Bollinger Bands Consistently underperforms MA rules and buy-and-hold after costs — Leung & Chong (2003); Lento et al. (2007)

These are defaults, not gospel — everything is tunable per instance in the admin panel.

Adding a new indicator

Create one file — nothing else changes:

// server/src/indicators/plugins/my-indicator.ts
import type { IndicatorPlugin } from "../../types.js";

const plugin: IndicatorPlugin = {
  id: "my-indicator",
  name: "My Indicator",
  description: "What it measures.",
  category: "momentum",            // momentum | trend | volatility | volume | level
  defaultWeight: 10,
  paramSchema: {
    period: { label: "Period", type: "number", default: 14, min: 2, max: 100 },
  },
  timeframeAffinity: { intraday: 1, swing: 1, delivery: 1, longterm: 1 },
  compute(candles, params, ctx) {
    return { signal: "buy", strength: 0.5, value: "…", explanation: "…" };
  },
};
export default plugin;

On the next server start the registry discovers it, seeds a default config row, and it appears in the admin panel and the scoring engine automatically. The SeenPlugin table guarantees seeding happens once — deleting the indicator in the admin panel won't resurrect it.

The admin panel can also add multiple instances of the same plugin with different parameters (e.g. RSI-14 and RSI-7), tune weights, toggle, reorder, and delete — all persisted.

API

Endpoint Purpose
GET /api/stocks/search?q= autocomplete
GET /api/stocks/:symbol/quote live quote
GET /api/stocks/:symbol/profile company fundamentals (sector, P/E, margins, analyst targets…)
POST /api/analysis {symbol, timeframe} full analysis
GET /api/analysis/recent history log
GET /api/indicators · POST · PATCH/:id · DELETE/:id · POST /reorder admin CRUD
GET /api/indicators/plugins discovered plugin types
GET/PUT /api/settings/thresholds signal bands

Deployment

Pushing to main runs GitHub Actions (.github/workflows/deploy.yml): typecheck + tests, then an SSH deploy of the backend to EC2 and a frontend sync to S3/CloudFront, followed by a smoke test. Full production runbook (architecture, secrets, networking, monitoring, cost) lives in deploy/README.md.

For a lighter single-box setup — nginx serves the built SPA directly instead of S3/CloudFront (deploy/nginx/stockit-iponly.conf) — run bash deploy/scripts/deploy.sh on the EC2 box. It pulls main, applies the Prisma schema, runs server tests, builds both workspaces, and reloads PM2, rolling back automatically if the post-deploy health check fails.

Swapping pieces

  • Data feed: implement MarketDataProvider (server/src/services/marketData/provider.ts) and export it from analysis.ts — search, quotes, and candles all flow through it.
  • Database: change the datasource in server/prisma/schema.prisma to postgresql and set a connection string; the Prisma models are portable.

About

A modular stock analysis and decision-support platform featuring live market data, configurable technical indicators, multi-timeframe signals, and paper trading.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages