diff --git a/tradingagents/agents/analysts/xau_macro_analyst.py b/tradingagents/agents/analysts/xau_macro_analyst.py new file mode 100644 index 00000000..b582da5c --- /dev/null +++ b/tradingagents/agents/analysts/xau_macro_analyst.py @@ -0,0 +1,70 @@ +from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder +from tradingagents.dataflows.fred_api import get_dxy_data, get_real_yields, get_inflation_data, get_fred_series + +def create_xau_macro_analyst(llm): + """ + Creates a node for the XAU Macro Analyst agent. + + This agent specializes in analyzing macroeconomic factors that influence the price of gold (XAU/USD). + It replaces the traditional fundamentals analyst for equity trading. + """ + + system_message = ( + "You are a specialized Macroeconomic Analyst for Gold (XAU/USD). Your mission is to provide a detailed analysis of the key macro drivers affecting gold's price. " + "DO NOT analyze company fundamentals. Instead, focus exclusively on the following:" + "\n\n1. **US Dollar Index (DXY)**: Analyze its recent trend (e.g., past 90 days). Is it strengthening or weakening? Explain how this trend typically impacts gold." + "\n2. **Real Yields**: Analyze the trend in 10-year real yields. Are they rising or falling? Explain the inverse relationship between real yields and gold (i.e., opportunity cost)." + "\n3. **Inflation Data**: Review the latest inflation metrics (CPI, PCE). Is inflation running hot or cooling down? Explain how inflation expectations affect gold's appeal as a hedge." + "\n4. **Fed Policy & VIX (Optional)**: Briefly mention the current Federal Reserve stance (if known) and the VIX level as a measure of market fear." + "\n\nUse the available tools to fetch the necessary data. Synthesize your findings into a comprehensive report. " + "Conclude your report with a Markdown table summarizing the key macro factors and their likely impact on gold (Bullish, Bearish, or Neutral)." + ) + + prompt = ChatPromptTemplate.from_messages( + [ + ( + "system", + "You are a helpful AI assistant, collaborating with other assistants." + " Use the provided tools to progress towards answering the question." + " The asset of interest is Gold (XAU/USD)." + " For your reference, the current date is {current_date}." + "\n\nTool Names: {tool_names}" + "\n\n{system_message}", + ), + MessagesPlaceholder(variable_name="messages"), + ] + ) + + tools = [ + get_dxy_data, + get_real_yields, + get_inflation_data, + get_fred_series, # For VIX or other specific series + ] + + prompt = prompt.partial( + system_message=system_message, + tool_names=", ".join([tool.name for tool in tools]), + ) + + chain = prompt | llm.bind_tools(tools) + + def xau_macro_analyst_node(state): + """ + The node function for the XAU Macro Analyst. + """ + current_date = state["trade_date"] + # The ticker is XAU, but the tools are specific to macro data. + chain_with_date = chain.partial(current_date=current_date) + result = chain_with_date.invoke(state["messages"]) + + report = "" + if not result.tool_calls: + report = result.content + + return { + "messages": [result], + "xau_macro_report": report, + } + + return xau_macro_analyst_node \ No newline at end of file diff --git a/tradingagents/agents/analysts/xau_market_analyst.py b/tradingagents/agents/analysts/xau_market_analyst.py new file mode 100644 index 00000000..7136e4ae --- /dev/null +++ b/tradingagents/agents/analysts/xau_market_analyst.py @@ -0,0 +1 @@ +# Placeholder for XAU Market Analyst \ No newline at end of file diff --git a/tradingagents/agents/analysts/xau_news_analyst.py b/tradingagents/agents/analysts/xau_news_analyst.py new file mode 100644 index 00000000..780146b6 --- /dev/null +++ b/tradingagents/agents/analysts/xau_news_analyst.py @@ -0,0 +1 @@ +# Placeholder for XAU News Analyst \ No newline at end of file diff --git a/tradingagents/agents/analysts/xau_positioning_analyst.py b/tradingagents/agents/analysts/xau_positioning_analyst.py new file mode 100644 index 00000000..872a912e --- /dev/null +++ b/tradingagents/agents/analysts/xau_positioning_analyst.py @@ -0,0 +1,68 @@ +from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder +from tradingagents.dataflows.cot_data import get_cot_positioning, analyze_cot_extremes +from tradingagents.dataflows.etf_flows import get_gold_etf_summary, get_gold_etf_flows + +def create_xau_positioning_analyst(llm): + """ + Creates a node for the XAU Positioning Analyst agent. + + This agent analyzes market positioning and sentiment for gold (XAU/USD) + using COT reports and ETF flow data. It replaces the standard social media analyst. + """ + + system_message = ( + "You are a specialized Market Positioning Analyst for Gold (XAU/USD). Your task is to analyze sentiment and capital flows from institutional and speculative traders. " + "Ignore social media. Your analysis must be based on hard data." + "\n\n1. **Commitment of Traders (COT) Report**: Use the `get_cot_positioning` and `analyze_cot_extremes` tools. What is the net positioning of Large Speculators vs. Commercials? Is the positioning at a historical extreme? Extreme positioning is often a strong contrarian indicator." + "\n2. **Gold ETF Flows**: Use the `get_gold_etf_summary` tool. Are major gold ETFs (like GLD and IAU) seeing inflows or outflows? Explain what this indicates about institutional investor sentiment." + "\n3. **Synthesis**: Combine the insights from both COT data and ETF flows. For example, are speculators heavily long while ETFs are seeing outflows? This could be a major divergence." + "\n\nSynthesize your findings into a comprehensive report. Conclude with a Markdown table summarizing the positioning data and its likely impact on gold (Bullish, Bearish, or Neutral)." + ) + + prompt = ChatPromptTemplate.from_messages( + [ + ( + "system", + "You are a helpful AI assistant, collaborating with other assistants." + " Use the provided tools to progress towards answering the question." + " The asset of interest is Gold (XAU/USD)." + " For your reference, the current date is {current_date}." + "\n\nTool Names: {tool_names}" + "\n\n{system_message}", + ), + MessagesPlaceholder(variable_name="messages"), + ] + ) + + tools = [ + get_cot_positioning, + analyze_cot_extremes, + get_gold_etf_summary, + get_gold_etf_flows, + ] + + prompt = prompt.partial( + system_message=system_message, + tool_names=", ".join([tool.name for tool in tools]), + ) + + chain = prompt | llm.bind_tools(tools) + + def xau_positioning_analyst_node(state): + """ + The node function for the XAU Positioning Analyst. + """ + current_date = state["trade_date"] + chain_with_date = chain.partial(current_date=current_date) + result = chain_with_date.invoke(state["messages"]) + + report = "" + if not result.tool_calls: + report = result.content + + return { + "messages": [result], + "xau_positioning_report": report, + } + + return xau_positioning_analyst_node \ No newline at end of file diff --git a/tradingagents/agents/utils/agent_utils.py b/tradingagents/agents/utils/agent_utils.py index 8ad4df15..01a3d334 100644 --- a/tradingagents/agents/utils/agent_utils.py +++ b/tradingagents/agents/utils/agent_utils.py @@ -34,6 +34,30 @@ from tradingagents.agents.utils.crypto_tools import ( get_market_overview ) +# XAU-specific tools (Gold) +from tradingagents.dataflows.fred_api import ( + get_dxy_data, + get_real_yields, + get_inflation_data, + get_fred_series, +) +from tradingagents.dataflows.cot_data import ( + get_cot_positioning, + analyze_cot_extremes, +) +from tradingagents.dataflows.etf_flows import ( + get_gold_etf_summary, + get_gold_etf_flows, + analyze_etf_divergence, +) +from tradingagents.dataflows.correlation_tools import ( + calculate_asset_correlation, + analyze_gold_macro_correlations, + check_correlation_regime, + get_rolling_correlations, +) + + def create_msg_delete(): def delete_messages(state): """Clear messages and add placeholder for Anthropic compatibility""" diff --git a/tradingagents/graph/xau_graph.py b/tradingagents/graph/xau_graph.py new file mode 100644 index 00000000..638e3a74 --- /dev/null +++ b/tradingagents/graph/xau_graph.py @@ -0,0 +1,67 @@ +from langgraph.prebuilt import ToolNode +from tradingagents.graph.trading_graph import TradingAgentsGraph +from tradingagents.xau_config import XAU_CONFIG + +# Import XAU-specific tools +from tradingagents.agents.utils.agent_utils import ( + get_stock_data, + get_indicators, + get_correlation, + get_dxy_data, + get_real_yields, + get_inflation_data, + get_fred_series, + get_news, + get_global_news, + get_cot_positioning, + analyze_cot_extremes, + get_gold_etf_summary, + get_gold_etf_flows, +) + +class XAUTradingGraph(TradingAgentsGraph): + """ + A specialized trading graph for XAU (Gold) trading. + + This graph uses a custom set of agents and tools tailored for macroeconomic + and positioning analysis relevant to gold. + """ + + def __init__(self, debug=False, config=None): + # Use XAU-specific config and analyst team + xau_config = config or XAU_CONFIG + xau_analysts = xau_config.get("analyst_team", []) + + super().__init__( + selected_analysts=xau_analysts, + debug=debug, + config=xau_config + ) + + def _create_tool_nodes(self): + """ + Override the tool node creation to use XAU-specific tools. + """ + return { + "xau_market": ToolNode([ + get_stock_data, # For XAU/USD price data from yfinance (e.g., "GC=F") + get_indicators, # Standard technical indicators + get_correlation, # For correlation with DXY, etc. + ]), + "xau_macro": ToolNode([ + get_dxy_data, + get_real_yields, + get_inflation_data, + get_fred_series, # For VIX, etc. + ]), + "xau_news": ToolNode([ + get_news, # For general and gold-specific news + get_global_news, + ]), + "xau_positioning": ToolNode([ + get_cot_positioning, + analyze_cot_extremes, + get_gold_etf_summary, + get_gold_etf_flows, + ]), + } \ No newline at end of file diff --git a/tradingagents/xau_config.py b/tradingagents/xau_config.py new file mode 100644 index 00000000..8a690086 --- /dev/null +++ b/tradingagents/xau_config.py @@ -0,0 +1,35 @@ +from tradingagents.default_config import DEFAULT_CONFIG + +# Create a deep copy to avoid modifying the original default config +XAU_CONFIG = { + **DEFAULT_CONFIG, + "asset_class": "commodity", + "trading_hours": "24/5", + "tick_size": 0.01, + "contract_size": 100, # oz for futures + "max_leverage": 50, + "max_position_size_pct": 2.0, + "atr_multiplier_stop": 2.5, + "correlation_threshold": -0.6, +} + +# Override data vendors for XAU-specific sources +XAU_CONFIG["data_vendors"] = { + **DEFAULT_CONFIG["data_vendors"], + "core_stock_apis": "yfinance", # For XAU/USD price data (GC=F) + "technical_indicators": "yfinance", + "macro_data": "fred", # NEW: FRED for macro + "positioning_data": "cot_api", # NEW: COT data + "etf_data": "yfinance", # NEW: ETF flows via yfinance + # Override equity-specific vendors + "fundamental_data": "fred", # Gold uses macro data, not company fundamentals + "news_data": "alpha_vantage", # Can still use for general market news +} + +# Define the specialized analyst team for XAU +XAU_CONFIG["analyst_team"] = [ + "xau_market", + "xau_macro", + "xau_news", + "xau_positioning", +] \ No newline at end of file diff --git a/xau_main.py b/xau_main.py new file mode 100644 index 00000000..1122807f --- /dev/null +++ b/xau_main.py @@ -0,0 +1,53 @@ +from tradingagents.graph.xau_graph import XAUTradingGraph +from tradingagents.xau_config import XAU_CONFIG +from dotenv import load_dotenv + +# Load environment variables from .env file +load_dotenv() + +def run_xau_analysis(): + """ + Initializes and runs the XAU Trading System for a specific date. + """ + print("Initializing XAU Trading System...") + + # Initialize the specialized XAU graph with its config + xau_system = XAUTradingGraph(debug=True, config=XAU_CONFIG) + + # Define the asset and date for analysis + # "GC=F" is the Yahoo Finance ticker for Gold futures. + # The system will use this for price data but analyze "XAU" conceptually. + asset_ticker = "GC=F" + trade_date = "2024-05-10" + + print(f"Running analysis for asset: {asset_ticker} (Gold) on date: {trade_date}") + + # Propagate the state through the graph to get a decision + try: + final_state, decision = xau_system.propagate(asset_ticker, trade_date) + + print("\n" + "="*80) + print("XAU Trading Analysis Complete") + print("="*80) + + # Print the reports generated by the new agents + if final_state.get("xau_macro_report"): + print("\n--- Macro Analyst Report ---") + print(final_state["xau_macro_report"]) + + if final_state.get("xau_positioning_report"): + print("\n--- Positioning Analyst Report ---") + print(final_state["xau_positioning_report"]) + + print("\n--- Final Trade Decision ---") + print(decision) + print("="*80) + + except Exception as e: + print(f"\nAn error occurred during XAU analysis: {e}") + import traceback + traceback.print_exc() + + +if __name__ == "__main__": + run_xau_analysis() \ No newline at end of file