{"ok":true,"phase":"v14.0 Phase 160","service":"Trading Builder Actual File Content Generator","artifact":{"department":"trading","artifactType":"actual_file_content_bundle","safetyMode":"paper_trading_only","liveTradingEnabled":false,"fileCount":17,"files":[{"path":"main.py","content":"from agents.market_data_agent import MarketDataAgent\nfrom agents.analysis_agent import AnalysisAgent\nfrom agents.risk_agent import RiskAgent\nfrom agents.execution_agent import ExecutionAgent\nfrom agents.portfolio_agent import PortfolioAgent\nfrom agents.learning_agent import LearningAgent\nfrom models import TradeSignal\n\n\nPAPER_TRADING_MODE = True\nLIVE_TRADING_ENABLED = False\n\n\ndef safety_boot_check():\n    if not PAPER_TRADING_MODE:\n        raise RuntimeError(\"Safety lock: paper trading mode must stay enabled by default.\")\n    if LIVE_TRADING_ENABLED:\n        raise RuntimeError(\"Safety lock: live trading is disabled in this starter repository.\")\n    print(\"SAITS v1.0 safety check passed: paper trading only.\")\n\n\ndef main():\n    safety_boot_check()\n\n    market_data = MarketDataAgent()\n    analysis = AnalysisAgent()\n    risk = RiskAgent()\n    execution = ExecutionAgent(paper_trading=True)\n    portfolio = PortfolioAgent()\n    learning = LearningAgent()\n\n    symbols = [\"SPY\", \"QQQ\", \"AAPL\", \"BTC-USD\", \"ETH-USD\", \"SOL-USD\"]\n    market_snapshot = market_data.get_snapshot(symbols)\n\n    signals = analysis.generate_signals(market_snapshot)\n\n    for signal in signals:\n        decision = risk.evaluate(signal=signal, account_equity=portfolio.equity)\n        if decision.approved:\n            order = execution.place_order(signal, decision.position_size)\n            portfolio.record_order(order, decision)\n        else:\n            portfolio.record_rejection(signal, decision)\n\n    learning.review_day(portfolio.trade_log)\n    portfolio.print_summary()\n\n\nif __name__ == \"__main__\":\n    main()\n"},{"path":"config.yaml","content":"system:\n  name: \"Sovereign Autonomous AI Trading System\"\n  version: \"1.0\"\n  mode: \"paper\"\n  live_trading_enabled: false\n\nmarkets:\n  stocks:\n    enabled: true\n    symbols: [\"SPY\", \"QQQ\", \"AAPL\", \"MSFT\", \"NVDA\"]\n  crypto:\n    enabled: true\n    symbols: [\"BTC-USD\", \"ETH-USD\", \"SOL-USD\"]\n\nrisk:\n  max_risk_per_trade_percent: 2\n  daily_loss_limit_percent: 5\n  max_drawdown_percent: 12\n  allow_broker_withdrawal_permissions: false\n\nindicators:\n  rsi_period: 14\n  ema_fast: 9\n  ema_medium: 21\n  ema_slow: 50\n  ema_trend: 200\n  macd_fast: 12\n  macd_slow: 26\n  macd_signal: 9\n  bollinger_period: 20\n\nbrokers:\n  alpaca:\n    mode: \"paper\"\n    api_key_env: \"ALPACA_PAPER_API_KEY\"\n    api_secret_env: \"ALPACA_PAPER_API_SECRET\"\n  coinbase:\n    mode: \"paper\"\n    api_key_env: \"COINBASE_PAPER_API_KEY\"\n    api_secret_env: \"COINBASE_PAPER_API_SECRET\"\n  binance:\n    mode: \"testnet\"\n    api_key_env: \"BINANCE_TESTNET_API_KEY\"\n    api_secret_env: \"BINANCE_TESTNET_API_SECRET\"\n"},{"path":"models.py","content":"from dataclasses import dataclass\nfrom typing import Dict, Optional\n\n\n@dataclass\nclass TradeSignal:\n    symbol: str\n    direction: str\n    entry_price: float\n    stop_loss: float\n    take_profit: float\n    confidence: float\n    rationale: str\n\n\n@dataclass\nclass RiskDecision:\n    approved: bool\n    reason: str\n    position_size: float\n    max_loss_amount: float\n\n\n@dataclass\nclass PaperOrder:\n    symbol: str\n    direction: str\n    quantity: float\n    entry_price: float\n    stop_loss: float\n    take_profit: float\n    status: str\n    rationale: str\n\n\n@dataclass\nclass Position:\n    symbol: str\n    quantity: float\n    entry_price: float\n    current_price: float\n    unrealized_pnl: float\n"},{"path":"agents/market_data_agent.py","content":"class MarketDataAgent:\n    def get_snapshot(self, symbols):\n        # Starter placeholder: replace with Alpaca, Polygon, Coinbase, Binance, or other providers.\n        snapshot = {}\n        for symbol in symbols:\n            snapshot[symbol] = {\n                \"price\": 100.0 if \"USD\" not in symbol else 50000.0,\n                \"volume\": 1000000,\n                \"sentiment_score\": 0.55,\n                \"rsi\": 48,\n                \"ema_9\": 101,\n                \"ema_21\": 100,\n                \"ema_50\": 98,\n                \"ema_200\": 95,\n                \"macd\": 1.2,\n                \"macd_signal\": 0.9,\n            }\n        return snapshot\n"},{"path":"agents/analysis_agent.py","content":"from models import TradeSignal\n\n\nclass AnalysisAgent:\n    def generate_signals(self, market_snapshot):\n        signals = []\n\n        for symbol, data in market_snapshot.items():\n            bullish = (\n                data[\"ema_9\"] > data[\"ema_21\"]\n                and data[\"macd\"] > data[\"macd_signal\"]\n                and data[\"rsi\"] < 70\n                and data[\"sentiment_score\"] >= 0.5\n            )\n\n            if bullish:\n                entry = float(data[\"price\"])\n                stop = entry * 0.98\n                target = entry * 1.04\n                signals.append(\n                    TradeSignal(\n                        symbol=symbol,\n                        direction=\"long\",\n                        entry_price=entry,\n                        stop_loss=stop,\n                        take_profit=target,\n                        confidence=0.62,\n                        rationale=\"EMA 9/21 bullish, MACD confirmation, RSI not overbought, sentiment acceptable.\",\n                    )\n                )\n\n        return signals\n"},{"path":"agents/risk_agent.py","content":"from models import RiskDecision\n\n\nclass RiskAgent:\n    def __init__(self):\n        self.max_risk_per_trade_percent = 2\n        self.daily_loss_limit_percent = 5\n        self.max_drawdown_percent = 12\n\n    def evaluate(self, signal, account_equity):\n        risk_amount = account_equity * (self.max_risk_per_trade_percent / 100)\n        price_risk = abs(signal.entry_price - signal.stop_loss)\n\n        if price_risk <= 0:\n            return RiskDecision(False, \"Invalid stop loss distance.\", 0, 0)\n\n        position_size = risk_amount / price_risk\n\n        if signal.confidence < 0.55:\n            return RiskDecision(False, \"Signal confidence below minimum threshold.\", 0, risk_amount)\n\n        return RiskDecision(\n            approved=True,\n            reason=\"Approved: within max risk per trade and confidence threshold.\",\n            position_size=round(position_size, 6),\n            max_loss_amount=round(risk_amount, 2),\n        )\n"},{"path":"agents/execution_agent.py","content":"from models import PaperOrder\n\n\nclass ExecutionAgent:\n    def __init__(self, paper_trading=True):\n        self.paper_trading = paper_trading\n        self.live_trading_enabled = False\n\n    def place_order(self, signal, quantity):\n        if not self.paper_trading or self.live_trading_enabled:\n            raise RuntimeError(\"Live trading is disabled. This starter only supports paper orders.\")\n\n        return PaperOrder(\n            symbol=signal.symbol,\n            direction=signal.direction,\n            quantity=quantity,\n            entry_price=signal.entry_price,\n            stop_loss=signal.stop_loss,\n            take_profit=signal.take_profit,\n            status=\"paper_filled\",\n            rationale=signal.rationale,\n        )\n"},{"path":"agents/portfolio_agent.py","content":"class PortfolioAgent:\n    def __init__(self):\n        self.equity = 100000.0\n        self.trade_log = []\n        self.rejections = []\n\n    def record_order(self, order, decision):\n        self.trade_log.append({\"order\": order, \"risk\": decision})\n        print(f\"Paper order recorded: {order.symbol} {order.direction} qty={order.quantity}\")\n\n    def record_rejection(self, signal, decision):\n        self.rejections.append({\"signal\": signal, \"risk\": decision})\n        print(f\"Signal rejected: {signal.symbol} reason={decision.reason}\")\n\n    def print_summary(self):\n        print(\"Portfolio Summary\")\n        print(f\"Equity: {self.equity}\")\n        print(f\"Paper trades: {len(self.trade_log)}\")\n        print(f\"Rejected signals: {len(self.rejections)}\")\n"},{"path":"agents/learning_agent.py","content":"class LearningAgent:\n    def review_day(self, trade_log):\n        print(\"Learning Agent nightly review placeholder\")\n        print(f\"Trades reviewed: {len(trade_log)}\")\n        print(\"Suggestion: collect more paper trading data before adjusting risk.\")\n"},{"path":"backtest_engine.py","content":"def run_backtest():\n    # Starter placeholder. Replace with historical OHLCV loading and chronological simulation.\n    return {\n        \"period\": \"2 years\",\n        \"mode\": \"paper_simulation\",\n        \"win_rate\": 0.0,\n        \"profit_factor\": 0.0,\n        \"sharpe_ratio\": 0.0,\n        \"max_drawdown\": 0.0,\n        \"note\": \"Backtest engine scaffold created. Add historical data provider before trusting metrics.\",\n    }\n\n\nif __name__ == \"__main__\":\n    print(run_backtest())\n"},{"path":"dashboard.py","content":"import streamlit as st\n\n\nst.set_page_config(page_title=\"SAITS v1.0 Dashboard\", layout=\"wide\")\n\nst.title(\"Sovereign Autonomous AI Trading System\")\nst.caption(\"Paper trading only. Live trading is disabled by default.\")\n\ncol1, col2, col3 = st.columns(3)\ncol1.metric(\"Mode\", \"Paper\")\ncol2.metric(\"Max Risk / Trade\", \"2%\")\ncol3.metric(\"Live Trading\", \"Disabled\")\n\nst.subheader(\"Open Positions\")\nst.info(\"No live positions. Connect paper execution logs to populate this table.\")\n\nst.subheader(\"Explainability\")\nst.write(\"Every signal, risk decision, and paper order should include a rationale.\")\n"},{"path":"requirements.txt","content":"pandas>=2.0.0\nnumpy>=1.24.0\nstreamlit>=1.30.0\npyyaml>=6.0.0\npytest>=7.0.0\n"},{"path":"Dockerfile","content":"FROM python:3.11-slim\n\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\n\nCMD [\"python\", \"main.py\"]\n"},{"path":"docker-compose.yml","content":"services:\n  saits:\n    build: .\n    environment:\n      PAPER_TRADING_MODE: \"true\"\n      LIVE_TRADING_ENABLED: \"false\"\n    command: python main.py\n\n  dashboard:\n    build: .\n    ports:\n      - \"8501:8501\"\n    command: streamlit run dashboard.py --server.address=0.0.0.0\n"},{"path":"tests/test_risk_agent.py","content":"from agents.risk_agent import RiskAgent\nfrom models import TradeSignal\n\n\ndef test_risk_agent_approves_valid_signal():\n    risk = RiskAgent()\n    signal = TradeSignal(\"SPY\", \"long\", 100, 98, 104, 0.7, \"test\")\n    decision = risk.evaluate(signal, 100000)\n    assert decision.approved is True\n    assert decision.position_size > 0\n\n\ndef test_risk_agent_rejects_invalid_stop():\n    risk = RiskAgent()\n    signal = TradeSignal(\"SPY\", \"long\", 100, 100, 104, 0.7, \"test\")\n    decision = risk.evaluate(signal, 100000)\n    assert decision.approved is False\n"},{"path":"tests/test_signal_flow.py","content":"from agents.market_data_agent import MarketDataAgent\nfrom agents.analysis_agent import AnalysisAgent\n\n\ndef test_signal_flow_generates_list():\n    data = MarketDataAgent().get_snapshot([\"SPY\"])\n    signals = AnalysisAgent().generate_signals(data)\n    assert isinstance(signals, list)\n"},{"path":"README.md","content":"# SAITS v1.0 — Sovereign Autonomous AI Trading System\n\nGenerated by OmegaCrownAI Trading Builder.\n\nThis repository is a **paper-trading starter system**. It is designed to help you test architecture, agent flow, risk controls, dashboard layout, and backtesting scaffolding before any real broker connection.\n\n## Critical Safety Notice\n\nThis starter is **paper-trading only**.\n\nLive trading is disabled by default.\n\nThis is educational software scaffolding, not financial advice, not a guarantee of profit, and not a complete live trading system.\n\nDo **not** add real broker keys or connect live brokerage accounts until all of these are complete:\n\n1. Code review\n2. Paper-trading test period\n3. Backtest review\n4. Risk review\n5. Security review\n6. Manual live-trading approval\n\nBroker API keys should never include withdrawal permissions.\n\n## Default Risk Rules\n\n- Max risk per trade: 2%\n- Daily loss limit: 5%\n- Max drawdown limit: 12%\n- Broker withdrawal permissions: blocked\n- Paper trading mode: enabled\n- Live trading mode: disabled\n\n## Included Files\n\n```text\nmain.py\nconfig.yaml\nmodels.py\nbacktest_engine.py\ndashboard.py\nrequirements.txt\nDockerfile\ndocker-compose.yml\nagents/market_data_agent.py\nagents/analysis_agent.py\nagents/risk_agent.py\nagents/execution_agent.py\nagents/portfolio_agent.py\nagents/learning_agent.py\ntests/test_risk_agent.py\ntests/test_signal_flow.py\nREADME.md\n```\n\n## What Each Major File Does\n\n| File | Purpose |\n| --- | --- |\n| main.py | Starts the paper-trading agent flow and runs the safety boot check. |\n| config.yaml | Stores market, broker, indicator, and risk settings. |\n| models.py | Defines TradeSignal, RiskDecision, PaperOrder, and Position models. |\n| agents/market_data_agent.py | Provides starter market data snapshots. Replace with paper data providers later. |\n| agents/analysis_agent.py | Generates starter signals using EMA, MACD, RSI, and sentiment placeholders. |\n| agents/risk_agent.py | Enforces max risk per trade and vetoes invalid trades. |\n| agents/execution_agent.py | Places paper orders only and blocks live trading. |\n| agents/portfolio_agent.py | Tracks paper orders, rejections, and account summary. |\n| agents/learning_agent.py | Reviews paper trades and suggests future improvements. |\n| backtest_engine.py | Scaffold for historical strategy simulation. |\n| dashboard.py | Streamlit dashboard starter. |\n| tests/ | Starter validation tests for risk and signal flow. |\n\n## Local Setup\n\nUnzip the bundle:\n\n```bash\nunzip saits-v1.zip\ncd saits-v1\n```\n\nCreate and activate a Python environment:\n\n```bash\npython -m venv .venv\nsource .venv/bin/activate\n```\n\nInstall dependencies:\n\n```bash\npip install -r requirements.txt\n```\n\n## Run the Paper-Trading Starter\n\n```bash\npython main.py\n```\n\nExpected behavior:\n\n- Safety boot check passes.\n- Agents initialize.\n- Paper signals are generated.\n- Risk agent approves or rejects signals.\n- Execution agent records paper orders only.\n- Portfolio summary prints to the terminal.\n\n## Run the Dashboard\n\n```bash\nstreamlit run dashboard.py\n```\n\nDashboard includes starter panels for:\n\n- Mode\n- Max risk per trade\n- Live trading status\n- Open positions placeholder\n- Explainability placeholder\n\n## Run Tests\n\n```bash\npytest\n```\n\nExpected starter tests:\n\n- Risk agent approves valid signal.\n- Risk agent rejects invalid stop loss.\n- Signal flow returns a list.\n\n## Docker Run\n\n```bash\ndocker compose up --build\n```\n\nThis starts:\n\n- SAITS paper-trading process\n- Streamlit dashboard on port 8501\n\n## Paper Trading Roadmap\n\n1. Replace placeholder market data with paper/sandbox data providers.\n2. Add historical OHLCV loader.\n3. Expand the backtest engine.\n4. Add paper broker adapters.\n5. Add persistent trade logging.\n6. Run 2–4 weeks of paper trading.\n7. Review all rejected and approved trades.\n8. Improve risk logic and signal quality.\n9. Only then consider live-readiness review.\n\n## Live Trading Warning\n\nDo not turn this into live trading by simply adding real API keys.\n\nBefore live mode:\n\n- Add proper secret management.\n- Use paper keys first.\n- Confirm withdrawal permissions are disabled.\n- Add broker sandbox tests.\n- Add order size caps.\n- Add kill switch.\n- Add manual approval gate.\n- Review compliance, risk, and logs.\n- Start with very small capital only after extended paper testing.\n\n## Support Notes\n\nThis generated repository is a starting point. It is intentionally conservative and incomplete for live execution. The safest next step is to keep improving paper-mode testing, backtesting, monitoring, and risk validation.\n"}],"warning":"Generated starter code is for paper trading only. It is educational scaffolding, not financial advice and not live trading software."}}