ratulsur commited on
Commit
ae34fa6
·
verified ·
1 Parent(s): 7b8a1d8

Upload 10 files

Browse files
utils/data_loader.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yfinance as yf
2
+ import pandas as pd
3
+ import streamlit as st
4
+ from datetime import datetime, timedelta
5
+ import io
6
+
7
+ @st.cache_data(ttl=3600)
8
+ def load_nifty50_symbols():
9
+ """Load Nifty 50 symbols"""
10
+ symbols = [
11
+ # IT Sector
12
+ "TCS.NS", "INFY.NS", "HCLTECH.NS", "TECHM.NS", "WIPRO.NS",
13
+
14
+ # Banking & Finance
15
+ "HDFCBANK.NS", "ICICIBANK.NS", "SBIN.NS", "AXISBANK.NS", "KOTAKBANK.NS",
16
+ "BAJFINANCE.NS", "BAJAJFINSV.NS", "HDFC.NS", "INDUSINDBK.NS",
17
+
18
+ # Energy & Oil
19
+ "RELIANCE.NS", "ONGC.NS", "POWERGRID.NS", "NTPC.NS", "BPCL.NS",
20
+
21
+ # Automobile
22
+ "TATAMOTORS.NS", "M&M.NS", "MARUTI.NS", "HEROMOTOCO.NS", "EICHERMOT.NS",
23
+
24
+ # Consumer Goods
25
+ "HINDUNILVR.NS", "ITC.NS", "NESTLEIND.NS", "BRITANNIA.NS", "TITAN.NS",
26
+
27
+ # Metals & Mining
28
+ "TATASTEEL.NS", "HINDALCO.NS", "JSWSTEEL.NS", "COALINDIA.NS",
29
+
30
+ # Pharmaceuticals
31
+ "SUNPHARMA.NS", "DRREDDY.NS", "CIPLA.NS", "DIVISLAB.NS",
32
+
33
+ # Infrastructure
34
+ "LT.NS", "ADANIPORTS.NS", "ULTRACEMCO.NS", "SHREECEM.NS", "GRASIM.NS",
35
+
36
+ # Telecommunications
37
+ "BHARTIARTL.NS",
38
+
39
+ # Others
40
+ "ASIANPAINT.NS", "HDFCLIFE.NS", "SBILIFE.NS", "UPL.NS", "ADANIENT.NS",
41
+ "BAJAJ-AUTO.NS", "APOLLOHOSP.NS", "DMART.NS", "PIDILITIND.NS"
42
+ ]
43
+ return symbols
44
+
45
+ @st.cache_data(ttl=3600)
46
+ def load_market_indices():
47
+ """Load major Indian market indices"""
48
+ indices = {
49
+ "NIFTY 50": "^NSEI",
50
+ "SENSEX": "^BSESN",
51
+ "BANK NIFTY": "^NSEBANK",
52
+ "NIFTY IT": "NIFTYIT.NS",
53
+ "NIFTY PHARMA": "NIFTYPHARMA.NS",
54
+ "NIFTY AUTO": "NIFTYAUTO.NS",
55
+ "NIFTY FMCG": "NIFTYFMCG.NS",
56
+ "NIFTY METAL": "NIFTYMETAL.NS",
57
+ "BSE 500": "^BSEFTY",
58
+ "NSE 500": "NIFTY500.NS"
59
+ }
60
+ return indices
61
+
62
+ def process_uploaded_file(uploaded_file):
63
+ """Process uploaded CSV/Excel file"""
64
+ try:
65
+ if uploaded_file.name.endswith('.csv'):
66
+ df = pd.read_csv(uploaded_file)
67
+ elif uploaded_file.name.endswith(('.xls', '.xlsx')):
68
+ df = pd.read_excel(uploaded_file)
69
+ else:
70
+ raise ValueError("Unsupported file format")
71
+
72
+ # Ensure required columns exist
73
+ required_columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume']
74
+ if not all(col in df.columns for col in required_columns):
75
+ raise ValueError("Missing required columns")
76
+
77
+ # Convert Date column to datetime
78
+ df['Date'] = pd.to_datetime(df['Date'])
79
+ return df
80
+ except Exception as e:
81
+ st.error(f"Error processing file: {str(e)}")
82
+ return None
83
+
84
+ @st.cache_data(ttl=3600)
85
+ def fetch_stock_data(symbol, period='1y'):
86
+ """Fetch stock data from Yahoo Finance"""
87
+ try:
88
+ stock = yf.Ticker(symbol)
89
+ data = stock.history(period=period)
90
+ return data
91
+ except Exception as e:
92
+ st.error(f"Error fetching data for {symbol}: {str(e)}")
93
+ return None
94
+
95
+ @st.cache_data(ttl=3600)
96
+ def get_stock_info(symbol):
97
+ """Get stock information"""
98
+ try:
99
+ stock = yf.Ticker(symbol)
100
+ info = stock.info
101
+ return {
102
+ 'name': info.get('longName', symbol),
103
+ 'sector': info.get('sector', 'N/A'),
104
+ 'market_cap': info.get('marketCap', 0),
105
+ 'pe_ratio': info.get('trailingPE', 0),
106
+ 'volume': info.get('volume', 0),
107
+ 'recommendation': info.get('recommendationKey', 'N/A'),
108
+ 'target_price': info.get('targetMeanPrice', 0)
109
+ }
110
+ except Exception as e:
111
+ st.error(f"Error fetching info for {symbol}: {str(e)}")
112
+ return None
113
+
114
+ def get_market_summary():
115
+ """Get market summary for indices"""
116
+ try:
117
+ indices = load_market_indices()
118
+ summaries = {}
119
+
120
+ for name, symbol in indices.items():
121
+ ticker = yf.Ticker(symbol)
122
+ data = ticker.history(period='1d')
123
+
124
+ if not data.empty:
125
+ summaries[name] = {
126
+ 'index_value': data['Close'].iloc[-1],
127
+ 'change': data['Close'].iloc[-1] - data['Open'].iloc[0],
128
+ 'change_percent': ((data['Close'].iloc[-1] - data['Open'].iloc[0]) / data['Open'].iloc[0]) * 100
129
+ }
130
+
131
+ return summaries
132
+ except Exception as e:
133
+ st.error(f"Error fetching market summary: {str(e)}")
134
+ return None
135
+
136
+ def get_stock_suggestions(data):
137
+ """Generate stock suggestions based on technical indicators"""
138
+ try:
139
+ # Simple moving averages
140
+ data['SMA20'] = data['Close'].rolling(window=20).mean()
141
+ data['SMA50'] = data['Close'].rolling(window=50).mean()
142
+
143
+ # Get latest values
144
+ current_price = data['Close'].iloc[-1]
145
+ sma20 = data['SMA20'].iloc[-1]
146
+ sma50 = data['SMA50'].iloc[-1]
147
+
148
+ # Generate suggestion
149
+ if sma20 > sma50:
150
+ trend = "BULLISH"
151
+ suggestion = "Consider buying. Price is above moving averages."
152
+ elif sma20 < sma50:
153
+ trend = "BEARISH"
154
+ suggestion = "Consider selling. Price is below moving averages."
155
+ else:
156
+ trend = "NEUTRAL"
157
+ suggestion = "Market is sideways. Wait for clear trend."
158
+
159
+ return {
160
+ 'trend': trend,
161
+ 'suggestion': suggestion,
162
+ 'current_price': current_price,
163
+ 'sma20': sma20,
164
+ 'sma50': sma50
165
+ }
166
+ except Exception as e:
167
+ st.error(f"Error generating suggestions: {str(e)}")
168
+ return None
utils/market_analysis.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ from typing import Dict, Any
4
+ import requests
5
+ import os
6
+ from datetime import datetime, timedelta
7
+
8
+ class MarketAnalyzer:
9
+ def __init__(self):
10
+ self.risk_levels = {
11
+ 'LOW': 'Conservative investment suitable for long-term holding',
12
+ 'MEDIUM': 'Moderate risk with potential for both gains and losses',
13
+ 'HIGH': 'High volatility, suitable for aggressive trading'
14
+ }
15
+ self.deepseek_api_key = os.environ.get("DEEPSEEK_API_KEY")
16
+ self.deepseek_api_url = "https://api.deepseek.com/v1/chat/completions"
17
+
18
+ def calculate_technical_indicators(self, data: pd.DataFrame) -> Dict[str, Any]:
19
+ """Calculate comprehensive technical indicators"""
20
+ try:
21
+ # Price-based indicators
22
+ data['SMA_20'] = data['Close'].rolling(window=20).mean()
23
+ data['SMA_50'] = data['Close'].rolling(window=50).mean()
24
+ data['SMA_200'] = data['Close'].rolling(window=200).mean()
25
+
26
+ # Relative Strength Index (RSI)
27
+ delta = data['Close'].diff()
28
+ gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
29
+ loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
30
+ rs = gain / loss
31
+ data['RSI'] = 100 - (100 / (1 + rs))
32
+
33
+ # MACD
34
+ exp1 = data['Close'].ewm(span=12, adjust=False).mean()
35
+ exp2 = data['Close'].ewm(span=26, adjust=False).mean()
36
+ data['MACD'] = exp1 - exp2
37
+ data['Signal_Line'] = data['MACD'].ewm(span=9, adjust=False).mean()
38
+
39
+ # Bollinger Bands
40
+ data['BB_middle'] = data['Close'].rolling(window=20).mean()
41
+ bb_std = data['Close'].rolling(window=20).std()
42
+ data['BB_upper'] = data['BB_middle'] + (bb_std * 2)
43
+ data['BB_lower'] = data['BB_middle'] - (bb_std * 2)
44
+
45
+ # Average True Range (ATR)
46
+ high_low = data['High'] - data['Low']
47
+ high_close = abs(data['High'] - data['Close'].shift())
48
+ low_close = abs(data['Low'] - data['Close'].shift())
49
+ ranges = pd.concat([high_low, high_close, low_close], axis=1)
50
+ true_range = ranges.max(axis=1)
51
+ data['ATR'] = true_range.rolling(window=14).mean()
52
+
53
+ # Volume indicators
54
+ data['Volume_SMA'] = data['Volume'].rolling(window=20).mean()
55
+ data['Volume_Rate'] = data['Volume'] / data['Volume_SMA']
56
+
57
+ return data
58
+ except Exception as e:
59
+ raise Exception(f"Error calculating technical indicators: {str(e)}")
60
+
61
+ def analyze_price_action(self, data: pd.DataFrame) -> Dict[str, Any]:
62
+ """Analyze recent price action and trends"""
63
+ try:
64
+ current_price = data['Close'].iloc[-1]
65
+ sma_20 = data['SMA_20'].iloc[-1]
66
+ sma_50 = data['SMA_50'].iloc[-1]
67
+ sma_200 = data['SMA_200'].iloc[-1]
68
+ rsi = data['RSI'].iloc[-1]
69
+ macd = data['MACD'].iloc[-1]
70
+ signal = data['Signal_Line'].iloc[-1]
71
+ volume_rate = data['Volume_Rate'].iloc[-1]
72
+
73
+ # Trend Analysis
74
+ short_term_trend = "BULLISH" if current_price > sma_20 else "BEARISH"
75
+ medium_term_trend = "BULLISH" if sma_20 > sma_50 else "BEARISH"
76
+ long_term_trend = "BULLISH" if sma_50 > sma_200 else "BEARISH"
77
+
78
+ # Momentum Analysis
79
+ momentum = {
80
+ 'RSI': {
81
+ 'value': rsi,
82
+ 'signal': 'OVERBOUGHT' if rsi > 70 else 'OVERSOLD' if rsi < 30 else 'NEUTRAL'
83
+ },
84
+ 'MACD': {
85
+ 'histogram': macd - signal,
86
+ 'signal': 'BULLISH' if macd > signal else 'BEARISH'
87
+ }
88
+ }
89
+
90
+ # Volume Analysis
91
+ volume_trend = "HIGH" if volume_rate > 1.5 else "LOW" if volume_rate < 0.5 else "NORMAL"
92
+
93
+ return {
94
+ 'trends': {
95
+ 'short_term': short_term_trend,
96
+ 'medium_term': medium_term_trend,
97
+ 'long_term': long_term_trend
98
+ },
99
+ 'momentum': momentum,
100
+ 'volume_analysis': {
101
+ 'trend': volume_trend,
102
+ 'rate': volume_rate
103
+ }
104
+ }
105
+ except Exception as e:
106
+ raise Exception(f"Error analyzing price action: {str(e)}")
107
+
108
+ def generate_trade_signals(self, data: pd.DataFrame) -> Dict[str, Any]:
109
+ """Generate trading signals based on technical analysis"""
110
+ try:
111
+ analysis = self.analyze_price_action(data)
112
+ current_price = data['Close'].iloc[-1]
113
+
114
+ # Signal Strength Calculation
115
+ bullish_signals = 0
116
+ bearish_signals = 0
117
+
118
+ # Trend Signals
119
+ for trend in analysis['trends'].values():
120
+ if trend == "BULLISH":
121
+ bullish_signals += 1
122
+ else:
123
+ bearish_signals += 1
124
+
125
+ # Momentum Signals
126
+ if analysis['momentum']['RSI']['signal'] == 'OVERSOLD':
127
+ bullish_signals += 1
128
+ elif analysis['momentum']['RSI']['signal'] == 'OVERBOUGHT':
129
+ bearish_signals += 1
130
+
131
+ if analysis['momentum']['MACD']['signal'] == 'BULLISH':
132
+ bullish_signals += 1
133
+ else:
134
+ bearish_signals += 1
135
+
136
+ # Volume Confirmation
137
+ if analysis['volume_analysis']['trend'] == 'HIGH':
138
+ if bullish_signals > bearish_signals:
139
+ bullish_signals += 1
140
+ else:
141
+ bearish_signals += 1
142
+
143
+ # Risk Assessment
144
+ volatility = data['ATR'].iloc[-1] / current_price * 100
145
+ risk_level = 'HIGH' if volatility > 3 else 'MEDIUM' if volatility > 1.5 else 'LOW'
146
+
147
+ # Generate Action Signal
148
+ signal_strength = (bullish_signals - bearish_signals) / (bullish_signals + bearish_signals)
149
+
150
+ if abs(signal_strength) < 0.2:
151
+ action = "HOLD"
152
+ confidence = "LOW"
153
+ else:
154
+ action = "BUY" if signal_strength > 0 else "SELL"
155
+ confidence = "HIGH" if abs(signal_strength) > 0.6 else "MEDIUM"
156
+
157
+ return {
158
+ 'action': action,
159
+ 'confidence': confidence,
160
+ 'risk_level': risk_level,
161
+ 'support_resistance': {
162
+ 'support': data['BB_lower'].iloc[-1],
163
+ 'resistance': data['BB_upper'].iloc[-1]
164
+ },
165
+ 'metrics': {
166
+ 'bullish_signals': bullish_signals,
167
+ 'bearish_signals': bearish_signals,
168
+ 'volatility': volatility
169
+ }
170
+ }
171
+ except Exception as e:
172
+ raise Exception(f"Error generating trade signals: {str(e)}")
173
+
174
+ async def get_ai_sentiment(self, symbol: str, price_data: pd.DataFrame) -> str:
175
+ """Get AI-powered market sentiment analysis using Deepseek API"""
176
+ try:
177
+ if not self.deepseek_api_key:
178
+ return "Error: Deepseek API key not found"
179
+
180
+ # Prepare market data summary
181
+ recent_data = price_data.tail(5)
182
+ price_change = (recent_data['Close'].iloc[-1] - recent_data['Close'].iloc[0]) / recent_data['Close'].iloc[0] * 100
183
+ volume_change = (recent_data['Volume'].iloc[-1] - recent_data['Volume'].iloc[0]) / recent_data['Volume'].iloc[0] * 100
184
+ rsi = self.calculate_rsi(price_data['Close'])[-1] if not price_data.empty else None
185
+
186
+ # Create prompt for Deepseek
187
+ prompt = f"""Analyze the following market data for {symbol}:
188
+ - Recent price change: {price_change:.2f}%
189
+ - Volume change: {volume_change:.2f}%
190
+ - RSI: {rsi:.2f if rsi is not None else 'N/A'}
191
+
192
+ Please provide a JSON response with the following structure:
193
+ {{
194
+ "sentiment": "bullish/bearish/neutral",
195
+ "confidence": <float between 0 and 1>,
196
+ "recommendation": "buy/sell/hold",
197
+ "risk_level": "low/medium/high",
198
+ "key_factors": [<array of reasons>]
199
+ }}"""
200
+
201
+ # Call Deepseek API
202
+ headers = {
203
+ "Authorization": f"Bearer {self.deepseek_api_key}",
204
+ "Content-Type": "application/json"
205
+ }
206
+
207
+ payload = {
208
+ "model": "deepseek-chat",
209
+ "messages": [
210
+ {
211
+ "role": "system",
212
+ "content": "You are an expert financial analyst. Provide market analysis in the exact JSON format requested."
213
+ },
214
+ {
215
+ "role": "user",
216
+ "content": prompt
217
+ }
218
+ ],
219
+ "temperature": 0.7,
220
+ "max_tokens": 500
221
+ }
222
+
223
+ response = requests.post(
224
+ self.deepseek_api_url,
225
+ headers=headers,
226
+ json=payload,
227
+ timeout=10
228
+ )
229
+
230
+ if response.status_code != 200:
231
+ return f"API Error: {response.status_code} - {response.text}"
232
+
233
+ # Extract the response content
234
+ try:
235
+ result = response.json()
236
+ if 'choices' in result and len(result['choices']) > 0:
237
+ return result['choices'][0]['message']['content']
238
+ else:
239
+ return "Error: Invalid API response format"
240
+ except Exception as e:
241
+ return f"Error parsing API response: {str(e)}"
242
+
243
+ except Exception as e:
244
+ return f"Error in sentiment analysis: {str(e)}"
245
+
246
+ def calculate_rsi(self, prices: pd.Series, period: int = 14) -> pd.Series:
247
+ """Calculate Relative Strength Index"""
248
+ delta = prices.diff()
249
+ gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
250
+ loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
251
+ rs = gain / loss
252
+ return 100 - (100 / (1 + rs))
253
+
254
+ def generate_detailed_report(self, symbol: str, data: pd.DataFrame, ai_sentiment: str = None) -> Dict[str, Any]:
255
+ """Generate comprehensive analysis report"""
256
+ try:
257
+ # Calculate all indicators
258
+ data = self.calculate_technical_indicators(data)
259
+
260
+ # Get trading signals
261
+ signals = self.generate_trade_signals(data)
262
+
263
+ # Price analysis
264
+ current_price = data['Close'].iloc[-1]
265
+ price_change_1d = (current_price - data['Close'].iloc[-2]) / data['Close'].iloc[-2] * 100
266
+ price_change_1w = (current_price - data['Close'].iloc[-6]) / data['Close'].iloc[-6] * 100
267
+
268
+ report = {
269
+ 'symbol': symbol,
270
+ 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
271
+ 'price_analysis': {
272
+ 'current_price': current_price,
273
+ 'changes': {
274
+ '1d': price_change_1d,
275
+ '1w': price_change_1w
276
+ }
277
+ },
278
+ 'technical_analysis': self.analyze_price_action(data),
279
+ 'trade_signals': signals,
280
+ 'risk_assessment': {
281
+ 'level': signals['risk_level'],
282
+ 'description': self.risk_levels[signals['risk_level']],
283
+ 'volatility': signals['metrics']['volatility']
284
+ }
285
+ }
286
+
287
+ if ai_sentiment:
288
+ report['ai_sentiment'] = ai_sentiment
289
+
290
+ return report
291
+ except Exception as e:
292
+ raise Exception(f"Error generating detailed report: {str(e)}")
utils/portfolio_manager.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ from typing import List, Dict, Optional
4
+ from utils.quantum_algorithms import QuantumInspiredOptimizer
5
+ from utils.data_loader import fetch_stock_data
6
+
7
+ class PortfolioManager:
8
+ def __init__(self):
9
+ self.quantum_optimizer = QuantumInspiredOptimizer()
10
+ self.watchlists = {} # User watchlists
11
+ self.portfolios = {} # User portfolios
12
+
13
+ def create_watchlist(self, user_id: str, name: str) -> Dict:
14
+ """Create a new watchlist for a user"""
15
+ if user_id not in self.watchlists:
16
+ self.watchlists[user_id] = {}
17
+
18
+ self.watchlists[user_id][name] = []
19
+ return {'status': 'success', 'message': f'Watchlist {name} created'}
20
+
21
+ def add_to_watchlist(self, user_id: str, watchlist_name: str, symbol: str) -> Dict:
22
+ """Add a symbol to a watchlist"""
23
+ if user_id in self.watchlists and watchlist_name in self.watchlists[user_id]:
24
+ if symbol not in self.watchlists[user_id][watchlist_name]:
25
+ self.watchlists[user_id][watchlist_name].append(symbol)
26
+ return {'status': 'success', 'message': f'Added {symbol} to watchlist'}
27
+ return {'status': 'error', 'message': 'Watchlist not found'}
28
+
29
+ def get_watchlist(self, user_id: str, watchlist_name: str) -> List[Dict]:
30
+ """Get watchlist with current prices and analysis"""
31
+ if user_id not in self.watchlists or watchlist_name not in self.watchlists[user_id]:
32
+ return []
33
+
34
+ watchlist_data = []
35
+ for symbol in self.watchlists[user_id][watchlist_name]:
36
+ data = fetch_stock_data(symbol, period='1d')
37
+ if data is not None:
38
+ current_price = data['Close'].iloc[-1]
39
+ change = ((current_price - data['Open'].iloc[0]) / data['Open'].iloc[0]) * 100
40
+
41
+ watchlist_data.append({
42
+ 'symbol': symbol,
43
+ 'current_price': current_price,
44
+ 'change_percent': change,
45
+ 'last_updated': data.index[-1].strftime('%Y-%m-%d %H:%M:%S')
46
+ })
47
+
48
+ return watchlist_data
49
+
50
+ def optimize_portfolio(self, symbols: List[str], risk_tolerance: float = 0.5) -> Dict:
51
+ """Optimize portfolio allocation using quantum-inspired algorithm"""
52
+ # Fetch historical data for all symbols
53
+ data = {}
54
+ for symbol in symbols:
55
+ hist_data = fetch_stock_data(symbol, period='1y')
56
+ if hist_data is not None:
57
+ data[symbol] = hist_data['Close']
58
+
59
+ if not data:
60
+ return {'status': 'error', 'message': 'No data available for optimization'}
61
+
62
+ # Calculate returns
63
+ returns = pd.DataFrame(data).pct_change().dropna()
64
+
65
+ # Get optimal weights
66
+ weights = self.quantum_optimizer.optimize_portfolio(returns, risk_tolerance)
67
+
68
+ # Calculate portfolio metrics
69
+ portfolio_return = sum(weights[symbol] * returns[symbol].mean() for symbol in symbols)
70
+ portfolio_risk = np.sqrt(sum(sum(
71
+ weights[s1] * weights[s2] * returns[s1].cov(returns[s2])
72
+ for s2 in symbols) for s1 in symbols))
73
+
74
+ return {
75
+ 'status': 'success',
76
+ 'allocation': weights,
77
+ 'metrics': {
78
+ 'expected_return': portfolio_return * 100, # Convert to percentage
79
+ 'risk': portfolio_risk * 100, # Convert to percentage
80
+ 'sharpe_ratio': portfolio_return / portfolio_risk if portfolio_risk > 0 else 0
81
+ }
82
+ }
83
+
84
+ def analyze_portfolio(self, portfolio: Dict[str, float]) -> Dict:
85
+ """Analyze current portfolio performance and suggest rebalancing"""
86
+ symbols = list(portfolio.keys())
87
+ current_weights = list(portfolio.values())
88
+
89
+ # Get optimal weights
90
+ optimal_allocation = self.optimize_portfolio(symbols)
91
+
92
+ if optimal_allocation['status'] == 'error':
93
+ return optimal_allocation
94
+
95
+ # Compare current vs optimal allocation
96
+ rebalancing_needed = any(
97
+ abs(portfolio[symbol] - optimal_allocation['allocation'][symbol]) > 0.05
98
+ for symbol in symbols
99
+ )
100
+
101
+ return {
102
+ 'status': 'success',
103
+ 'current_allocation': portfolio,
104
+ 'optimal_allocation': optimal_allocation['allocation'],
105
+ 'metrics': optimal_allocation['metrics'],
106
+ 'rebalancing_needed': rebalancing_needed,
107
+ 'rebalancing_suggestions': {
108
+ symbol: optimal_allocation['allocation'][symbol] - portfolio[symbol]
109
+ for symbol in symbols
110
+ } if rebalancing_needed else {}
111
+ }
utils/quantum_algorithms.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from sklearn.preprocessing import MinMaxScaler
3
+ from typing import List, Dict, Tuple
4
+ import pandas as pd
5
+
6
+ class QuantumInspiredOptimizer:
7
+ def __init__(self, n_qubits=4, iterations=100):
8
+ self.n_qubits = n_qubits
9
+ self.iterations = iterations
10
+ self.scaler = MinMaxScaler()
11
+
12
+ def quantum_inspired_encoding(self, data):
13
+ """Convert classical data into quantum-inspired representation"""
14
+ scaled_data = self.scaler.fit_transform(data.reshape(-1, 1))
15
+ phase = 2 * np.pi * scaled_data
16
+ return np.exp(1j * phase)
17
+
18
+ def quantum_pattern_detection(self, prices):
19
+ """Detect patterns using quantum-inspired interference"""
20
+ encoded_data = self.quantum_inspired_encoding(prices)
21
+ amplitudes = np.abs(encoded_data)
22
+ phases = np.angle(encoded_data)
23
+
24
+ # Pattern detection through interference
25
+ interference_pattern = np.convolve(amplitudes.flatten(), np.exp(1j * phases.flatten()))
26
+ return np.abs(interference_pattern[:len(prices)])
27
+
28
+ def quantum_momentum_indicator(self, prices, window=14):
29
+ """Calculate quantum-inspired momentum indicator"""
30
+ encoded_data = self.quantum_inspired_encoding(prices)
31
+ momentum = np.zeros(len(prices))
32
+
33
+ for i in range(window, len(prices)):
34
+ quantum_state = encoded_data[i-window:i]
35
+ interference = np.sum(quantum_state * np.conjugate(quantum_state))
36
+ momentum[i] = np.abs(interference)
37
+
38
+ return momentum
39
+
40
+ def quantum_trend_prediction(self, prices, lookback=5):
41
+ """Predict trend using quantum-inspired algorithm"""
42
+ encoded_data = self.quantum_inspired_encoding(prices)
43
+ predictions = np.zeros(len(prices))
44
+
45
+ for i in range(lookback, len(prices)):
46
+ quantum_state = encoded_data[i-lookback:i]
47
+ superposition = np.sum(quantum_state) / np.sqrt(lookback)
48
+ predictions[i] = np.abs(superposition)
49
+
50
+ return self.scaler.inverse_transform(predictions.reshape(-1, 1)).flatten()
51
+
52
+ def optimize_portfolio(self, returns: pd.DataFrame, risk_tolerance: float = 0.5) -> Dict[str, float]:
53
+ """Quantum-inspired portfolio optimization"""
54
+ n_assets = returns.shape[1]
55
+
56
+ # Initialize quantum-inspired particles
57
+ n_particles = 100
58
+ particles = np.random.rand(n_particles, n_assets)
59
+ particles = particles / particles.sum(axis=1)[:, np.newaxis]
60
+
61
+ # Calculate returns and risks
62
+ portfolio_returns = np.dot(particles, returns.mean().values)
63
+ covariance = returns.cov().values
64
+ portfolio_risks = np.sqrt(np.diagonal(np.dot(np.dot(particles, covariance), particles.T)))
65
+
66
+ # Quantum interference optimization
67
+ for _ in range(self.iterations):
68
+ # Quantum phase estimation
69
+ phases = 2 * np.pi * (portfolio_returns - portfolio_risks * risk_tolerance)
70
+ quantum_states = np.exp(1j * phases.reshape(-1, 1))
71
+
72
+ # Interference effect
73
+ interference = np.sum(quantum_states * np.conjugate(quantum_states))
74
+ best_idx = np.argmax(np.abs(interference))
75
+
76
+ # Update particles
77
+ particles = particles * np.exp(1j * phases.reshape(-1, 1))
78
+ particles = np.abs(particles)
79
+ particles = particles / particles.sum(axis=1)[:, np.newaxis]
80
+
81
+ # Select best portfolio weights
82
+ best_weights = particles[best_idx]
83
+
84
+ return {
85
+ asset: weight for asset, weight in zip(returns.columns, best_weights)
86
+ }
87
+
88
+ def detect_quantum_patterns(self, prices: np.ndarray) -> List[Dict[str, any]]:
89
+ """Advanced pattern detection using quantum interference"""
90
+ encoded_data = self.quantum_inspired_encoding(prices)
91
+ patterns = []
92
+
93
+ # Sliding window analysis
94
+ window_sizes = [5, 10, 20]
95
+ for window in window_sizes:
96
+ for i in range(window, len(prices)):
97
+ quantum_state = encoded_data[i-window:i]
98
+ interference = np.sum(quantum_state * np.conjugate(quantum_state))
99
+
100
+ # Pattern strength and type detection
101
+ pattern_strength = np.abs(interference)
102
+ phase_coherence = np.angle(interference)
103
+
104
+ if pattern_strength > 1.5: # Significant pattern threshold
105
+ pattern_type = "Bullish" if phase_coherence > 0 else "Bearish"
106
+ patterns.append({
107
+ 'type': pattern_type,
108
+ 'strength': float(pattern_strength),
109
+ 'position': i,
110
+ 'window': window
111
+ })
112
+
113
+ return patterns
114
+
115
+ def quantum_risk_assessment(self, prices: np.ndarray, volumes: np.ndarray) -> Dict[str, float]:
116
+ """Quantum-inspired risk assessment"""
117
+ price_encoded = self.quantum_inspired_encoding(prices)
118
+ volume_encoded = self.quantum_inspired_encoding(volumes)
119
+
120
+ # Quantum interference between price and volume
121
+ interference = np.sum(price_encoded * np.conjugate(volume_encoded))
122
+
123
+ # Calculate risk metrics
124
+ volatility = np.std(prices) / np.mean(prices)
125
+ volume_impact = np.abs(interference) / len(prices)
126
+
127
+ return {
128
+ 'volatility': float(volatility),
129
+ 'volume_impact': float(volume_impact),
130
+ 'risk_score': float(np.sqrt(volatility * volume_impact))
131
+ }
utils/technical_indicators.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ def calculate_rsi(data, periods=14):
5
+ """Calculate Relative Strength Index"""
6
+ delta = data['Close'].diff()
7
+ gain = (delta.where(delta > 0, 0)).rolling(window=periods).mean()
8
+ loss = (-delta.where(delta < 0, 0)).rolling(window=periods).mean()
9
+ rs = gain / loss
10
+ return 100 - (100 / (1 + rs))
11
+
12
+ def calculate_macd(data):
13
+ """Calculate MACD"""
14
+ exp1 = data['Close'].ewm(span=12, adjust=False).mean()
15
+ exp2 = data['Close'].ewm(span=26, adjust=False).mean()
16
+ macd = exp1 - exp2
17
+ signal = macd.ewm(span=9, adjust=False).mean()
18
+ return macd, signal
19
+
20
+ def calculate_bollinger_bands(data, window=20):
21
+ """Calculate Bollinger Bands"""
22
+ sma = data['Close'].rolling(window=window).mean()
23
+ std = data['Close'].rolling(window=window).std()
24
+ upper_band = sma + (std * 2)
25
+ lower_band = sma - (std * 2)
26
+ return upper_band, sma, lower_band
27
+
28
+ def calculate_support_resistance(data, window=20):
29
+ """Calculate Support and Resistance levels"""
30
+ high_rolling = data['High'].rolling(window=window).max()
31
+ low_rolling = data['Low'].rolling(window=window).min()
32
+ return low_rolling, high_rolling