Skip to content

Update total portfolio value error by breaking the loops #200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 80 additions & 56 deletions src/agents/risk_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,77 +7,101 @@

##### Risk Management Agent #####
def risk_management_agent(state: AgentState):
"""Controls position sizing based on real-world risk factors for multiple tickers."""
portfolio = state["data"]["portfolio"]
data = state["data"]
tickers = data["tickers"]

# Initialize risk analysis for each ticker
risk_analysis = {}
current_prices = {} # Store prices here to avoid redundant API calls
"""Controls position sizing based on real-world risk factors for multiple tickers."""
portfolio = state["data"]["portfolio"]
data = state["data"]
tickers = data["tickers"]

# Initialize risk analysis for each ticker
risk_analysis = {}
current_prices = {} # Store prices here to avoid redundant API calls
cost_value = {}

# intitialize total portfolio to cash
total_portfolio_value = portfolio.get("cash", 0)

# get all pricing and calculate total portfolio value
for ticker in tickers:
progress.update_status("risk_management_agent", ticker, "Portfolio calculation with latest price data")

prices = get_prices(
ticker=ticker,
start_date=data["start_date"],
end_date=data["end_date"],
)

for ticker in tickers:
progress.update_status("risk_management_agent", ticker, "Analyzing price data")
if not prices:
progress.update_status("risk_management_agent", ticker, "Failed: No price data found")
continue

prices = get_prices(
ticker=ticker,
start_date=data["start_date"],
end_date=data["end_date"],
)
prices_df = prices_to_df(prices)
progress.update_status("risk_management_agent", ticker, "Calculating position limits")

if not prices:
progress.update_status("risk_management_agent", ticker, "Failed: No price data found")
continue
# Calculate portfolio value
current_price = prices_df["close"].iloc[-1]
current_prices[ticker] = current_price # Store the current price

prices_df = prices_to_df(prices)
# Calculate current position value for this ticker
current_position_value = portfolio["positions"][ticker]["long"] * current_prices[ticker]

progress.update_status("risk_management_agent", ticker, "Calculating position limits")
cost_value[ticker] = portfolio["positions"][ticker]["long"] * portfolio["positions"][ticker]["long_cost_basis"]

# Calculate portfolio value
current_price = prices_df["close"].iloc[-1]
current_prices[ticker] = current_price # Store the current price
print("Current position value of ", ticker, " is: ", current_position_value)
print("Cost basis value of ", ticker, " is: ", cost_value[ticker])

# Calculate current position value for this ticker
current_position_value = portfolio.get("cost_basis", {}).get(ticker, 0)
# Calculate total portfolio value using stored prices
total_portfolio_value = total_portfolio_value + current_position_value

# Calculate total portfolio value using stored prices
total_portfolio_value = portfolio.get("cash", 0) + sum(portfolio.get("cost_basis", {}).get(t, 0) for t in portfolio.get("cost_basis", {}))
print("Total portfolio value is: ", total_portfolio_value)

# Base limit is 20% of portfolio for any single position
position_limit = total_portfolio_value * 0.20
for ticker in tickers:
progress.update_status("risk_management_agent", ticker, "Managing position limits")

# For existing positions, subtract current position value from limit
remaining_position_limit = position_limit - current_position_value
current_position_value = portfolio["positions"][ticker]["long"] * current_prices[ticker]

# Ensure we don't exceed available cash
max_position_size = min(remaining_position_limit, portfolio.get("cash", 0))
# Base limit is 20% of portfolio for any single position
position_limit = total_portfolio_value * 0.20
print("Position limit for ", ticker, " is: ", position_limit)

risk_analysis[ticker] = {
"remaining_position_limit": float(max_position_size),
"current_price": float(current_price),
"reasoning": {
"portfolio_value": float(total_portfolio_value),
"current_position": float(current_position_value),
"position_limit": float(position_limit),
"remaining_limit": float(remaining_position_limit),
"available_cash": float(portfolio.get("cash", 0)),
},
}
# For existing positions, subtract current position value from limit
remaining_position_limit = position_limit - current_position_value
print("Remaining position limit for ", ticker, " is: ", remaining_position_limit)

progress.update_status("risk_management_agent", ticker, "Done")

message = HumanMessage(
content=json.dumps(risk_analysis),
name="risk_management_agent",
)
# Ensure we don't exceed available cash
if remaining_position_limit < 0:
remaining_position_limit = 0

if state["metadata"]["show_reasoning"]:
show_agent_reasoning(risk_analysis, "Risk Management Agent")
max_position_size = min(remaining_position_limit, portfolio.get("cash", 0))

# Add the signal to the analyst_signals list
state["data"]["analyst_signals"]["risk_management_agent"] = risk_analysis
print("Max position size for ", ticker, " is: ", max_position_size)

return {
"messages": state["messages"] + [message],
"data": data,
risk_analysis[ticker] = {
"remaining_position_limit": float(max_position_size),
"current_price": float(current_price),
"reasoning": {
"portfolio_value": float(total_portfolio_value),
"current_position": float(current_position_value),
"position_limit": float(position_limit),
"remaining_limit": float(remaining_position_limit),
"available_cash": float(portfolio.get("cash", 0)),
},
}

progress.update_status("risk_management_agent", ticker, "Done")

message = HumanMessage(
content=json.dumps(risk_analysis),
name="risk_management_agent",
)

if state["metadata"]["show_reasoning"]:
show_agent_reasoning(risk_analysis, "Risk Management Agent")

# Add the signal to the analyst_signals list
state["data"]["analyst_signals"]["risk_management_agent"] = risk_analysis

return {
"messages": state["messages"] + [message],
"data": data,
}