feat: dealer flow, mirror portfolio (M21), options convexity, FINRA short interest, alert producers, vendor gate
CI / Test & Type-Check (push) Canceled after 0s
CI / Test & Type-Check (push) Canceled after 0s
Snapshot of in-progress module work across multiple slices: - Dealer Flow: dealerExposureEngine, dealerMapService, dealerMapExplain, dealerMapIntegrity, dealerMapReplay, dealerStudyEngine, hanStyleLevels - Mirror Portfolio (M21): fundRepository, captureIngest, mirrorAlertProducers, fund holdings strip, live book, position capture ingest - Options: BSM, NormalizedOptionSurface types, OptionsChainRouter, ConvexityGate, option legs panel - Alert producers: vixLevel, rotation, thesis, unlock, portfolioRisk, mirror (fund_capture, fund_13f, mirror_diff) - FINRA short interest adapter + queue integration - SEC company tickers adapter + ingest (symbol search index seed) - Vendor gate (rate-limit-first data plane, ADR-0009) - CUSIP registry, reverse 13F refresh, stock float service - LRU cache, portfolio backtest engine - Frontend: dealer-flow, funds, journal, lab, monitor, plan, portfolio, reports, screener, strategies, theses, guided-start, exits, more pages - Volume profile, workspace profile, visibility-aware poll - ADRs 0010 (mirror math not advice), 0011 (symbol search index) - VENDOR_INTEGRATIONS.md, END_USER_TEST.md - .gitignore: exclude DBs, .DS_Store, local config, agent scratch
This commit is contained in:
@@ -163,7 +163,7 @@ export function sizePosition(
|
||||
}
|
||||
|
||||
const shares = Math.max(0, Math.floor(sharesAfterMacro));
|
||||
explanations.push(`The math implies ~${shares} shares given your stop of ${plan.stopPerShare} and ${(plan.riskFraction * 100).toFixed(1)}% risk. Educational analysis, not investment advice.`);
|
||||
explanations.push(`The math implies ~${shares} shares given your stop of ${plan.stopPerShare} and ${(plan.riskFraction * 100).toFixed(1)}% risk.`);
|
||||
|
||||
return {
|
||||
shares,
|
||||
|
||||
@@ -59,7 +59,7 @@ export function computeTierStats(db: DatabaseSync, userId: string): TierStats[]
|
||||
byTier[t].total += 1;
|
||||
// Profitability heuristic: a closed trade with a positive realized gain.
|
||||
// Falls back gracefully if no outcome column exists (counts total only).
|
||||
if (isProfit(db, userId, r as never)) byTier[t].profitable += 1;
|
||||
if (isProfit(r as { realized_pnl: number | null })) byTier[t].profitable += 1;
|
||||
}
|
||||
return (['A_STAR', 'A', 'B', 'C'] as const).map((tier) => {
|
||||
const s = byTier[tier] ?? { total: 0, profitable: 0 };
|
||||
@@ -67,15 +67,9 @@ export function computeTierStats(db: DatabaseSync, userId: string): TierStats[]
|
||||
});
|
||||
}
|
||||
|
||||
/** Deterministic profitability probe — returns false when the outcome column
|
||||
* is absent (no false positives; unlock stays conservative). */
|
||||
function isProfit(_db: DatabaseSync, _userId: string, _row: never): boolean {
|
||||
// Reserved: once a `realized_pnl`/`outcome` column is added to `trades`,
|
||||
// inspect it here. Today there is no such column, so we conservatively return
|
||||
// false — unlocking requires explicit operator/user evidence recorded in
|
||||
// `sizing_unlocks`. This keeps the gate fail-closed until the journal records
|
||||
// realized PnL (planned in the alerts/thesis slices).
|
||||
return false;
|
||||
/** Deterministic profitability probe — checks realized_pnl on the trade row. */
|
||||
function isProfit(row: { realized_pnl: number | null }): boolean {
|
||||
return (row.realized_pnl ?? 0) > 0;
|
||||
}
|
||||
|
||||
/** Has the user unlocked A_STAR? Reads `sizing_unlocks` (operator-evidenced). */
|
||||
|
||||
Reference in New Issue
Block a user