DagonGod / utils /portfolio_manager.py
ratulsur's picture
Upload 10 files
ae34fa6 verified
import pandas as pd
import numpy as np
from typing import List, Dict, Optional
from utils.quantum_algorithms import QuantumInspiredOptimizer
from utils.data_loader import fetch_stock_data
class PortfolioManager:
def __init__(self):
self.quantum_optimizer = QuantumInspiredOptimizer()
self.watchlists = {} # User watchlists
self.portfolios = {} # User portfolios
def create_watchlist(self, user_id: str, name: str) -> Dict:
"""Create a new watchlist for a user"""
if user_id not in self.watchlists:
self.watchlists[user_id] = {}
self.watchlists[user_id][name] = []
return {'status': 'success', 'message': f'Watchlist {name} created'}
def add_to_watchlist(self, user_id: str, watchlist_name: str, symbol: str) -> Dict:
"""Add a symbol to a watchlist"""
if user_id in self.watchlists and watchlist_name in self.watchlists[user_id]:
if symbol not in self.watchlists[user_id][watchlist_name]:
self.watchlists[user_id][watchlist_name].append(symbol)
return {'status': 'success', 'message': f'Added {symbol} to watchlist'}
return {'status': 'error', 'message': 'Watchlist not found'}
def get_watchlist(self, user_id: str, watchlist_name: str) -> List[Dict]:
"""Get watchlist with current prices and analysis"""
if user_id not in self.watchlists or watchlist_name not in self.watchlists[user_id]:
return []
watchlist_data = []
for symbol in self.watchlists[user_id][watchlist_name]:
data = fetch_stock_data(symbol, period='1d')
if data is not None:
current_price = data['Close'].iloc[-1]
change = ((current_price - data['Open'].iloc[0]) / data['Open'].iloc[0]) * 100
watchlist_data.append({
'symbol': symbol,
'current_price': current_price,
'change_percent': change,
'last_updated': data.index[-1].strftime('%Y-%m-%d %H:%M:%S')
})
return watchlist_data
def optimize_portfolio(self, symbols: List[str], risk_tolerance: float = 0.5) -> Dict:
"""Optimize portfolio allocation using quantum-inspired algorithm"""
# Fetch historical data for all symbols
data = {}
for symbol in symbols:
hist_data = fetch_stock_data(symbol, period='1y')
if hist_data is not None:
data[symbol] = hist_data['Close']
if not data:
return {'status': 'error', 'message': 'No data available for optimization'}
# Calculate returns
returns = pd.DataFrame(data).pct_change().dropna()
# Get optimal weights
weights = self.quantum_optimizer.optimize_portfolio(returns, risk_tolerance)
# Calculate portfolio metrics
portfolio_return = sum(weights[symbol] * returns[symbol].mean() for symbol in symbols)
portfolio_risk = np.sqrt(sum(sum(
weights[s1] * weights[s2] * returns[s1].cov(returns[s2])
for s2 in symbols) for s1 in symbols))
return {
'status': 'success',
'allocation': weights,
'metrics': {
'expected_return': portfolio_return * 100, # Convert to percentage
'risk': portfolio_risk * 100, # Convert to percentage
'sharpe_ratio': portfolio_return / portfolio_risk if portfolio_risk > 0 else 0
}
}
def analyze_portfolio(self, portfolio: Dict[str, float]) -> Dict:
"""Analyze current portfolio performance and suggest rebalancing"""
symbols = list(portfolio.keys())
current_weights = list(portfolio.values())
# Get optimal weights
optimal_allocation = self.optimize_portfolio(symbols)
if optimal_allocation['status'] == 'error':
return optimal_allocation
# Compare current vs optimal allocation
rebalancing_needed = any(
abs(portfolio[symbol] - optimal_allocation['allocation'][symbol]) > 0.05
for symbol in symbols
)
return {
'status': 'success',
'current_allocation': portfolio,
'optimal_allocation': optimal_allocation['allocation'],
'metrics': optimal_allocation['metrics'],
'rebalancing_needed': rebalancing_needed,
'rebalancing_suggestions': {
symbol: optimal_allocation['allocation'][symbol] - portfolio[symbol]
for symbol in symbols
} if rebalancing_needed else {}
}