Spaces:
Running
Running
Deploy Aureon OS (deploy/selfhost stack: nginx edge + fusion API x2 + console + HNC organ + redis + postgres; paper mode) (part 3)
1ccf652 verified Download aureon/bots/orca_kill_executor.py from GaryLeckey/aureon-os: direct link, hf CLI and curl.
- Browser
- Download file 29.8 kB
-
https://huggingface.co/spaces/GaryLeckey/aureon-os/resolve/main/aureon/bots/orca_kill_executor.py
- Command line
-
hf download hf://spaces/GaryLeckey/aureon-os/aureon/bots/orca_kill_executor.py
-
curl -L -o orca_kill_executor.py https://huggingface.co/spaces/GaryLeckey/aureon-os/resolve/main/aureon/bots/orca_kill_executor.py
29.8 kB
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| π¦πͺ ORCA KILL EXECUTION - HUNT β KILL β PROFIT πͺπ¦ | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| "The Orca doesn't just find prey - it KILLS and FEEDS." | |
| This module handles the actual execution: | |
| 1. HUNT β Find the target (done by global scanner) | |
| 2. KILL β Execute the trade (BUY or SELL) | |
| 3. WATCH β Monitor for profit target | |
| 4. FEAST β Close position and realize profit | |
| EXCHANGES SUPPORTED: | |
| π KRAKEN: Full trading (TUSD/USD available) | |
| π¦ ALPACA: Full trading (USD available) | |
| Gary Leckey | Orca Kills Now | January 2026 | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| """ | |
| from aureon.core.aureon_baton_link import link_system as _baton_link; _baton_link(__name__) | |
| import sys | |
| import os | |
| import time | |
| import json | |
| import logging | |
| from dataclasses import dataclass, field, asdict | |
| from typing import Dict, List, Optional, Any, Tuple | |
| from datetime import datetime, timezone | |
| logger = logging.getLogger(__name__) | |
| # Position tracking file | |
| POSITION_FILE = "orca_active_positions.json" | |
| class OrcaPosition: | |
| """An active position held by the Orca.""" | |
| id: str | |
| symbol: str | |
| exchange: str | |
| side: str # 'long' or 'short' | |
| # Entry details | |
| entry_price: float | |
| entry_qty: float | |
| entry_cost: float # Total cost including fees | |
| entry_time: float | |
| entry_order_id: str | |
| # Target/Stop | |
| take_profit_pct: float = 5.0 # Default 5% profit target | |
| stop_loss_pct: float = -3.0 # Default -3% stop loss | |
| # Current state | |
| current_price: float = 0.0 | |
| unrealized_pnl: float = 0.0 | |
| unrealized_pnl_pct: float = 0.0 | |
| # Exit details (when closed) | |
| exit_price: float = 0.0 | |
| exit_qty: float = 0.0 | |
| exit_cost: float = 0.0 | |
| exit_time: float = 0.0 | |
| exit_order_id: str = "" | |
| exit_reason: str = "" | |
| # Final P&L | |
| realized_pnl: float = 0.0 | |
| status: str = "open" # 'open', 'closed', 'stopped' | |
| def update_pnl(self, current_price: float): | |
| """Update unrealized P&L.""" | |
| self.current_price = current_price | |
| if self.side == 'long': | |
| self.unrealized_pnl = (current_price - self.entry_price) * self.entry_qty | |
| self.unrealized_pnl_pct = ((current_price / self.entry_price) - 1) * 100 | |
| else: # short | |
| self.unrealized_pnl = (self.entry_price - current_price) * self.entry_qty | |
| self.unrealized_pnl_pct = ((self.entry_price / current_price) - 1) * 100 | |
| def should_take_profit(self) -> bool: | |
| """Check if we hit profit target.""" | |
| return self.unrealized_pnl_pct >= self.take_profit_pct | |
| def should_stop_loss(self) -> bool: | |
| """Check if we hit stop loss.""" | |
| return self.unrealized_pnl_pct <= self.stop_loss_pct | |
| def to_dict(self) -> Dict: | |
| return asdict(self) | |
| class OrcaKillExecutor: | |
| """ | |
| π¦πͺ THE ORCA KILL EXECUTOR | |
| Takes hunt results and executes actual trades: | |
| - BUY to open long positions | |
| - SELL to close positions | |
| - Monitors for profit/stop | |
| """ | |
| def __init__(self, dry_run: bool = False): | |
| self.dry_run = dry_run | |
| self.positions: Dict[str, OrcaPosition] = {} | |
| self.kraken = None | |
| self.alpaca = None | |
| self._init_exchanges() | |
| self._load_positions() | |
| def _init_exchanges(self): | |
| """Initialize exchange connections.""" | |
| # Kraken - ALWAYS get real balance, only use dry_run for orders | |
| try: | |
| from aureon.exchanges.kraken_client import get_kraken_client | |
| self.kraken = get_kraken_client() | |
| if self.kraken: | |
| # Store original dry_run state | |
| original_dry_run = getattr(self.kraken, 'dry_run', False) | |
| # Temporarily disable dry_run to get REAL balance | |
| self.kraken.dry_run = False | |
| balance = self.kraken.get_account_balance() | |
| # Restore dry_run for order execution | |
| self.kraken.dry_run = self.dry_run | |
| # Check multiple stablecoins | |
| tusd = float(balance.get('TUSD', 0)) | |
| usd = float(balance.get('USD', 0)) | |
| usdc = float(balance.get('USDC', 0)) | |
| usdt = float(balance.get('USDT', 0)) | |
| total_stable = tusd + usd + usdc + usdt | |
| self.kraken_balance = balance # Store full balance | |
| logger.info(f"π Kraken connected: ${tusd:.2f} TUSD, ${usd:.2f} USD, ${usdc:.2f} USDC, ${usdt:.2f} USDT") | |
| logger.info(f" Total stable: ${total_stable:.2f} (dry_run orders: {self.dry_run})") | |
| except Exception as e: | |
| logger.error(f"Kraken init error: {e}") | |
| self.kraken_balance = {} | |
| # Alpaca | |
| try: | |
| from aureon.exchanges.alpaca_client import AlpacaClient | |
| self.alpaca = AlpacaClient() | |
| acct = self.alpaca.get_account() | |
| cash = float(acct.get('cash', 0)) | |
| logger.info(f"π¦ Alpaca connected: ${cash:.2f} USD") | |
| except Exception as e: | |
| logger.error(f"Alpaca init error: {e}") | |
| def _load_positions(self): | |
| """Load active positions from file.""" | |
| try: | |
| if os.path.exists(POSITION_FILE): | |
| with open(POSITION_FILE, 'r') as f: | |
| data = json.load(f) | |
| for pos_id, pos_data in data.items(): | |
| self.positions[pos_id] = OrcaPosition(**pos_data) | |
| logger.info(f"π Loaded {len(self.positions)} active positions") | |
| except Exception as e: | |
| logger.error(f"Failed to load positions: {e}") | |
| def _save_positions(self): | |
| """Save active positions to file.""" | |
| try: | |
| data = {pos_id: pos.to_dict() for pos_id, pos in self.positions.items()} | |
| with open(POSITION_FILE, 'w') as f: | |
| json.dump(data, f, indent=2) | |
| except Exception as e: | |
| logger.error(f"Failed to save positions: {e}") | |
| def get_balance(self, exchange: str) -> Tuple[str, float]: | |
| """Get available balance on exchange.""" | |
| if exchange == 'kraken' and self.kraken: | |
| # Use cached balance if available, otherwise fetch fresh (with dry_run disabled) | |
| if hasattr(self, 'kraken_balance') and self.kraken_balance: | |
| balance = self.kraken_balance | |
| else: | |
| # Temporarily disable dry_run to get REAL balance | |
| original_dry_run = getattr(self.kraken, 'dry_run', False) | |
| self.kraken.dry_run = False | |
| balance = self.kraken.get_account_balance() | |
| self.kraken.dry_run = original_dry_run | |
| self.kraken_balance = balance | |
| # Check for TUSD (primary), then USD, then USDC, then USDT | |
| for asset in ['TUSD', 'USD', 'ZUSD', 'USDC', 'USDT']: | |
| amt = float(balance.get(asset, 0)) | |
| if amt > 0.5: # At least $0.50 | |
| return asset, amt | |
| return 'TUSD', 0.0 | |
| elif exchange == 'alpaca' and self.alpaca: | |
| acct = self.alpaca.get_account() | |
| return 'USD', float(acct.get('cash', 0)) | |
| return 'USD', 0.0 | |
| def get_price(self, symbol: str, exchange: str) -> float: | |
| """Get current price for symbol.""" | |
| try: | |
| if exchange == 'kraken' and self.kraken: | |
| # Normalize symbol (ME/USD -> MEUSD) | |
| kraken_sym = symbol.replace('/', '') | |
| price_info = self.kraken.best_price(kraken_sym) | |
| return float(price_info.get('price', 0)) | |
| elif exchange == 'alpaca' and self.alpaca: | |
| quote = self.alpaca.get_crypto_quote(symbol.replace('/', '')) | |
| return float(quote.get('ap', 0) or quote.get('ask', 0)) | |
| except Exception as e: | |
| logger.error(f"Price fetch error for {symbol}: {e}") | |
| return 0.0 | |
| def _normalize_symbol(self, symbol: str) -> str: | |
| """Normalize symbol formats into BASE/QUOTE convention.""" | |
| if not isinstance(symbol, str): | |
| return "" | |
| cleaned = symbol.strip().upper() | |
| if "/" in cleaned: | |
| return cleaned | |
| # Common fallback: BTCUSD -> BTC/USD | |
| if len(cleaned) > 3: | |
| if cleaned.endswith("USD"): | |
| return f"{cleaned[:-3]}/USD" | |
| if cleaned.endswith("USDT"): | |
| return f"{cleaned[:-4]}/USDT" | |
| if cleaned.endswith("USDC"): | |
| return f"{cleaned[:-4]}/USDC" | |
| return cleaned | |
| def validate_ticker(self, symbol: str, exchange: str) -> Dict[str, Any]: | |
| """Validate ticker syntax and market availability on the selected exchange.""" | |
| normalized = self._normalize_symbol(symbol) | |
| if "/" not in normalized: | |
| return { | |
| "valid": False, | |
| "symbol": normalized, | |
| "reason": "Ticker must be in BASE/QUOTE format (example: ETH/USD)", | |
| } | |
| price = self.get_price(normalized, exchange) | |
| if price <= 0: | |
| return { | |
| "valid": False, | |
| "symbol": normalized, | |
| "reason": f"Ticker unavailable or not priced on {exchange}", | |
| } | |
| return { | |
| "valid": True, | |
| "symbol": normalized, | |
| "exchange": exchange, | |
| "price": price, | |
| } | |
| def select_trade_candidate(self, tickers: List[str], exchange: str) -> Dict[str, Any]: | |
| """ | |
| Validate a list of tickers and select the highest-priced valid candidate. | |
| Selection policy is intentionally deterministic for auditability. | |
| """ | |
| if not tickers: | |
| return {"selected": None, "validations": [], "reason": "No tickers provided"} | |
| validations = [self.validate_ticker(ticker, exchange) for ticker in tickers] | |
| valid = [v for v in validations if v.get("valid")] | |
| if not valid: | |
| return {"selected": None, "validations": validations, "reason": "No valid tickers"} | |
| selected = sorted(valid, key=lambda item: item.get("price", 0.0), reverse=True)[0] | |
| return {"selected": selected, "validations": validations} | |
| def run_orca_kill_cycle( | |
| self, | |
| tickers: List[str], | |
| exchange: str, | |
| side: str = "buy", | |
| amount_usd: Optional[float] = None, | |
| take_profit_pct: float = 5.0, | |
| stop_loss_pct: float = -3.0, | |
| monitor_cycles: int = 30, | |
| poll_seconds: float = 1.0, | |
| ) -> Dict[str, Any]: | |
| """ | |
| Execute the complete Orca cycle: | |
| selection/validation -> trade -> monitor -> profitable close. | |
| """ | |
| selection = self.select_trade_candidate(tickers=tickers, exchange=exchange) | |
| selected = selection.get("selected") | |
| if not selected: | |
| return { | |
| "success": False, | |
| "phase": "selection", | |
| "reason": selection.get("reason", "No valid selection"), | |
| "selection": selection, | |
| } | |
| position = self.execute_kill( | |
| symbol=selected["symbol"], | |
| exchange=exchange, | |
| side=side, | |
| amount_usd=amount_usd, | |
| take_profit_pct=take_profit_pct, | |
| stop_loss_pct=stop_loss_pct, | |
| ) | |
| if not position: | |
| return { | |
| "success": False, | |
| "phase": "execution", | |
| "reason": "Failed to execute kill", | |
| "selection": selection, | |
| } | |
| closed_positions: List[OrcaPosition] = [] | |
| for _ in range(max(1, monitor_cycles)): | |
| closed_now = self.monitor_positions() | |
| if closed_now: | |
| closed_positions.extend(closed_now) | |
| break | |
| if poll_seconds > 0: | |
| time.sleep(poll_seconds) | |
| closed_position = next((p for p in closed_positions if p.id == position.id), None) | |
| if not closed_position: | |
| return { | |
| "success": False, | |
| "phase": "monitor", | |
| "reason": "Position did not close within monitoring window", | |
| "selection": selection, | |
| "position_id": position.id, | |
| "closed_positions": [p.id for p in closed_positions], | |
| } | |
| profitable = closed_position.realized_pnl > 0 | |
| return { | |
| "success": profitable, | |
| "phase": "closed", | |
| "selection": selection, | |
| "position_id": closed_position.id, | |
| "symbol": closed_position.symbol, | |
| "exit_reason": closed_position.exit_reason, | |
| "realized_pnl": closed_position.realized_pnl, | |
| "profitable_close": profitable, | |
| } | |
| def execute_kill(self, symbol: str, exchange: str, side: str, | |
| amount_usd: Optional[float] = None, | |
| take_profit_pct: float = 5.0, | |
| stop_loss_pct: float = -3.0) -> Optional[OrcaPosition]: | |
| """ | |
| πͺ EXECUTE THE KILL | |
| Args: | |
| symbol: Trading pair (e.g., "ME/USD") | |
| exchange: Exchange to trade on ('kraken' or 'alpaca') | |
| side: 'buy' for long, 'sell' for short | |
| amount_usd: Amount in USD to trade (default: 90% of balance) | |
| take_profit_pct: Profit target % | |
| stop_loss_pct: Stop loss % | |
| Returns: | |
| OrcaPosition if successful, None if failed | |
| """ | |
| print(f"\nπ¦πͺ ORCA KILL EXECUTION") | |
| print("=" * 60) | |
| print(f" Symbol: {symbol}") | |
| print(f" Exchange: {exchange}") | |
| print(f" Side: {side.upper()}") | |
| print(f" TP: +{take_profit_pct}%") | |
| print(f" SL: {stop_loss_pct}%") | |
| print(f" DRY-RUN: {self.dry_run}") | |
| print("=" * 60) | |
| # Get balance | |
| quote_asset, balance = self.get_balance(exchange) | |
| print(f"\nπ° Available: ${balance:.2f} {quote_asset}") | |
| if balance < 1.0: | |
| print(f"β Insufficient balance on {exchange}") | |
| return None | |
| # Calculate trade size (90% of balance or specified amount) | |
| trade_amount = amount_usd or (balance * 0.9) | |
| trade_amount = min(trade_amount, balance * 0.95) # Keep 5% buffer | |
| print(f"π Trade amount: ${trade_amount:.2f}") | |
| # Get current price | |
| price = self.get_price(symbol, exchange) | |
| if price <= 0: | |
| print(f"β Could not get price for {symbol}") | |
| return None | |
| print(f"π΅ Current price: ${price:.6f}") | |
| # Calculate quantity | |
| qty = trade_amount / price | |
| print(f"π¦ Quantity: {qty:.6f} {symbol.split('/')[0]}") | |
| # Execute order | |
| print(f"\nπͺ EXECUTING {side.upper()} ORDER...") | |
| order_result = None | |
| if exchange == 'kraken' and self.kraken: | |
| try: | |
| # Kraken needs the pair without slash | |
| kraken_pair = symbol.replace('/', '') | |
| # If we have TUSD, we need to trade METUSD pair or convert first | |
| if quote_asset == 'TUSD': | |
| # Check if direct TUSD pair exists | |
| tusd_pair = symbol.split('/')[0] + 'TUSD' | |
| try: | |
| self.kraken.best_price(tusd_pair) | |
| kraken_pair = tusd_pair | |
| print(f" Using TUSD pair: {kraken_pair}") | |
| except: | |
| # No TUSD pair, need to convert TUSD->USD first | |
| print(f" β οΈ No {tusd_pair} pair, using USD pair") | |
| order_result = self.kraken.place_market_order( | |
| symbol=kraken_pair, | |
| side=side, | |
| quote_qty=trade_amount | |
| ) | |
| except Exception as e: | |
| print(f"β Kraken order failed: {e}") | |
| return None | |
| elif exchange == 'alpaca' and self.alpaca: | |
| try: | |
| # Alpaca crypto trading | |
| order_result = self.alpaca.submit_order( | |
| symbol=symbol.replace('/', ''), | |
| qty=None, # Use notional | |
| side=side, | |
| type='market', | |
| time_in_force='gtc', | |
| notional=trade_amount | |
| ) | |
| except Exception as e: | |
| print(f"β Alpaca order failed: {e}") | |
| return None | |
| if not order_result: | |
| print(f"β Order execution failed") | |
| return None | |
| # Check for errors | |
| if 'error' in order_result: | |
| print(f"β Order error: {order_result}") | |
| return None | |
| # Parse order result | |
| order_id = order_result.get('orderId', order_result.get('id', str(time.time()))) | |
| exec_price = float( | |
| order_result.get('price') | |
| or order_result.get('avg_price') | |
| or order_result.get('avgPrice') | |
| or price | |
| ) | |
| exec_qty = float( | |
| order_result.get('executedQty') | |
| or order_result.get('vol_exec') | |
| or order_result.get('filled_qty') | |
| or qty | |
| ) | |
| exec_cost = float( | |
| order_result.get('cummulativeQuoteQty') | |
| or order_result.get('cost') | |
| or order_result.get('filled_notional') | |
| or (exec_price * exec_qty) | |
| ) | |
| print(f"\nβ ORDER FILLED!") | |
| print(f" Order ID: {order_id}") | |
| print(f" Price: ${exec_price:.6f}") | |
| print(f" Quantity: {exec_qty:.6f}") | |
| print(f" Cost: ${exec_cost:.2f}") | |
| # Create position | |
| pos_id = f"{exchange}_{symbol.replace('/', '')}_{int(time.time())}" | |
| position = OrcaPosition( | |
| id=pos_id, | |
| symbol=symbol, | |
| exchange=exchange, | |
| side='long' if side == 'buy' else 'short', | |
| entry_price=exec_price, | |
| entry_qty=exec_qty, | |
| entry_cost=exec_cost, | |
| entry_time=time.time(), | |
| entry_order_id=order_id, | |
| take_profit_pct=take_profit_pct, | |
| stop_loss_pct=stop_loss_pct, | |
| current_price=exec_price, | |
| status='open' | |
| ) | |
| # Save position | |
| self.positions[pos_id] = position | |
| self._save_positions() | |
| print(f"\nπ Position opened: {pos_id}") | |
| print(f" Target: +{take_profit_pct}% (${exec_price * (1 + take_profit_pct/100):.6f})") | |
| print(f" Stop: {stop_loss_pct}% (${exec_price * (1 + stop_loss_pct/100):.6f})") | |
| return position | |
| def close_position(self, position: OrcaPosition, reason: str = "manual") -> bool: | |
| """ | |
| Close an open position. | |
| """ | |
| if position.status != 'open': | |
| print(f"β οΈ Position {position.id} already {position.status}") | |
| return False | |
| print(f"\nπͺ CLOSING POSITION: {position.symbol}") | |
| print(f" Side: {position.side}") | |
| print(f" Entry: ${position.entry_price:.6f}") | |
| print(f" Current PnL: {position.unrealized_pnl_pct:+.2f}%") | |
| print(f" Reason: {reason}") | |
| # Determine close side | |
| close_side = 'sell' if position.side == 'long' else 'buy' | |
| # Execute close order | |
| order_result = None | |
| if position.exchange == 'kraken' and self.kraken: | |
| try: | |
| kraken_pair = position.symbol.replace('/', '') | |
| order_result = self.kraken.place_market_order( | |
| symbol=kraken_pair, | |
| side=close_side, | |
| quantity=position.entry_qty | |
| ) | |
| except Exception as e: | |
| print(f"β Close order failed: {e}") | |
| return False | |
| elif position.exchange == 'alpaca' and self.alpaca: | |
| try: | |
| order_result = self.alpaca.submit_order( | |
| symbol=position.symbol.replace('/', ''), | |
| qty=position.entry_qty, | |
| side=close_side, | |
| type='market', | |
| time_in_force='gtc' | |
| ) | |
| except Exception as e: | |
| print(f"β Close order failed: {e}") | |
| return False | |
| if not order_result or 'error' in order_result: | |
| print(f"β Close failed: {order_result}") | |
| return False | |
| # Update position with exit details | |
| exit_price = float( | |
| order_result.get('price') | |
| or order_result.get('avg_price') | |
| or order_result.get('avgPrice') | |
| or position.current_price | |
| ) | |
| exit_qty = float( | |
| order_result.get('executedQty') | |
| or order_result.get('vol_exec') | |
| or order_result.get('filled_qty') | |
| or position.entry_qty | |
| ) | |
| exit_cost = float( | |
| order_result.get('cummulativeQuoteQty') | |
| or order_result.get('cost') | |
| or order_result.get('filled_notional') | |
| or (exit_price * exit_qty) | |
| ) | |
| position.exit_price = exit_price | |
| position.exit_qty = exit_qty | |
| position.exit_cost = exit_cost | |
| position.exit_time = time.time() | |
| position.exit_order_id = order_result.get('orderId', '') | |
| position.exit_reason = reason | |
| # Calculate realized P&L | |
| if position.side == 'long': | |
| position.realized_pnl = exit_cost - position.entry_cost | |
| else: | |
| position.realized_pnl = position.entry_cost - exit_cost | |
| position.status = 'closed' | |
| self._save_positions() | |
| pnl_emoji = "π’" if position.realized_pnl > 0 else "π΄" | |
| print(f"\n{pnl_emoji} POSITION CLOSED!") | |
| print(f" Exit Price: ${exit_price:.6f}") | |
| print(f" Realized P&L: ${position.realized_pnl:.4f}") | |
| return True | |
| def monitor_positions(self) -> List[OrcaPosition]: | |
| """ | |
| Monitor all open positions and close if hit TP/SL. | |
| Returns list of positions that were closed. | |
| """ | |
| closed = [] | |
| for pos_id, position in list(self.positions.items()): | |
| if position.status != 'open': | |
| continue | |
| # Update current price | |
| price = self.get_price(position.symbol, position.exchange) | |
| if price <= 0: | |
| continue | |
| position.update_pnl(price) | |
| # Check take profit | |
| if position.should_take_profit(): | |
| print(f"\nπ― TAKE PROFIT HIT: {position.symbol} +{position.unrealized_pnl_pct:.2f}%") | |
| if self.close_position(position, reason="take_profit"): | |
| closed.append(position) | |
| continue | |
| # Check stop loss | |
| if position.should_stop_loss(): | |
| print(f"\nπ STOP LOSS HIT: {position.symbol} {position.unrealized_pnl_pct:.2f}%") | |
| if self.close_position(position, reason="stop_loss"): | |
| closed.append(position) | |
| continue | |
| # Print status | |
| pnl_emoji = "π’" if position.unrealized_pnl >= 0 else "π΄" | |
| print(f"{pnl_emoji} {position.symbol}: ${price:.6f} ({position.unrealized_pnl_pct:+.2f}%)") | |
| return closed | |
| def get_open_positions(self) -> List[OrcaPosition]: | |
| """Get all open positions.""" | |
| return [p for p in self.positions.values() if p.status == 'open'] | |
| def status(self): | |
| """Print current status.""" | |
| print("\n" + "=" * 60) | |
| print("π¦ ORCA KILL EXECUTOR STATUS") | |
| print("=" * 60) | |
| # Exchange balances | |
| kraken_asset, kraken_bal = self.get_balance('kraken') | |
| alpaca_asset, alpaca_bal = self.get_balance('alpaca') | |
| print(f"\nπ° BALANCES:") | |
| print(f" π Kraken: ${kraken_bal:.2f} {kraken_asset}") | |
| print(f" π¦ Alpaca: ${alpaca_bal:.2f} {alpaca_asset}") | |
| # Open positions | |
| open_pos = self.get_open_positions() | |
| print(f"\nπ OPEN POSITIONS: {len(open_pos)}") | |
| total_pnl = 0.0 | |
| for pos in open_pos: | |
| price = self.get_price(pos.symbol, pos.exchange) | |
| if price > 0: | |
| pos.update_pnl(price) | |
| pnl_emoji = "π’" if pos.unrealized_pnl >= 0 else "π΄" | |
| print(f" {pnl_emoji} {pos.symbol} ({pos.exchange})") | |
| print(f" Entry: ${pos.entry_price:.6f}") | |
| print(f" Current: ${pos.current_price:.6f}") | |
| print(f" P&L: {pos.unrealized_pnl_pct:+.2f}% (${pos.unrealized_pnl:+.4f})") | |
| total_pnl += pos.unrealized_pnl | |
| if open_pos: | |
| print(f"\n π΅ Total Unrealized: ${total_pnl:+.4f}") | |
| # Closed positions (recent) | |
| closed_pos = [p for p in self.positions.values() if p.status == 'closed'] | |
| if closed_pos: | |
| print(f"\nπ RECENT CLOSED: {len(closed_pos)}") | |
| for pos in closed_pos[-5:]: # Last 5 | |
| pnl_emoji = "π’" if pos.realized_pnl > 0 else "π΄" | |
| print(f" {pnl_emoji} {pos.symbol}: ${pos.realized_pnl:+.4f} ({pos.exit_reason})") | |
| print("=" * 60) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # π¦ QUICK KILL FUNCTIONS | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def orca_execute_kill(symbol: str, exchange: str, side: str, | |
| amount_usd: float = None, dry_run: bool = False): | |
| """πͺ Execute a kill (trade).""" | |
| executor = OrcaKillExecutor(dry_run=dry_run) | |
| return executor.execute_kill(symbol, exchange, side, amount_usd) | |
| def orca_hunt_and_kill(dry_run: bool = False): | |
| """π¦ Run full hunt cycle and execute best kill.""" | |
| from aureon.scanners.aureon_live_momentum_hunter import LiveMomentumHunter | |
| # Hunt | |
| hunter = LiveMomentumHunter(dry_run=dry_run) | |
| results = hunter.hunt() | |
| if not results: | |
| print("\nβ³ No kills found - Orca is patient") | |
| return None | |
| # Execute best kill | |
| best = results[0] | |
| executor = OrcaKillExecutor(dry_run=dry_run) | |
| # Determine exchange - check which one has the symbol | |
| # For now, check if it came from global scan (likely Kraken) | |
| exchange = 'alpaca' | |
| if best.nexus_factors.get('extreme_momentum'): | |
| # Came from global scanner, likely Kraken | |
| exchange = 'kraken' | |
| position = executor.execute_kill( | |
| symbol=best.symbol, | |
| exchange=exchange, | |
| side=best.side, | |
| take_profit_pct=5.0, | |
| stop_loss_pct=-3.0 | |
| ) | |
| return position | |
| def orca_monitor(): | |
| """π Monitor open positions.""" | |
| executor = OrcaKillExecutor(dry_run=False) # Always real for monitoring | |
| return executor.monitor_positions() | |
| def orca_status(): | |
| """π Show executor status.""" | |
| executor = OrcaKillExecutor(dry_run=False) | |
| executor.status() | |
| if __name__ == "__main__": | |
| import sys | |
| if len(sys.argv) > 1: | |
| cmd = sys.argv[1] | |
| if cmd == 'status': | |
| orca_status() | |
| elif cmd == 'monitor': | |
| orca_monitor() | |
| elif cmd == 'hunt': | |
| # Dry run hunt and kill | |
| orca_hunt_and_kill(dry_run=False) | |
| elif cmd == 'hunt-live': | |
| # LIVE hunt and kill | |
| print("β οΈ LIVE MODE - Real trades will be executed!") | |
| confirm = input("Type 'KILL' to confirm: ") | |
| if confirm == 'KILL': | |
| orca_hunt_and_kill(dry_run=False) | |
| else: | |
| print(f"Unknown command: {cmd}") | |
| print("Usage: python orca_kill_executor.py [status|monitor|hunt|hunt-live]") | |
| else: | |
| # Default: show status | |
| orca_status() | |