Ray Dalio Idea Meritocracy AI Trading Team

Growth, inflation, and debt agents feed a disagreement agent and a trader, then the trade order

This AI team is inspired by Ray Dalio’s public writing about “idea meritocracy”: smart people with different views argue openly, and the best idea wins. Three agents each look at the economy through a different lens, a fourth agent makes them argue, and a trader builds a diversified ETF portfolio from the winning ideas. It is not a copy of Bridgewater’s All Weather portfolio.

How it works

  1. Growth agent asks what wins if the economy speeds up or slows down.

  2. Inflation agent asks what wins or loses if inflation and interest rates surprise.

  3. Debt and liquidity agent argues from debt, money supply, currency, and central bank policy.

  4. Disagreement agent challenges all three and names the strongest idea.

  5. Trading agent builds a diversified macro ETF portfolio and is the only agent allowed to place orders. The team repeats this once a day.

The copyable example now uses GPT-6 Luna with high reasoning, matching the Luna challenge version. A leveraged version holds leveraged ETFs instead. Earlier BotSpot paper observations used Gemini; changing the model does not change those historical results.

Run it on BotSpot

Run this team on BotSpot without installing anything. BotSpot runs LumiBot in the cloud, backtests it, and connects it to your broker.

Backtest tear sheet

GPT-6 Luna, January 5 to 16, 2026, Yahoo daily prices, $100,000 start. The team built a macro mix of SPY, EEM, GLD, IEF, and SHV and ended at $101,483 (+1%), about even with SPY. Cash never went below $262. Earlier BotSpot paper observations used Gemini and are separate from these Luna backtest results and the current Luna example.

Backtest tear sheet for the Ray Dalio Idea Meritocracy AI Trading Team

Open the full tear sheet. A short backtest shows the team works as written. It is not a promise of future returns.

The code

Regular ETFs:

"""Ray Dalio / Bridgewater-inspired idea-meritocracy AI trading team example.

Regular ETF data-on variant. Uses LumiBot's default built-in tools, including
FRED/ALFRED macro tools when FRED_API_KEY is supplied, Alpaca News when
ALPACA_NEWS_API_KEY / ALPACA_NEWS_API_SECRET are supplied, SEC tools, market
state, account state, and order tools. No custom public CSV FRED helper is used.
"""

from lumibot.credentials import IS_BACKTESTING
from lumibot.entities import Asset, TradingFee
from lumibot.strategies.strategy import Strategy
from lumibot.traders import Trader


ORDER_READINESS_RULE = (
    "Immediately before every buy or sell order, call account_portfolio, "
    "account_positions, and market_last_price for the exact ordered symbol in "
    "this same agent run, then call orders_submit_order. LumiBot rejects blind "
    "orders with ORDER_READINESS_REQUIRED when those readiness calls are missing."
)

DATA_USAGE_RULE = (
    "Use official LumiBot built-in tools for evidence: FRED/ALFRED macro tools "
    "for rates, inflation, liquidity, growth, and credit; Alpaca News for "
    "recent market and ETF-proxy headlines; SEC tools only when sector or "
    "company fundamentals are relevant. Keep tool use bounded: at most one FRED "
    "snapshot or short series request and one Alpaca News call per agent run; set "
    "Alpaca News limit <= 5; do not paginate or repeatedly re-check the same evidence. "
    "Do not rely on a custom public CSV FRED helper."
)


class AITradingTeamRayDalioIdeaMeritocracyStrategy(Strategy):
    parameters = {
        "universe": [
            "SPY", "QQQ", "IWM", "TLT", "IEF", "TIP", "GLD", "DBC",
            "VNQ", "UUP", "FXI", "EEM", "SHV",
        ],
        "min_positions": 3,
    }

    def initialize(self):
        self.sleeptime = "1D"
        self.agents.create(
            name="growth_agent",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Argue which ETFs win if growth improves. Inspect price/market tools, "
                "FRED growth/liquidity/rates context, and relevant Alpaca News before answering. "
                "Be direct and expose weak assumptions. " + DATA_USAGE_RULE
            ),
        )
        self.agents.create(
            name="inflation_agent",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Argue which ETFs win or lose if inflation and rates surprise. Inspect FRED CPI, "
                "inflation expectations, Treasury/rate data, and relevant Alpaca News before answering. "
                "Be direct. " + DATA_USAGE_RULE
            ),
        )
        self.agents.create(
            name="debt_liquidity_agent",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Argue from debt, liquidity, currency, and policy pressure. Inspect FRED liquidity, "
                "credit, dollar, and rate context plus relevant Alpaca News before answering. "
                "Be direct. " + DATA_USAGE_RULE
            ),
        )
        self.agents.create(
            name="thoughtful_disagreement",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Challenge all views with thoughtful disagreement. Identify the best diversified "
                "basket after stress testing. Check whether the upstream agents actually used "
                "FRED and Alpaca News evidence. Do not re-call tools unless upstream evidence is entirely absent; "
                "if you must, make only one short FRED call and one Alpaca News call with limit <= 5."
            ),
        )
        self.agents.create(
            name="trader",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=True,
            system_prompt=(
                "Build a Ray Dalio-style idea-meritocracy macro ETF basket, not a one-ETF bet. "
                "Hold at least three positions when risk is on; SHV or cash-like exposure may count "
                "as one position when evidence is weak. Reconcile and justify any override of the "
                "specialists or disagreement agent. Use variable weights and diversify across growth, "
                "duration, inflation/commodities, international/currency, and defensive sleeves when supported. "
                + DATA_USAGE_RULE + " " + ORDER_READINESS_RULE
            ),
        )

    def on_trading_iteration(self):
        context = {
            "date": self.get_datetime().date().isoformat(),
            "universe": self.parameters["universe"],
            "min_positions": self.parameters["min_positions"],
            "data_expectation": "Use official FRED tools and Alpaca News commonly; smoke tests will inspect agent_detail for actual tool calls.",
            "data_tool_validation_run_id": "2026-07-08-fresh-alpaca-news-fred-smoke-v1",
        }
        growth = self.agents["growth_agent"].run(
            task_prompt="Use FRED growth/liquidity/rate context and Alpaca News, then rank the strongest regular ETFs from a growth-regime view.",
            context=context,
        )
        inflation = self.agents["inflation_agent"].run(
            task_prompt="Use FRED inflation/rate context and Alpaca News, then rank the strongest regular ETFs from an inflation-and-rates view.",
            context=context,
        )
        liquidity = self.agents["debt_liquidity_agent"].run(
            task_prompt="Use FRED debt/liquidity/currency context and Alpaca News, then rank the strongest regular ETFs from a debt-and-liquidity view.",
            context=context,
        )
        disagreement = self.agents["thoughtful_disagreement"].run(
            task_prompt="Challenge the growth, inflation, and liquidity views. Prefer a diversified basket of at least three ETFs unless risk evidence argues for SHV/cash-like ballast.",
            context={**context, "growth": growth.summary, "inflation": inflation.summary, "liquidity": liquidity.summary},
        )
        self.agents["trader"].run(
            task_prompt=(
                "Rebalance into a diversified basket of at least three regular ETFs, using SHV/cash-like exposure only as ballast or a risk break. "
                "Before each order, call account_portfolio, account_positions, and market_last_price for the exact ordered symbol in this same run. "
                "Explain which specialist advice you accepted or rejected and cite FRED/Alpaca evidence used."
            ),
            context={**context, "growth": growth.summary, "inflation": inflation.summary, "liquidity": liquidity.summary, "disagreement": disagreement.summary},
        )


if __name__ == "__main__":
    quote_asset = Asset("USD", Asset.AssetType.FOREX)
    params = AITradingTeamRayDalioIdeaMeritocracyStrategy.parameters

    if IS_BACKTESTING:
        trading_fee = TradingFee(percent_fee=0.001)
        AITradingTeamRayDalioIdeaMeritocracyStrategy.backtest(
            datasource_class=None,
            benchmark_asset=Asset("SPY", Asset.AssetType.STOCK),
            buy_trading_fees=[trading_fee],
            sell_trading_fees=[trading_fee],
            quote_asset=quote_asset,
            parameters=params,
        )
    else:
        trader = Trader()
        strategy = AITradingTeamRayDalioIdeaMeritocracyStrategy(
            quote_asset=quote_asset,
            parameters=params,
        )
        trader.add_strategy(strategy)
        trader.run_all()

Leveraged ETFs:

"""Ray Dalio / Bridgewater-inspired idea-meritocracy AI trading team example.

Leveraged ETF data-on variant. Uses LumiBot's default built-in tools, including
FRED/ALFRED macro tools when FRED_API_KEY is supplied, Alpaca News when
ALPACA_NEWS_API_KEY / ALPACA_NEWS_API_SECRET are supplied, SEC tools, market
state, account state, and order tools. The trade universe is 2x/3x leveraged
ETFs plus SHV/cash as a rare escape hatch.
"""

from lumibot.credentials import IS_BACKTESTING
from lumibot.entities import Asset, TradingFee
from lumibot.strategies.strategy import Strategy
from lumibot.traders import Trader


ORDER_READINESS_RULE = (
    "Immediately before every buy or sell order, call account_portfolio, "
    "account_positions, and market_last_price for the exact ordered symbol in "
    "this same agent run, then call orders_submit_order. LumiBot rejects blind "
    "orders with ORDER_READINESS_REQUIRED when those readiness calls are missing."
)

DATA_USAGE_RULE = (
    "Use official LumiBot built-in tools by their real names: get_fred_snapshot, "
    "get_fred_latest, get_fred_series, and list_fred_series for macro evidence; "
    "alpaca_news for recent market, sector, rates, and ETF-proxy headlines; SEC "
    "tools only when sector or company fundamentals are relevant. Keep tool use bounded: "
    "at most one FRED snapshot or short series request and one Alpaca News call per agent run; "
    "set Alpaca News limit <= 5; do not paginate or repeatedly re-check the same evidence. "
    "Do not rely on a custom public CSV FRED helper."
)

LEVERAGE_RULE = (
    "This is a leveraged ETF strategy. Use only symbols from the leveraged "
    "universe plus SHV/cash-like exposure. Stay biased toward diversified 3x "
    "exposure when evidence supports risk-taking; use 2x as a risk-down choice; "
    "use inverse leveraged ETFs only with explicit downside or hedge evidence. "
    "Hold at least three positions in normal conditions, and do not make a single "
    "all-in bet. SHV/cash may count as one position when the model refuses every "
    "reasonable leveraged setup."
)


class AITradingTeamRayDalioIdeaMeritocracyStrategy(Strategy):
    parameters = {
        "universe": [
            "TQQQ", "QLD", "SQQQ", "QID", "UPRO", "SSO", "SPXU", "SDS",
            "UDOW", "DDM", "SDOW", "DXD", "TNA", "UWM", "TZA", "TWM",
            "FNGU", "FNGD", "TECL", "TECS", "SOXL", "SOXS", "FAS", "FAZ",
            "CURE", "RXD", "LABU", "LABD", "ERX", "ERY", "GUSH", "DRIP",
            "TMF", "UBT", "TBT", "TTT", "UGL", "GLL", "AGQ", "ZSL",
            "UCO", "SCO", "NUGT", "DUST", "YINN", "YANG", "EDC", "EDZ",
            "EURL", "EUO", "YCS", "DRN", "SRS", "SHV",
        ],
        "min_positions": 3,
    }

    def initialize(self):
        self.sleeptime = "1D"
        self.agents.create(
            name="growth_agent",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Argue which leveraged ETFs win if growth improves. First call get_fred_snapshot "
                "or get_fred_latest for growth, liquidity, rates, and credit context, then call "
                "alpaca_news for broad market and ETF-proxy headlines. Use exact symbols from the "
                "universe only. " + DATA_USAGE_RULE + " " + LEVERAGE_RULE
            ),
        )
        self.agents.create(
            name="inflation_agent",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Argue which leveraged ETFs win or lose if inflation and rates surprise. First call "
                "get_fred_snapshot or get_fred_latest for CPI, inflation expectations, Treasury yields, "
                "and policy-rate context, then call alpaca_news for rates, commodities, and market headlines. "
                "Use exact symbols from the universe only. " + DATA_USAGE_RULE + " " + LEVERAGE_RULE
            ),
        )
        self.agents.create(
            name="debt_liquidity_agent",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Argue from debt, liquidity, currency, credit, and policy pressure. First call FRED tools "
                "such as get_fred_snapshot/get_fred_latest, then call alpaca_news for market stress and ETF-proxy headlines. "
                "Use exact symbols from the universe only. " + DATA_USAGE_RULE + " " + LEVERAGE_RULE
            ),
        )
        self.agents.create(
            name="thoughtful_disagreement",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=False,
            system_prompt=(
                "Challenge all views with thoughtful disagreement. Identify the best diversified leveraged basket after stress testing. "
                "Check whether upstream agents actually used get_fred_snapshot/get_fred_latest and alpaca_news. Do not re-call tools unless upstream evidence is entirely absent; if you must, make only one short FRED call and one Alpaca News call with limit <= 5. "
                + DATA_USAGE_RULE + " " + LEVERAGE_RULE
            ),
        )
        self.agents.create(
            name="trader",
            model="openai/gpt-6-luna",
            reasoning_effort="high",
            allow_trading=True,
            system_prompt=(
                "Build a Ray Dalio-style idea-meritocracy leveraged ETF basket. This is not All Weather and not a one-ETF momentum bet. "
                "Use the specialists' disagreement process, reconcile overrides, and size at least three positions in normal conditions. "
                "Favor 3x ETFs for high-conviction sleeves, use 2x when conviction or drawdown risk is lower, and use inverse ETFs only as carefully justified hedge or downside exposure. "
                "SHV/cash-like exposure may count as one position only when evidence is too weak for full leveraged risk. "
                + DATA_USAGE_RULE + " " + LEVERAGE_RULE + " " + ORDER_READINESS_RULE
            ),
        )

    def on_trading_iteration(self):
        context = {
            "date": self.get_datetime().date().isoformat(),
            "universe": self.parameters["universe"],
            "min_positions": self.parameters["min_positions"],
            "data_expectation": "Use get_fred_snapshot/get_fred_latest and alpaca_news commonly; smoke tests inspect agent_detail for actual tool calls.",
            "leverage_expectation": "Use only leveraged ETFs plus SHV/cash escape, hold at least three positions, and bias toward diversified 3x exposure.",
            "data_tool_validation_run_id": "2026-07-08-fresh-alpaca-news-fred-smoke-v1",
        }
        growth = self.agents["growth_agent"].run(
            task_prompt=(
                "Call get_fred_snapshot or get_fred_latest and alpaca_news, then rank the strongest leveraged ETFs from a growth-regime view. "
                "Prefer diversified 3x exposure when evidence supports it."
            ),
            context=context,
        )
        inflation = self.agents["inflation_agent"].run(
            task_prompt=(
                "Call get_fred_snapshot or get_fred_latest and alpaca_news, then rank the strongest leveraged ETFs from an inflation-and-rates view. "
                "Explain any inverse or 2x risk-down preference."
            ),
            context=context,
        )
        liquidity = self.agents["debt_liquidity_agent"].run(
            task_prompt=(
                "Call get_fred_snapshot or get_fred_latest and alpaca_news, then rank the strongest leveraged ETFs from a debt-and-liquidity view. "
                "Explain whether liquidity argues for 3x risk, 2x risk-down, inverse exposure, or SHV ballast."
            ),
            context=context,
        )
        disagreement = self.agents["thoughtful_disagreement"].run(
            task_prompt="Challenge the growth, inflation, and liquidity views. Prefer a diversified leveraged basket of at least three symbols unless risk evidence argues for SHV/cash-like ballast.",
            context={**context, "growth": growth.summary, "inflation": inflation.summary, "liquidity": liquidity.summary},
        )
        self.agents["trader"].run(
            task_prompt=(
                "Rebalance into a diversified leveraged ETF basket of at least three positions. Bias toward 3x ETFs, use 2x only as a risk-down choice, and use inverse ETFs only with explicit hedge/downside evidence. "
                "Before each order, call account_portfolio, account_positions, and market_last_price for the exact ordered symbol in this same run. "
                "Explain which specialist advice you accepted or rejected and cite FRED/Alpaca evidence used."
            ),
            context={**context, "growth": growth.summary, "inflation": inflation.summary, "liquidity": liquidity.summary, "disagreement": disagreement.summary},
        )


if __name__ == "__main__":
    quote_asset = Asset("USD", Asset.AssetType.FOREX)
    params = AITradingTeamRayDalioIdeaMeritocracyStrategy.parameters

    if IS_BACKTESTING:
        trading_fee = TradingFee(percent_fee=0.001)
        AITradingTeamRayDalioIdeaMeritocracyStrategy.backtest(
            datasource_class=None,
            benchmark_asset=Asset("SPY", Asset.AssetType.STOCK),
            buy_trading_fees=[trading_fee],
            sell_trading_fees=[trading_fee],
            quote_asset=quote_asset,
            parameters=params,
        )
    else:
        trader = Trader()
        strategy = AITradingTeamRayDalioIdeaMeritocracyStrategy(
            quote_asset=quote_asset,
            parameters=params,
        )
        trader.add_strategy(strategy)
        trader.run_all()

Run it yourself

pip install lumibot
python -m lumibot.example_strategies.ai_trading_team_ray_dalio_idea_meritocracy

Add OPENAI_API_KEY for GPT-6 Luna and your broker keys (for example ALPACA_API_KEY, ALPACA_API_SECRET, and ALPACA_IS_PAPER=true) to your .env file. This file trades by default. Set IS_BACKTESTING=true in your environment to backtest it instead. For macro data, add a free FRED_API_KEY (see FRED Macro Data).

Good to know

  • Inspired by Ray Dalio’s public writing. Not affiliated with or endorsed by Ray Dalio or Bridgewater, and not a copy of any real strategy.

  • The picture shows the three research agents side by side because none of them depends on another. The code calls them one after another.

See AI Trading Bot Examples for more AI trading bots and Backtest, paper, or live: choose the runner for backtest and live runs.