95 lines
4.5 KiB
Python
95 lines
4.5 KiB
Python
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):
|
|
"""
|
|
Create and configure an XAU (Gold) Positioning Analyst node that synthesizes COT reports and ETF flow data.
|
|
|
|
Constructs a tool-assisted prompt chain focused on Gold (XAU/USD) positioning using Commitment of Traders (COT) data and major gold ETF flows, and returns a node function that performs the analysis for a given state.
|
|
|
|
Returns:
|
|
xau_positioning_analyst_node (callable): A node function that accepts a `state` dict and returns a dict containing analysis messages and a generated `xau_positioning_report`.
|
|
"""
|
|
"""
|
|
Execute the XAU Positioning Analyst on a given state.
|
|
|
|
Parameters:
|
|
state (dict): Execution state containing at least:
|
|
- "trade_date": date or date-like string used as the prompt's current_date.
|
|
- "messages": list of messages to pass into the prompt chain.
|
|
|
|
Returns:
|
|
dict: {
|
|
"messages": [result_message], # list containing the chain result message
|
|
"xau_positioning_report": report (str) # report text when no tool calls were made, otherwise empty string
|
|
}
|
|
"""
|
|
|
|
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):
|
|
"""
|
|
Execute the XAU positioning analyst chain for the given state and produce a positioning report.
|
|
|
|
Parameters:
|
|
state (dict): Runtime state containing:
|
|
- "trade_date" (str or date): Trade date to bind into the analyst chain.
|
|
- "messages" (list): Messages to pass into the analyst chain.
|
|
|
|
Returns:
|
|
dict: {
|
|
"messages": [result], # list containing the chain invocation result object
|
|
"xau_positioning_report": str # report text extracted from result.content when no tool calls were made, otherwise an empty string
|
|
}
|
|
"""
|
|
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 |