feat: strategy builder
This commit is contained in:
26
frontend/src/lib/format.ts
Normal file
26
frontend/src/lib/format.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Shared price/rate formatter. Raw quotes (spot, strike, bid/ask) always show a
|
||||
* meaningful number of decimals — 4 for FX-scale instruments (<10), 2 above that
|
||||
* (equities/indices), matching standard quoting convention for each magnitude.
|
||||
* NOT for post-nominal dollar amounts (P&L, entry cost) — those stay at 2 decimals
|
||||
* via each page's own fmtMoney.
|
||||
*/
|
||||
export function fmtPrice(v: number | null | undefined, decimals?: number): string {
|
||||
if (v == null || Number.isNaN(v)) return '—'
|
||||
const d = decimals ?? (Math.abs(v) < 10 ? 4 : 2)
|
||||
return v.toFixed(d)
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a backend UTC timestamp as a compact local "as of" label, e.g. "18/07 14:32".
|
||||
* Backend timestamps come in two shapes, both naive UTC: Python's `datetime.isoformat()`
|
||||
* ("2026-07-18T14:32:01.123") and sqlite's `datetime('now')` ("2026-07-18 14:32:01").
|
||||
*/
|
||||
export function fmtAsOf(raw: string | null | undefined): string | null {
|
||||
if (!raw) return null
|
||||
let iso = raw.includes('T') ? raw : raw.replace(' ', 'T')
|
||||
if (!/[zZ]|[+-]\d{2}:?\d{2}$/.test(iso)) iso += 'Z'
|
||||
const d = new Date(iso)
|
||||
if (Number.isNaN(d.getTime())) return null
|
||||
return d.toLocaleString('fr-FR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })
|
||||
}
|
||||
Reference in New Issue
Block a user