Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions LOCAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ Paper desk. Live Binance last for crypto fills. NSE/Yahoo when the cash session

- **Node.js 22 LTS** — [https://nodejs.org](https://nodejs.org) (include npm)
- Windows, macOS, or Linux
- Unzip this folder, e.g. `D:\work Dir\MeridianFinal`
- This operator’s working copy: `D:\work Dir\MeridianFinal-local\MeridianFinal`

No Postgres required. The app uses embedded PGLite unless you set `DATABASE_URL`.

## Quick start (Windows)

1. Unzip to `D:\work Dir\MeridianFinal`
Working copy: **`D:\work Dir\MeridianFinal-local\MeridianFinal`**

1. Open that folder
2. Double-click **`run.bat`**
- First run: `npm install` (a few minutes)
- Copies `.env.example` → `.env` if missing
Expand Down
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
# Meridian Final

Personal multi-asset desk (V1–V4). Paper first. Live Kite stays off.
**Canonical product.** V2 Greeks + V3 auto desk + V4 meta-label, in one paper desk.

- **Auto paper** — ₹10L book, farm sleeve (labels + costs) and PnL sleeve (Kelly, armed after meta promote). Binance overnight; NSE cash/F&O only in the cash session. 10× is a return target, not a promise.
Paper first. Live Kite stays off. Mock book ₹10,00,000.

Older trees are **frozen**. Do not patch V3/V4. Do not use the MeridianV4 repo.

- **Signals / Paper / Paper auto-send** — Signals proposes (Would BUY). Paper waits for Approve / Skip / Size. Paper auto-send fills on its own. Live is locked.
- **Tape** — NSE, FX, COMEX/MCX, every Binance USDT pair
- **Book** — CSV → Buy / Hold / Sell
- **Greeks** — gamma scalping reviews
- **Research** — natural-language names
- **Advice** — spot / futures / options cards
- **Book** — CSV cash ledger, separate from the paper clip book. META is n/a until the paper model promotes.
- **Greeks** — what-if calculator (V2), not the live paper book
- **Research** — natural-language names, or empty if the query does not match
- **Advice** — spot / futures / options cards that respect session and promotion

**Run on your PC:** see [LOCAL.md](LOCAL.md) (`run.bat` on Windows, `run.sh` on macOS/Linux).
**Run on your PC:** see [LOCAL.md](LOCAL.md) (`run.bat` on Windows, `run.sh` on macOS/Linux). localhost and 127.0.0.1 both sign in.

Test login: `WQ3137` / `Test@password`

Python engines: `meridian_final/`. Spec: [docs/BUILD_PLAN.md](docs/BUILD_PLAN.md)
| Doc | |
|-----|--|
| Lineage (V1→Final) | [docs/LINEAGE.md](docs/LINEAGE.md) |
| Build spec | [docs/BUILD_PLAN.md](docs/BUILD_PLAN.md) |
| UX contract | [docs/UX_BACKLOG.md](docs/UX_BACKLOG.md) |
| Python math ports | `meridian_final/` |

Kite keys never belong in git. This is personal software. You can lose the whole book. Nothing here is an order.
2 changes: 1 addition & 1 deletion START_HERE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MERIDIAN FINAL — run on your PC

Windows:
1. Install Node.js 22 LTS from https://nodejs.org (tick "Add to PATH")
2. Unzip this folder to D:\work Dir\MeridianFinal
2. Working copy: D:\work Dir\MeridianFinal-local\MeridianFinal
3. Double-click run.bat
4. Open http://localhost:3000
5. Login WQ3137 / Test@password
Expand Down
7 changes: 4 additions & 3 deletions docs/BUILD_PLAN.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Meridian Final — Build Master Spec

**Last updated:** 23 Aug 2026
**Repos:** [sanjaymaverick-cmd/MeridianFinal](https://github.com/sanjaymaverick-cmd/MeridianFinal)
**Lineage:** V1 advisor → V2 Greeks → V3 auto desk → V4 OpenAlgo / meta-label
**Isolation:** V3 and V4 stay frozen. Final copies math, never patches those trees.
**Canonical repo:** [sanjaymaverick-cmd/MeridianFinal](https://github.com/sanjaymaverick-cmd/MeridianFinal)
**Canonical product:** Meridian Final = V2 Greeks + V3 auto desk + V4 meta-label, one paper desk
**Lineage:** [LINEAGE.md](LINEAGE.md) — V1 advisor → V2 Greeks → V3 auto desk → V4 OpenAlgo / meta-label → **this repo**
**Isolation:** V3 and V4 stay frozen. Final copies math, never patches those trees. Do not use the MeridianV4 GitHub repo as a working tree.

---

Expand Down
51 changes: 51 additions & 0 deletions docs/LINEAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Meridian Final — lineage

**Canonical product:** Meridian Final
**Canonical repo:** [sanjaymaverick-cmd/MeridianFinal](https://github.com/sanjaymaverick-cmd/MeridianFinal)
**As of:** 23 Aug 2026

**Local checkout (operator PC):** `D:\work Dir\MeridianFinal-local\MeridianFinal`

V1–V4 are frozen history. New work ships **only** here. Do not patch the V3 or V4 trees. Do not use [MeridianV4](https://github.com/sanjaymaverick-cmd/MeridianV4) as a working repo.

```
V1 advisor → V2 Greeks → V3 auto desk → V4 OpenAlgo / meta-label
↓
Meridian Final (this repo)
TypeScript desk + meridian_final/ Python ports
```

## What each version contributed

| Version | What it was | What Final kept | Isolation |
|---------|-------------|-----------------|-----------|
| **V1** | Five-factor advisor. Book Buy / Hold / Sell. | Scoring on the imported cash book. | Math copied into `meridian_final/scoring.py` + Book UI. |
| **V2** | Greeks book, gamma scalping. | `/greeks` what-if calculator. Gamma-scalp reviews. Daily PnL = theta. Harvest = ½ Γ (ΔS)². | Copied into `meridian_final/greeks.py`, `gamma_scalp.py`. Not the live paper book. |
| **V3** | Auto paper desk. Short holds, EOD flatten. Honest 199-row meta set (21.6% win, ₹50k). | Farm sleeve, fill tape, gamma rehedge reviews. | V3 files (`build_meta_labels.py`, `meridian_v3_*`) are **read-only**. Never edit. |
| **V4** | OpenAlgo strategy host. mlfinlab-style meta. Longer-hold PnL sleeve. Promotion gates. | Decision-engine math. Farm 90s labels vs PnL (hard stop / 2.2R / trail). Promote only on paper fills. | V4 tree frozen. Ports in `meridian_final/decision.py`. OpenAlgo is optional, not the running desk. |

## What Final is (and is not)

**Is:** one personal paper desk. Mock ₹10,00,000. Signals / Paper / Paper auto-send. Live locked. Kite disarmed. Research that answers the query or returns empty. Promotion in English.

**Is not:** a live broker. An OpenAlgo plugin. A continuation of the MeridianV4 GitHub repo. An order.

## Promotion (from V4, tightened)

PnL sleeve stays flat until **all** of: n ≥ 2000, test AUC ≥ 0.55, hit > 52%. Quality holds (≥300s) counted separately from 90s farm time-stops. Synth-only AUC does not promote. Book META is `n/a` until then — never fake 0%.

## Execution path

```
Research (NL + universe + Grok when signed in)
↓
Scoring (V1) + Meta (V4 logistic, if promoted)
↓
Decision engine (gates, size, manage)
↓
Greeks / gamma reviews (V2)
↓
OMS: paper desk now → Kite / OpenAlgo later, only if LIVE_OK + static IP
```

Spec: [BUILD_PLAN.md](BUILD_PLAN.md). UX contract: [UX_BACKLOG.md](UX_BACKLOG.md). Local run: [../LOCAL.md](../LOCAL.md).
27 changes: 27 additions & 0 deletions docs/UX_BACKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Meridian Final — UX backlog (paper desk)

Shipped on this branch. Constraint: mock capital. Analyzer / Paper only. Kite disarmed. Never “Arm”.

| ID | Item | Where |
|---|---|---|
| UX-01 | Identity strip: MOCK · mode · ENGINE ON\|PAUSED · KITE DISARMED. Modes Signals / Paper / Paper auto-send / Live (locked). No `:live` fill suffix. | `desk-shell`, `ux-copy` |
| UX-02 | Pause ≠ Flatten. Pause keeps exits. Flatten confirms. Resume paper. Duplicate Kill gone. | `desk-shell`, `paper-engine` |
| UX-03 | Promotion verdict in English with n / AUC / hit pass-fail. Quality vs time-stop share. | `promotion-strip` |
| UX-04 | Book META is n/a until promote. Factor Buy decoupled. Two ledgers. | `portfolio.ts`, `portfolio.tsx` |
| UX-05 | localhost and 127.0.0.1 on :3000 and :8080. Guest cannot Pause/Reset/mode. Origin error in English. | `auth/server`, `login`, `desk-shell` |
| UX-06 | Paper mode pending Approve / Skip / Size (15s auto-skip). Flatten-one on clips. Auto-send is explicit. | `paper-engine`, `auto.tsx` |
| UX-07 | Signals last scan stays live with Would BUY / Would SELL. No new fills. | `paper-engine` tick |
| UX-08 | Research returns empty + reason on mismatch. Guest heuristic labelled. Run history. | `research-rank`, `research.tsx` |
| UX-09 | Last decision sentence. Heat vs cap. Farm hold countdown. PnL idle named. | `auto.tsx` |
| UX-10 | English fill/scan reasons. Quote source is not the word live. | `ux-copy` |
| UX-11 | Reset confirms. Not in the header thumb zone next to Pause. | `auto.tsx` |
| UX-12 | Download is the fit set; hold class labelled; count mismatch noted. | `auto.tsx`, `listSamples` |
| UX-13 | Weekend/cash-closed advice does not work NSE cash. Unpromoted meta is not a 0.55 gate to work. | `advice.ts` |
| UX-14 | Mode chips on mobile. Clip cards under md. No forced 720px table. | `desk-shell`, `auto.tsx` |
| UX-15 | Fresh desk starts Signals + paused. Start paper is labelled. | `emptyEngine`, header |
| UX-16 | Greeks titled what-if / calculator. Snapshot marks. | `greeks.tsx` |
| UX-17 | One timestamp column on Command fills. | `index.tsx` |
| UX-18 | Header is the mode source. Auto chips labelled mirrors. | `desk-shell`, `auto.tsx` |
| UX-19 | Book Block. Research Watch / Ignore. Greeks Queue paper hedge / Dismiss. | `desk.ts`, pages |

Preserve: Kite off. Kill/Pause in the header. Pause does not flatten. Resume never sneaks to live.
87 changes: 85 additions & 2 deletions src/components/auto-engine.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { useEffect } from "react";
import { useQuery } from "@tanstack/react-query";
import { getPaperBook, resetPaperBook, setPaperFlags } from "@/lib/server/desk";
import {
getPaperBook,
resetPaperBook,
setPaperFlags,
flattenPaperBook,
flattenPaperClip,
approvePaperPending,
skipPaperPending,
setPaperBlock,
setPaperWatch,
queuePaperHedge,
dismissPaperHedge,
} from "@/lib/server/desk";
import { useDesk } from "@/lib/desk-store";

export function AutoEngine() {
Expand All @@ -20,7 +32,6 @@ export function AutoEngine() {
}

export async function setDeskMode(mode: "advisory" | "paper" | "auto") {
// Optimistic UI — engine used to force mode=auto on every poll; that is fixed.
useDesk.getState().setMode(mode);
try {
const book = await setPaperFlags({ data: { mode } });
Expand Down Expand Up @@ -48,3 +59,75 @@ export async function resetDeskPaper() {
console.error("[desk] reset failed", err);
}
}

export async function flattenDeskPaper() {
try {
const book = await flattenPaperBook();
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] flatten failed", err);
}
}

export async function flattenDeskClip(symbol: string) {
try {
const book = await flattenPaperClip({ data: { symbol } });
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] flatten clip failed", err);
}
}

export async function approveDeskPending(id: string, sizePct?: number) {
try {
const book = await approvePaperPending({ data: { id, sizePct } });
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] approve failed", err);
}
}

export async function skipDeskPending(id: string) {
try {
const book = await skipPaperPending({ data: { id } });
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] skip failed", err);
}
}

export async function blockDeskSymbol(symbol: string, blocked: boolean) {
try {
const book = await setPaperBlock({ data: { symbol, blocked } });
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] block failed", err);
}
}

export async function watchDeskSymbol(symbol: string, watch: boolean) {
try {
const book = await setPaperWatch({ data: { symbol, watch } });
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] watch failed", err);
}
}

export async function queueDeskHedge(symbol: string, note: string, from = "greeks") {
try {
const book = await queuePaperHedge({ data: { symbol, note, from } });
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] queue hedge failed", err);
}
}

export async function dismissDeskHedge() {
try {
const book = await dismissPaperHedge();
useDesk.getState().hydratePaper(book);
} catch (err) {
console.error("[desk] dismiss hedge failed", err);
}
}
38 changes: 38 additions & 0 deletions src/components/confirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Button } from "@/components/ui/button";

export function Confirm({
title,
body,
action,
danger,
onCancel,
onOk,
}: {
title: string;
body: string;
action: string;
danger?: boolean;
onCancel: () => void;
onOk: () => void;
}) {
return (
<div className="fixed inset-0 z-50 flex items-end justify-center bg-bg/70 p-4 sm:items-center">
<div
role="dialog"
aria-modal="true"
className="w-full max-w-md rounded-[24px] border border-border bg-surface p-5 shadow-soft"
>
<h2 className="font-display text-2xl">{title}</h2>
<p className="mt-2 text-sm leading-relaxed text-muted">{body}</p>
<div className="mt-5 flex justify-end gap-2">
<Button variant="ghost" onClick={onCancel}>
Cancel
</Button>
<Button variant={danger ? "danger" : "default"} onClick={onOk}>
{action}
</Button>
</div>
</div>
</div>
);
}
Loading