Skip to main content
Glama

ReadyTrader-Stocks

CI License: MIT

Important Disclaimer (Read Before Use)

ReadyTrader-Stocks is provided for informational and educational purposes only and does not constitute financial, investment, legal, or tax advice. Trading stocks and equities involves substantial risk and may result in partial or total loss of funds. Past performance is not indicative of future results. You are solely responsible for any decisions, trades, configurations, supervision, and the security of your credentials/API keys. ReadyTrader-Stocks is provided β€œAS IS”, without warranties of any kind, and we make no guarantees regarding profitability, performance, availability, or outcomes. By using ReadyTrader-Stocks, you acknowledge and accept these risks.

See also: DISCLAIMER.md.


Related MCP server: trading-mcp-server

🌎 The Big Picture

ReadyTrader-Stocks is a specialized bridge that turns your AI Agent (like Gemini or Claude) into a professional stock trading operator.

Think of it this way: Your AI agent provides the Intelligence (analyzing charts, earnings reports, and news sentiment), while ReadyTrader-Stocks provides the Hands (connecting to brokerages and data providers) and the Safety Brakes (enforcing your risk rules). It allows you to delegate complex trading tasks to an AI without giving it unchecked access to your capital.

πŸ›‘οΈ The Trust Model: Intelligence vs. Execution

The core philosophy of this project is a strict separation of powers:

  • The AI Agent (The Brain): Decides what and when to trade. It can research historical data, scan social media, and simulate strategies, but it has no direct power to move money.

  • The MCP Server (The Guardrail): Owns the API keys and enforces your safety policies. It filters every AI request through a "Risk Guardian" that rejects any trade that is too large, too risky, or violates your personal limits.

πŸ’° Funding Model (Non-Custodial)

ReadyTrader-Stocks operates on a User-Custodied basis. This means:

  • You keep your funds: Your capital remains in your own brokerage account (e.g., Alpaca, Tradier, Interactive Brokers).

  • You control the keys: You provide API keys that allow the agent to trade but (recommended) not withdraw.

  • Agent as Operator: The agent acts as a remote operator. It sends order instructions to your broker using your keys, and the broker handles actual execution and settlement.

Note: In Paper Mode (default), we simulate a virtual wallet with fake funds so you can practice without linking a real brokerage.

πŸ”„ A Day in the Life of a Trade

  1. Research: You ask your agent, "Find a good entry for AAPL." The agent calls get_stock_price, fetch_ohlcv, get_market_regime and get_social_sentiment.

  2. Proposal: The agent concludes, "AAPL is oversold; I want to buy 3 shares." It calls place_market_order.

  3. Governance: The Risk Guardian checks the order against your account: no more than 5% of the account per trade (valued at the latest market price, never at a price the order carries; selling out of a position is an exit and is never sized as new exposure), on the paper account nothing that adds exposure after a 5% daily loss or a 10% drawdown (a live brokerage account has no loss history here, so live orders list those two rules in inactive_rules), and no BUY into a collapse (docs/FALLING_KNIFE.md). Live orders also pass your MAX_ORDER_AMOUNT / ALLOW_TICKERS policy and need LIVE_TRADING_ENABLED=true.

  4. Consent: With EXECUTION_APPROVAL_MODE=approve_each, the order comes back as a pending proposal. You approve it through the API or the dashboard; the Risk Guardian checks it again with fresh prices, and only then does the trade execute.


πŸ–₯️ Next.js Dashboard

ReadyTrader-Stocks includes a small Next.js dashboard backed by the API server (app/api_server.py).

How to Enable:

  1. Start the API server from the repository root: python app/api_server.py (serves 127.0.0.1:8000; set API_HOST / API_PORT to change it).

  2. In another terminal: cd frontend && npm install && npm run dev

  3. Open http://localhost:3000. If the API runs elsewhere, set NEXT_PUBLIC_API_URL (and NEXT_PUBLIC_WS_URL) before starting the dashboard; if the dashboard is served from another address, add it to the API's API_CORS_ORIGINS.

What it shows:

  • Portfolio: the paper account's balances, equity, today's P&L and drawdown, from /api/portfolio (the live view is not implemented yet).

  • Mode: Paper Mode or LIVE TRADING, read from /api/health.

  • Guard Rail: pending approve_each proposals with the order each would place (symbol, side, shares, type, venue, paper or live); Approve and Reject ask for the proposal's confirm_token and call /api/approve-trade.

  • Live Markets: tickers pushed over the API's WebSocket (/ws). No tool starts a market-data stream in this release, so this panel stays empty.


πŸš€ Key Features

  • πŸ“‰ Paper Trading Simulator: a zero-risk practice account with persistent balances; market orders fill at the latest price and limit orders only when marketable.

  • 🧠 Strategy Research: a backtesting engine for agent-written strategies, synthetic black-swan stress tests and a market-regime detector.

  • πŸ“° News & Social Feeds: NewsAPI, Alpha Vantage and free RSS headlines, plus recent Reddit/X posts for the agent to judge. No invented sentiment scores (see docs/SENTIMENT.md).


⚑ 10-minute evaluation

Run both demos locally (no brokerage keys needed; Python 3.12+, dependencies installed as below):

python examples/paper_quick_demo.py
python examples/simulation_demo.py

You’ll get exportable artifacts under artifacts/demo_stress/ (gitignored).

Prompt pack (copy/paste): prompts/READYTRADER_PROMPT_PACK.md.

ReadyTrader-Stocks demo flow

πŸ› οΈ Installation & Setup

Prerequisites

  • Docker, or Python 3.12+ for a local install (below)

1. Build & Run (Standalone)

Run the server in a container. It exposes stdio for MCP clients.

cd ReadyTrader-Stocks
docker build -t readytrader-stocks .
# Run interactively (to test); the named volume keeps the paper ledger between runs
docker run --rm -i -v readytrader-stocks-data:/app/data readytrader-stocks

Local development (no Docker)

If you want to run or test ReadyTrader-Stocks locally. Requires Python 3.12 or newer (pandas_ta has no release for older versions).

python3.12 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
python app/main.py   # MCP server on stdio; an MCP client launches it the same way

2. Configuration (.env)

Create a .env file or pass environment variables. Start from env.example (copy to .env).

Variable

Default

Description

PAPER_MODE

true

false (or 0, no, off) for live trading; any other value stays on paper.

LIVE_TRADING_ENABLED

false

Must be exactly true for any live execution.

TRADING_HALTED

false

Kill switch: any value other than empty, false, 0, no or off refuses every live order. Read at start-up, so restart after changing it.

EXECUTION_APPROVAL_MODE

auto

auto executes immediately; approve_each (or any value other than auto) makes every order a proposal a human approves.

API_PORT

8000

Port for the FastAPI/WebSocket server (python app/api_server.py).

API_CORS_ORIGINS

http://localhost:3000,http://127.0.0.1:3000

Browser origins allowed to call the API; set it if the dashboard runs elsewhere.

API_OPERATOR_TOKEN

unset

Operator secret for the API server only: when set, every /api/ call but /api/health needs Authorization: Bearer <it>; live proposals can be approved only when it is set.

EXECUTION_DB_PATH, EXECUTION_SESSION_ID

unset

Give both processes the same values so the API can approve the MCP server's proposals.

MAX_ORDER_AMOUNT

unset

Largest live order (shares) the policy allows. A value that is not a number refuses every live order (invalid_policy_config).

ALLOW_TICKERS, ALLOW_BROKERAGES

unset (all)

Comma-separated allowlists for live orders, checked when an order is proposed and again when it executes.

DISCORD_WEBHOOK_URL

""

Optional webhook for trade approval notifications.

MARKET_GUARD_ENABLED

true

Price-based Falling Knife check on every BUY (trade check and order). See docs/FALLING_KNIFE.md.

MARKET_GUARD_ON_DATA_ERROR

unset

What a BUY does when the daily bars cannot be read: block or allow. Unset blocks in live mode and allows (flagged) in paper mode.

Variable

Description

ALPACA_API_KEY

API Key for Alpaca brokerage.

ALPACA_API_SECRET

API Secret for Alpaca brokerage.

ALPACA_PAPER

true (default) sends live-mode Alpaca orders to your Alpaca paper account; false to trade the real account.

TRADIER_ACCESS_TOKEN

Access Token for Tradier.

Variable

Default

Description

TICKER_CACHE_TTL_SEC

5

How long to cache price data.

OHLCV_CACHE_TTL_SEC

60

How long to cache daily bars (the Falling Knife check reads them).

Variable

Default

Description

LOG_LEVEL

INFO

Log level for the JSON logs the API server writes.

PAPER_DB_PATH

data/paper.db

The paper ledger (SQLite).

RISK_PROFILE, EXECUTION_MODE and RATE_LIMIT_DEFAULT_PER_MIN are read but not applied yet: the Risk Guardian's limits are fixed (5% per trade, 5% daily loss, 10% drawdown) and no rate limit is enforced.

Every variable the server reads is listed, with its default, in env.example.


Brokerage credentials

To place live orders or fetch balances, configure brokerage credentials via env.

  • ALPACA_API_KEY=...

  • ALPACA_API_SECRET=...

  • TRADIER_ACCESS_TOKEN=...

Live orders go out only with PAPER_MODE=false and LIVE_TRADING_ENABLED=true; TRADING_HALTED=true refuses them all, closing orders included (flatten at the brokerage while halted). Each is sized against the brokerage account's equity. Alpaca orders fill now or not at all: they are sent only while the market is open (else market_closed), as IOC orders (filled now, a limit at its limit or better, the rest cancelled; a fractional market order goes out DAY, a fractional limit is refused), so none waits at the broker past the Risk Guardian's checks and the kill switch; the answer reports what filled. Alpaca orders go to your Alpaca paper account until you also set ALPACA_PAPER=false (Tradier likewise stays in its sandbox until TRADIER_SANDBOX=false), so you can test the whole live path without real money. Capabilities per brokerage: docs/EXCHANGES.md.

Tools:

  • place_stock_order(symbol, side, amount, price=0.0, order_type='market', exchange='alpaca', rationale='') (exchange: alpaca, tradier, ibkr, schwab, etrade, robinhood)

  • reset_paper_wallet() - Reset all simulated data

  • deposit_paper_funds(asset, amount) - Add virtual cash

βœ… Approving trades (approve_each)

With EXECUTION_APPROVAL_MODE=approve_each, every order that passes the Risk Guardian comes back as {"status": "pending_approval", "request_id", "confirm_token"} instead of executing. To approve it through the API (or the dashboard), run the MCP server and python app/api_server.py with the same EXECUTION_DB_PATH and EXECUTION_SESSION_ID; then:

  • GET /api/pending-approvals lists the proposals with their orders, never their tokens (they expire after 120 s).

  • POST /api/approve-trade {"request_id", "confirm_token", "approve": true} re-runs the Risk Guardian with fresh prices and executes; "approve": false cancels. A refusal answers 409 with the reason; an unknown proposal 404; a wrong token 403. A proposal executes only in the mode it was made in: a paper proposal approved by an API running live is refused (mode_mismatch).

  • The confirm_token goes to the agent with the proposal, so on its own it does not prove that a person approved. Set API_OPERATOR_TOKEN for the API server (never for the MCP server): every /api/ call except /api/health then needs Authorization: Bearer <it> (the dashboard asks for it once per tab), and a live proposal is approved only when it is set (operator_token_required).


πŸ”Œ Integration Guide

With the Agent Zero plugin: install a0-readytrader-stocks-plugin (2.0.0 or later) from Agent Zero's Plugins page (Git URL or ZIP). It installs this server into the plugin's folder, registers it with Agent Zero's MCP client in paper mode, and adds a paper-trading skill.

By hand: in Agent Zero, open Settings β†’ MCP/A2A β†’ External MCP Servers and add the server to the JSON there. Copy/paste file: configs/agent_zero.mcp.json.

{
  "mcpServers": {
    "readytrader_stocks": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "readytrader-stocks-data:/app/data",
        "-e",
        "PAPER_MODE=true",
        "readytrader-stocks"
      ]
    }
  }
}
  • The agent sees the tools as readytrader_stocks.<tool> (Agent Zero lowercases the server name and turns other characters into _). Saving the settings reloads Agent Zero's MCP servers.

  • Agent Zero starts the server afresh for every call, so the -v volume is what keeps the paper account between calls. Agent Zero must be able to run docker where it runs.

  • Without Docker: set "command" to the Python 3.12 interpreter of a ReadyTrader-Stocks checkout with its requirements installed (e.g. /path/to/ReadyTrader-Stocks/.venv/bin/python) and "args" to ["/path/to/ReadyTrader-Stocks/app/main.py"], paths Agent Zero can reach. Agent Zero passes the server only a minimal environment, so put settings in the entry's "env" (for example {"PAPER_MODE": "true"}) or in the checkout's .env.

Option B: Generic MCP Client (Claude Desktop, etc.)

Add this to your mcp-server-config.json:

Quick copy/paste file: configs/claude_desktop.mcp-server-config.json.

{
  "mcpServers": {
    "readytrader_stocks": {
      "command": "docker",
      "args": [
        "run", 
        "-i", 
        "--rm",
        "-v", "readytrader-stocks-data:/app/data",
        "-e", "PAPER_MODE=true",
        "readytrader-stocks"
      ]
    }
  }
}

Prebuilt config: configs/claude_desktop.mcp-server-config.json.


πŸ“š Feature Guide

1. Strategy Backtesting

Example Prompt:

"Create a mean-reversion strategy for AAPL. Write a Python function on_candle that uses RSI. Backtest it on daily bars and tell me the PnL and the trades."

What happens:

  1. Agent calls fetch_ohlcv("AAPL") to see data structure.

  2. Agent writes code for on_candle(close, rsi, state) returning 'buy', 'sell' or 'hold'.

  3. Agent calls run_backtest_simulation(code, "AAPL", "1d"): the last 500 bars, from $10,000.

  4. The server runs the code with dangerous imports (such as os) refused and returns {"pnl_percent": 11.91, "total_trades": 2, "trades_log": [...], ...}; a strategy that fails returns backtest_error.

2. Paper Trading Laboratory (Zero-Key Flow)

Perfect for "interning" your agent without any paid API keys.

  • Fund your account: deposit_paper_funds("USD", 100000)

  • Researching Stocks: Use fetch_ohlcv and get_stock_price (powered by public yfinance data).

  • Read the News: fetch_rss_news (free MarketWatch/Yahoo Finance headlines, optionally filtered by ticker).

  • Place Orders: place_market_order("AAPL", "buy", 10) fills at the latest price; a limit order fills only if it is marketable (resting orders are not simulated).

  • Reset Everything: reset_paper_wallet()

3. Market Regime & Risk

The agent can query the "weather" before flying.

  • Tool: get_market_regime("AAPL")

  • Output: {"regime": "VOLATILE_RANGING", "direction": "SIDEWAYS", "adx": 19.45, "atr_pct": 2.12, "summary": "..."}

  • Agent Logic: "The market is Trending Up (ADX > 25). I will switch to my Trend-Following Strategy and disable Mean-Reversion."

The Guardian (Passive Safety): You don't need to do anything. If the agent tries to bet 50% of the portfolio on a whim, validate_trade_risk will BLOCK the trade automatically.

It also refuses a BUY into a collapse: a stock down 15%+ from its highest close of the last four sessions and still at its lowest close. The rule, the data it reads and the evidence behind the threshold (tested on 64 stocks it had never seen) are in docs/FALLING_KNIFE.md.


🧰 Tool Reference

For the complete (generated) tool catalog with signatures and docstrings, see: docs/TOOLS.md.

Category

Tool

Description

Market Data

get_stock_price

Latest price (yfinance).

get_multiple_prices

Latest prices for several tickers.

fetch_ohlcv

Historical candles for research.

Intelligence

get_market_sentiment

CNN Fear & Greed (market-wide); source_unavailable when CNN refuses.

get_social_sentiment

Recent X/Reddit posts for you to judge (no score).

get_financial_news

NewsAPI headlines (NEWSAPI_KEY).

get_market_news

Alpha Vantage headlines (ALPHAVANTAGE_API_KEY).

fetch_rss_news

Free MarketWatch/Yahoo Finance headlines.

Trading

place_market_order

Market order through the Risk Guardian.

place_limit_order

Limit order (paper: fills only if marketable).

place_stock_order

Either, with a brokerage choice for live orders.

validate_trade_risk

Check a trade without placing it.

Account

deposit_paper_funds

Add virtual cash (Paper Mode).

reset_paper_wallet

Clear the paper account.

Research

run_backtest_simulation

Run Strategy Backtest.

run_synthetic_stress_test

Run synthetic black-swan stress test with deterministic replay + recommendations.

get_market_regime

Trend/Chop Detection.

post_market_insight, get_latest_insights

Share signals between agents.


Built for the Agentic Future.

πŸ§ͺ Synthetic Stress Testing

This MCP includes a 100% randomized (but deterministic-by-seed) synthetic market simulator. It can generate trending, ranging, and volatile regimes and inject black swan crashes and parabolic blow-off tops.

Tool: run_synthetic_stress_test(strategy_code, config_json='{}')

Returns JSON containing:

  • metrics summary across scenarios

  • replay seeds (master + per-scenario)

  • artifacts: CSV scenario metrics, plus worst-case equity curve CSV + trades JSON

  • recommendations: suggested parameter changes (and applies to PARAMS keys if present)

Example config_json:

{
  "master_seed": 123,
  "scenarios": 200,
  "length": 500,
  "timeframe": "1h",
  "initial_capital": 10000,
  "start_price": 100,
  "base_vol": 0.01,
  "black_swan_prob": 0.02,
  "parabolic_prob": 0.02
}

πŸ“Œ Project docs

  • README.md: Project overview and configuration

  • docs/TOOLS.md: complete tool catalog (generated from app/tools)

  • docs/ERRORS.md: common error codes and operator troubleshooting

  • docs/EXCHANGES.md: brokerage capability matrix (what is wired, what is not)

  • docs/MARKETDATA.md: where market data comes from

  • docs/THREAT_MODEL.md: operator-focused threat model (live trading)

  • docs/FALLING_KNIFE.md: the price-based Falling Knife rule, and the study behind the thresholds

  • docs/SENTIMENT.md: why this server does not score sentiment, and how to supply your own reading

  • docs/CUSTODY.md: key custody + rotation guidance

  • docs/POSITIONING.md: credibility-safe marketing + messaging

  • CHANGELOG.md: version-to-version change summary

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers