Daniel Alnawaz commited on
Commit
d5ebc41
Β·
unverified Β·
1 Parent(s): 9f363ea

Capital tracking

Browse files
Files changed (1) hide show
  1. autonomous_bot.py +38 -5
autonomous_bot.py CHANGED
@@ -497,17 +497,42 @@ class AutonomousTradingBot:
497
  if paper_mode:
498
  logger.info("πŸ“‹ PAPER TRADE MODE β€” no real orders will be placed.")
499
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  def get_equity_for(slot: StrategySlot) -> float:
501
  if paper_mode:
502
- return max_cap * slot.capital_frac
 
503
  try:
504
  state = self.api.get_user_state(user_addr)
505
  ms = state.get("crossMarginSummary") or state.get("marginSummary") or {}
506
  real = float(ms.get("accountValue", 0.0))
507
- return min(real, max_cap * slot.capital_frac)
 
 
508
  except Exception as e:
509
  logger.error(f"equity fetch error: {e}")
510
- return 0.0
511
 
512
  def get_position(coin: str) -> float:
513
  if paper_mode:
@@ -602,6 +627,12 @@ class AutonomousTradingBot:
602
  )
603
  pnl_usdc = (px - entry_px) * trade_sz * side if trade_sz > 0 else None
604
 
 
 
 
 
 
 
605
  self.tg.send_exit(slot.coin, exit_reason, pnl_usdc=pnl_usdc,
606
  strategy=slot.strategy_name, timeframe=slot.timeframe)
607
  slot.open_trade = None
@@ -827,11 +858,13 @@ class AutonomousTradingBot:
827
  subscribe_all()
828
 
829
  slot_summary = ", ".join(f"{s.coin}/{s.timeframe}({s.strategy_name})" for s in self.slots)
 
830
  self.tg.send_info(
831
  f"πŸ€– *Bot started* β€” account `{user_addr}`\n"
832
  f"Slots: `{slot_summary}`\n"
833
- f"Capital: ${max_cap:.2f} | Leverage: {leverage}x | "
834
- f"{'πŸ“‹ PAPER' if paper_mode else 'πŸ’° LIVE'}"
 
835
  )
836
 
837
  logger.info(f"Running {len(self.slots)} slot(s): " +
 
497
  if paper_mode:
498
  logger.info("πŸ“‹ PAPER TRADE MODE β€” no real orders will be placed.")
499
 
500
+ # ── Compounding capital tracker ───────────────────────────────
501
+ # Tracks each slot's running capital in memory.
502
+ # - Paper mode: starts at max_cap * capital_frac, updated after every
503
+ # closed trade so profits/losses compound into position sizing.
504
+ # - Live mode: reads real on-chain equity (already compounds naturally),
505
+ # scaled by this slot's fraction of total capital. No hard ceiling so
506
+ # gains are not lost.
507
+ _running_capital: Dict[str, float] = {
508
+ slot.label: max_cap * slot.capital_frac for slot in self.slots
509
+ }
510
+
511
+ def _update_running_capital(slot: StrategySlot, pnl: float):
512
+ """Apply a closed-trade PnL to the slot's running capital."""
513
+ old = _running_capital[slot.label]
514
+ _running_capital[slot.label] = max(old + pnl, 1.0) # floor at $1 to avoid sizing to 0
515
+ new = _running_capital[slot.label]
516
+ change = "πŸ“ˆ" if pnl >= 0 else "πŸ“‰"
517
+ logger.info(
518
+ f"{slot.label} {change} capital updated: "
519
+ f"${old:.2f} β†’ ${new:.2f} (PnL {pnl:+.4f} USDC)"
520
+ )
521
+
522
  def get_equity_for(slot: StrategySlot) -> float:
523
  if paper_mode:
524
+ # Paper: use compounding in-memory capital
525
+ return _running_capital[slot.label]
526
  try:
527
  state = self.api.get_user_state(user_addr)
528
  ms = state.get("crossMarginSummary") or state.get("marginSummary") or {}
529
  real = float(ms.get("accountValue", 0.0))
530
+ # Scale total equity by this slot's capital fraction.
531
+ # No hard ceiling β€” profits compound naturally.
532
+ return real * slot.capital_frac
533
  except Exception as e:
534
  logger.error(f"equity fetch error: {e}")
535
+ return _running_capital[slot.label] # fall back to last known value
536
 
537
  def get_position(coin: str) -> float:
538
  if paper_mode:
 
627
  )
628
  pnl_usdc = (px - entry_px) * trade_sz * side if trade_sz > 0 else None
629
 
630
+ # ── Compound capital ──────────────────────────────
631
+ # Update slot's running capital so next position is
632
+ # sized from the new (grown or shrunk) equity.
633
+ if pnl_usdc is not None:
634
+ _update_running_capital(slot, pnl_usdc)
635
+
636
  self.tg.send_exit(slot.coin, exit_reason, pnl_usdc=pnl_usdc,
637
  strategy=slot.strategy_name, timeframe=slot.timeframe)
638
  slot.open_trade = None
 
858
  subscribe_all()
859
 
860
  slot_summary = ", ".join(f"{s.coin}/{s.timeframe}({s.strategy_name})" for s in self.slots)
861
+ capital_summary = " | ".join(f"{s.label}=${_running_capital[s.label]:.2f}" for s in self.slots)
862
  self.tg.send_info(
863
  f"πŸ€– *Bot started* β€” account `{user_addr}`\n"
864
  f"Slots: `{slot_summary}`\n"
865
+ f"Capital: ${max_cap:.2f} total | Leverage: {leverage}x | "
866
+ f"{'πŸ“‹ PAPER' if paper_mode else 'πŸ’° LIVE'}\n"
867
+ f"Per-slot: `{capital_summary}`"
868
  )
869
 
870
  logger.info(f"Running {len(self.slots)} slot(s): " +