Full sync - all projects, memory, configs
This commit is contained in:
@ -154,13 +154,44 @@ def check_buy_signals(game_id, username, candidates=None):
|
||||
if result["success"]:
|
||||
log_entry = log_decision("BUY", ticker, reason, result)
|
||||
buys.append(log_entry)
|
||||
print(f" BUY {ticker}: {shares} shares @ ${price:.2f} = ${shares * price:,.2f}")
|
||||
sector = c.get("sector", "Unknown")
|
||||
print(f" BUY {ticker} ({sector}): {shares} shares @ ${price:.2f} = ${shares * price:,.2f}")
|
||||
else:
|
||||
log_decision("SKIP", ticker, f"Buy failed: {result.get('error', 'unknown')}")
|
||||
# Log the specific reason for failure (sector cap, cash reserve, etc.)
|
||||
error = result.get('error', 'unknown')
|
||||
log_decision("SKIP", ticker, f"Buy failed: {error}")
|
||||
if "sector" in error.lower() or "cash reserve" in error.lower():
|
||||
print(f" SKIP {ticker}: {error}")
|
||||
|
||||
return buys
|
||||
|
||||
|
||||
def check_rebalance(game_id, username):
|
||||
"""Check if rebalancing is needed and optionally execute."""
|
||||
rebalance_result = game_engine.rebalance_portfolio(game_id, username, dry_run=True)
|
||||
|
||||
if rebalance_result["violations"]:
|
||||
print("\n Portfolio violations detected:")
|
||||
for violation in rebalance_result["violations"]:
|
||||
print(f" - {violation}")
|
||||
|
||||
if rebalance_result["actions"]:
|
||||
print(f" Recommended rebalance actions:")
|
||||
for action in rebalance_result["actions"]:
|
||||
print(f" - {action['action']} {action['shares']} {action['ticker']} @ ${action['price']:.2f} ({action['reason']})")
|
||||
|
||||
# Auto-execute rebalancing for serious violations
|
||||
total_excess_pct = (rebalance_result["total_excess"] / game_engine.get_portfolio(game_id, username)["total_value"]) * 100
|
||||
if total_excess_pct > 5.0: # Auto-rebalance if excess > 5% of portfolio
|
||||
print(f" Auto-executing rebalance (excess: {total_excess_pct:.1f}% of portfolio)...")
|
||||
exec_result = game_engine.rebalance_portfolio(game_id, username, dry_run=False)
|
||||
return exec_result
|
||||
else:
|
||||
print(" No rebalancing needed")
|
||||
|
||||
return rebalance_result
|
||||
|
||||
|
||||
def run_trading_logic(game_id, username, candidates=None):
|
||||
"""Run full trading cycle for a player."""
|
||||
print(f"\n--- Trading Logic [{username}@{game_id}] ---")
|
||||
@ -170,6 +201,9 @@ def run_trading_logic(game_id, username, candidates=None):
|
||||
for ticker, price in updated:
|
||||
print(f" {ticker}: ${price:.2f}")
|
||||
|
||||
print("\nChecking portfolio balance...")
|
||||
rebalance_result = check_rebalance(game_id, username)
|
||||
|
||||
print("\nChecking sell signals...")
|
||||
sells = check_sell_signals(game_id, username)
|
||||
if not sells:
|
||||
@ -180,7 +214,21 @@ def run_trading_logic(game_id, username, candidates=None):
|
||||
if not buys:
|
||||
print(" No buy signals")
|
||||
|
||||
return {"sells": sells, "buys": buys, "price_updates": len(updated)}
|
||||
# Show current portfolio summary
|
||||
p = game_engine.get_portfolio(game_id, username)
|
||||
if p:
|
||||
sectors = game_engine.get_sector_allocation(game_id, username)
|
||||
cash_pct = (p["cash"] / p["total_value"]) * 100
|
||||
print(f"\nPortfolio Summary:")
|
||||
print(f" Total Value: ${p['total_value']:,.2f}")
|
||||
print(f" Cash: ${p['cash']:,.2f} ({cash_pct:.1f}%)")
|
||||
print(f" Positions: {p['num_positions']}")
|
||||
if sectors:
|
||||
print(f" Sector Allocation:")
|
||||
for sector, pct in sorted(sectors.items(), key=lambda x: x[1], reverse=True):
|
||||
print(f" {sector}: {pct:.1f}%")
|
||||
|
||||
return {"sells": sells, "buys": buys, "price_updates": len(updated), "rebalance": rebalance_result}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user