Almaatla commited on
Commit
77ac113
·
verified ·
1 Parent(s): 1d771a0

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +77 -19
index.html CHANGED
@@ -270,31 +270,89 @@
270
  }
271
  }
272
 
273
- function placeOrder(side, qty){
274
- qty = Math.floor(Number(qty));
275
- if (!Number.isFinite(qty) || qty <= 0) return;
276
- if (!Number.isFinite(state.price) || state.price <= 0) return;
277
-
278
- const cost = qty * state.price;
279
-
280
- if (side === "BUY") {
281
- if (state.cash < cost + COMMISSION) return;
282
- const totalVal = state.shares * state.avgCost + cost;
283
- state.shares += qty;
284
- state.avgCost = state.shares > 0 ? (totalVal / state.shares) : 0;
285
- state.cash -= (cost + COMMISSION);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  } else {
287
- if (state.shares < qty) return;
288
- state.shares -= qty;
289
- state.cash += (cost - COMMISSION);
290
- if (state.shares === 0) state.avgCost = 0;
291
  }
 
 
 
 
 
 
 
292
 
293
- state.orders.push({ side, qty, price: state.price, day: state.day, ts: Date.now() });
 
 
 
 
 
 
294
  recalcEquity();
295
- render();
 
296
  }
297
 
 
 
 
 
298
  function resetLocal(){
299
  state.cash = INITIAL_CASH;
300
  state.shares = 0;
 
270
  }
271
  }
272
 
273
+ function placeOrder(side, qty){
274
+ qty = Math.floor(Number(qty));
275
+ if (!Number.isFinite(qty) || qty <= 0) return;
276
+ if (!Number.isFinite(state.price) || state.price <= 0) return;
277
+
278
+ const tradeShares = (side === "BUY") ? qty : -qty; // SELL is negative shares
279
+ const px = state.price;
280
+
281
+ // Cash flow: buying spends cash, selling receives cash
282
+ // cashDelta = - (tradeShares * price) - commission
283
+ // (if tradeShares is negative => -(-qty*px) = +qty*px)
284
+ const cashDelta = -(tradeShares * px) - COMMISSION;
285
+
286
+ // Optional: simple leverage guard (to avoid infinite short)
287
+ // e.g. require equity stays above 0 after the trade
288
+ // We'll compute after updating state, and revert if violates.
289
+ const old = { cash: state.cash, shares: state.shares, avgCost: state.avgCost };
290
+
291
+ // Update cash
292
+ state.cash += cashDelta;
293
+
294
+ // Update position + avgCost (handles long<->flat<->short)
295
+ const prevShares = state.shares;
296
+ const newShares = prevShares + tradeShares;
297
+
298
+ // Helper: same direction means both >=0 or both <=0 (excluding 0)
299
+ const sameDir =
300
+ (prevShares > 0 && newShares > 0) ||
301
+ (prevShares < 0 && newShares < 0);
302
+
303
+ if (newShares === 0) {
304
+ state.shares = 0;
305
+ state.avgCost = 0;
306
+ } else if (prevShares === 0) {
307
+ // Opening a new position (long or short)
308
+ state.shares = newShares;
309
+ state.avgCost = px;
310
+ } else if (sameDir) {
311
+ // Increasing position in the same direction => weighted average price
312
+ // weights are absolute sizes
313
+ const totalAbs = Math.abs(prevShares) + Math.abs(tradeShares);
314
+ const avg = (Math.abs(prevShares) * state.avgCost + Math.abs(tradeShares) * px) / totalAbs;
315
+ state.shares = newShares;
316
+ state.avgCost = avg;
317
+ } else {
318
+ // Reducing/closing/reversing: avgCost stays the same if partially reduced;
319
+ // if reversed beyond zero, new avgCost becomes entry price of the remainder.
320
+ state.shares = newShares;
321
+
322
+ const reducedToZeroOrBeyond =
323
+ (prevShares > 0 && newShares < 0) || (prevShares < 0 && newShares > 0);
324
+
325
+ if (reducedToZeroOrBeyond) {
326
+ // Position flipped direction; remaining shares have new entry at px
327
+ state.avgCost = px;
328
  } else {
329
+ // Still same original direction but smaller size; keep avgCost
330
+ // (avgCost unchanged)
 
 
331
  }
332
+ }
333
+
334
+ // Record order
335
+ state.orders.push({ side, qty, price: px, day: state.day, ts: Date.now() });
336
+
337
+ // Recalc equity and (optional) enforce margin rule
338
+ recalcEquity();
339
 
340
+ // Simple margin guard (optional but strongly recommended):
341
+ // disallow trades that make equity negative
342
+ if (state.equity <= 0) {
343
+ // revert
344
+ state.cash = old.cash;
345
+ state.shares = old.shares;
346
+ state.avgCost = old.avgCost;
347
  recalcEquity();
348
+ state.orders.pop();
349
+ return;
350
  }
351
 
352
+ render();
353
+ }
354
+
355
+
356
  function resetLocal(){
357
  state.cash = INITIAL_CASH;
358
  state.shares = 0;