Round leg prices to 2 decimals everywhere
Entry price, mark and strike are now rounded to 2dp on add, on edit, on market reload, and on load (self-heals legacy entries) — fixes display of float artifacts like "15.000000001". Also persist the leg's locked/currentMark fields in the store. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,12 @@
|
||||
const VERSION = 1;
|
||||
const MULTIPLIER = 100; // standard equity option contract size
|
||||
|
||||
/** Round a price to 2 decimals (kills float artifacts like 15.000000001). */
|
||||
function round2(v) {
|
||||
const n = Number(v);
|
||||
return Number.isFinite(n) ? Math.round(n * 100) / 100 : 0;
|
||||
}
|
||||
|
||||
function empty() {
|
||||
return { v: VERSION, symbol: "", spotSnapshot: 0, updatedAt: null, legs: [] };
|
||||
}
|
||||
@@ -31,10 +37,15 @@
|
||||
if (!raw) return empty();
|
||||
const obj = JSON.parse(raw);
|
||||
if (!obj || obj.v !== VERSION || !Array.isArray(obj.legs)) return empty();
|
||||
// sanitize: drop legs with no usable strike / type
|
||||
obj.legs = obj.legs.filter(
|
||||
(l) => l && Number.isFinite(Number(l.strike)) && (l.type === "call" || l.type === "put")
|
||||
);
|
||||
// sanitize: drop legs with no usable strike / type; round prices to 2dp (self-heal)
|
||||
obj.legs = obj.legs
|
||||
.filter((l) => l && Number.isFinite(Number(l.strike)) && (l.type === "call" || l.type === "put"))
|
||||
.map((l) => ({
|
||||
...l,
|
||||
strike: round2(l.strike),
|
||||
entryPrice: round2(l.entryPrice),
|
||||
currentMark: (typeof l.currentMark === "number" ? round2(l.currentMark) : (l.currentMark ?? null)),
|
||||
}));
|
||||
return obj;
|
||||
} catch {
|
||||
return empty();
|
||||
@@ -84,11 +95,13 @@
|
||||
symbol: leg.symbol || state.symbol,
|
||||
expiry: leg.expiry,
|
||||
type: leg.type,
|
||||
strike: strike,
|
||||
strike: round2(strike),
|
||||
side: leg.side === "short" ? "short" : "long",
|
||||
qty: Math.max(1, Math.round(Number(leg.qty) || 1)),
|
||||
entryPrice: Number(leg.entryPrice) || 0,
|
||||
entryPrice: round2(leg.entryPrice),
|
||||
iv: Number(leg.iv) || 0,
|
||||
locked: leg.locked === true,
|
||||
currentMark: (typeof leg.currentMark === "number" ? round2(leg.currentMark) : null),
|
||||
});
|
||||
save(state);
|
||||
return { state, replacedSymbol };
|
||||
@@ -105,7 +118,13 @@
|
||||
function updateLeg(id, patch) {
|
||||
const state = load();
|
||||
const leg = state.legs.find((l) => l.id === id);
|
||||
if (leg) Object.assign(leg, patch);
|
||||
if (leg) {
|
||||
const p = { ...patch };
|
||||
if ("entryPrice" in p) p.entryPrice = round2(p.entryPrice);
|
||||
if ("currentMark" in p && p.currentMark != null) p.currentMark = round2(p.currentMark);
|
||||
if ("strike" in p) p.strike = round2(p.strike);
|
||||
Object.assign(leg, p);
|
||||
}
|
||||
save(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user