kaganseyda commited on
Commit
348ddaa
·
verified ·
1 Parent(s): 8961cfd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +434 -298
app.py CHANGED
@@ -1,336 +1,472 @@
 
 
 
 
1
  import gradio as gr
2
- import yfinance as yf
3
  import numpy as np
4
  import pandas as pd
5
- import json
6
- from scipy import signal
7
- from scipy.fft import fft, fftfreq
8
- from scipy.stats import norm, gaussian_kde
9
  import warnings
10
- from datetime import datetime, timedelta
11
- from skopt import gp_minimize
12
- from skopt.space import Real, Integer
13
- from skopt.utils import use_named_args
14
-
15
  warnings.filterwarnings('ignore')
16
 
17
- # ==============================================================================
18
- # 1. SİNYAL ÜRETİCİ (İŞÇİ)
19
- # Sadece verilen parametrelere göre sinyal üreten saf DSP modülü.
20
- # ==============================================================================
21
- class SpectralStockAnalyzer:
22
- def __init__(self, data, interval='1d'):
23
- self.data = data
24
- self.interval = interval
25
- self.filtered_prices = None
26
- self.momentum_signal = None
27
- self.volatility = self.calculate_volatility()
28
- self.adx = self.calculate_adx()
29
-
30
- def calculate_volatility(self, window=20):
31
- returns = self.data['Close'].pct_change()
32
- annualization_factor = 52 if self.interval == '1wk' else 252
33
- vol = returns.rolling(window=window).std() * np.sqrt(annualization_factor)
34
- return vol.fillna(method='bfill').fillna(method='ffill')
35
-
36
- def calculate_adx(self, lookback=14):
37
- high, low, close = self.data['High'], self.data['Low'], self.data['Close']
38
- tr = pd.concat([high - low, abs(high - close.shift()), abs(low - close.shift())], axis=1).max(axis=1)
39
- up_move, down_move = high - high.shift(), low.shift() - low
40
- plus_dm = pd.Series(np.where((up_move > down_move) & (up_move > 0), up_move, 0), index=self.data.index)
41
- minus_dm = pd.Series(np.where((down_move > up_move) & (down_move > 0), down_move, 0), index=self.data.index)
42
-
43
- atr = tr.rolling(window=lookback).mean()
44
- plus_di = 100 * (plus_dm.ewm(alpha=1/lookback, min_periods=lookback).mean() / atr)
45
- minus_di = 100 * (minus_dm.ewm(alpha=1/lookback, min_periods=lookback).mean() / atr)
46
 
47
- dx = 100 * (abs(plus_di - minus_di) / (plus_di + minus_di).replace(0, 1))
48
- adx = dx.ewm(alpha=1/lookback, min_periods=lookback).mean()
49
- return adx.fillna(20)
50
-
51
- def process_signal_chain(self, cutoff_freq, filter_order, momentum_thresh, price_thresh):
52
- # 1. Filtreleme
53
- prices = self.data['Close'].values
54
- nyquist = 0.5
55
- normalized_cutoff = max(0.01, min(cutoff_freq / nyquist, 0.99))
56
- b, a = signal.butter(int(filter_order), normalized_cutoff, btype='low')
57
- self.filtered_prices = signal.filtfilt(b, a, prices)
58
 
59
- # 2. Momentum Sinyali
60
- window_size=30
61
- momentum_values = []
62
- safe_window_size = min(window_size, len(self.filtered_prices) - 1)
63
- for i in range(safe_window_size, len(self.filtered_prices)):
64
- window_data = self.filtered_prices[i - safe_window_size:i]
65
- window_spectrum = fft(window_data)
66
- magnitude = np.abs(window_spectrum)
67
- dominant_idx = np.argmax(magnitude[1:]) + 1 if len(magnitude) > 1 else 0
68
- phase = np.angle(window_spectrum[dominant_idx])
69
- momentum = np.cos(phase)
70
- momentum_values.append(momentum)
71
- self.momentum_signal = np.concatenate([np.zeros(safe_window_size), np.array(momentum_values)])
72
-
73
- # 3. Alım Sinyallerini Tespit Et
74
- signals = []
75
- for i in range(5, len(self.momentum_signal)):
76
- if i >= len(self.filtered_prices) or i >= len(self.data): continue
77
 
78
- momentum_condition = (self.momentum_signal[i - 1] < momentum_thresh and
79
- self.momentum_signal[i] > self.momentum_signal[i - 1])
80
- recent_change = (self.filtered_prices[i] - self.filtered_prices[i - 5]) / self.filtered_prices[i - 5]
81
- price_condition = recent_change < price_thresh
 
 
82
 
83
- if momentum_condition and price_condition:
84
- signal_date = self.data.index[i]
85
- signals.append({
86
- 'date': signal_date,
87
- 'price': self.data['Close'].loc[signal_date],
88
- 'context': {
89
- 'volatility': self.volatility.loc[signal_date],
90
- 'adx': self.adx.loc[signal_date],
91
- 'momentum': self.momentum_signal[i]
92
- }
93
- })
94
- return signals
95
-
96
- # ==============================================================================
97
- # 2. ÖĞRENME MOTORU (ÖĞRETMEN)
98
- # Sinyalleri doğrular, başarılı olanların paternini öğrenir.
99
- # ==============================================================================
100
- class SignalFeedbackEngine:
101
- def __init__(self, full_data, interval='1d'):
102
- self.full_data = full_data
103
- self.interval = interval
104
- self.param_space = [
105
- Real(0.01, 0.25, name='cutoff_freq'), Integer(3, 6, name='filter_order'),
106
- Real(-0.9, -0.1, name='momentum_thresh'), Real(-0.15, -0.02, name='price_thresh')]
107
- self.successful_signal_profile = None
108
-
109
- def validate_signals(self, signals, forward_periods=20, success_threshold=0.01):
110
- validated = []
111
- for signal in signals:
112
- future_data = self.full_data.loc[signal['date']:]
113
- if len(future_data) > forward_periods:
114
- end_price = future_data['Close'].iloc[forward_periods]
115
- ret = (end_price - signal['price']) / signal['price']
116
- signal['outcome'] = {
117
- 'return': ret,
118
- 'is_success': ret > success_threshold
119
- }
120
- validated.append(signal)
121
- return validated
122
-
123
- def objective_function(self):
124
- @use_named_args(self.param_space)
125
- def evaluate_params(**params):
126
- analyzer = SpectralStockAnalyzer(self.full_data, self.interval)
127
- signals = analyzer.process_signal_chain(**params)
128
 
129
- if len(signals) < 5: return 10 # Çok az sinyal varsa cezalandır
130
-
131
- validated_signals = self.validate_signals(signals)
132
- if not validated_signals: return 10
133
-
134
- successes = [s for s in validated_signals if s['outcome']['is_success']]
 
 
 
135
 
136
- success_rate = len(successes) / len(validated_signals)
137
- if success_rate < 0.5: return 5 # Başarı oranı düşükse cezalandır
138
-
139
- # Başarılı sinyallerin ortalama getirisini ve riskini hesaba katan bir skor
140
- avg_success_return = np.mean([s['outcome']['return'] for s in successes]) if successes else 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
- # Kalite Skoru: Başarı oranı * Ortalama Getiri
143
- quality_score = success_rate * avg_success_return
144
 
145
- return -quality_score # Optimizasyon minimize ettiği için negatifini alıyoruz
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
- return evaluate_params
 
148
 
149
- def find_optimal_parameters(self):
150
- print("Finding optimal parameters based on historical signal quality...")
151
- objective = self.objective_function()
152
- result = gp_minimize(func=objective, dimensions=self.param_space, n_calls=40, random_state=42, n_jobs=-1)
153
-
154
- best_params = {dim.name: val for dim, val in zip(self.param_space, result.x)}
155
- print(f"Optimal parameters found with Quality Score: {-result.fun:.4f}")
156
- return best_params
157
-
158
- def learn_successful_signal_profile(self, optimal_params):
159
- print("Learning the DNA of successful signals...")
160
- analyzer = SpectralStockAnalyzer(self.full_data, self.interval)
161
- signals = analyzer.process_signal_chain(**optimal_params)
162
- validated_signals = self.validate_signals(signals)
163
-
164
- successes = [s for s in validated_signals if s['outcome']['is_success']]
165
- if len(successes) < 5:
166
- print("Not enough successful signals to build a reliable profile.")
167
- self.successful_signal_profile = None
168
- return
169
-
170
- # Başarılı sinyallerin bağlam (context) verilerini topla
171
- profile_data = {
172
- 'volatility': [s['context']['volatility'] for s in successes],
173
- 'adx': [s['context']['adx'] for s in successes]
174
- }
175
-
176
- # Olasılık yoğunluk fonksiyonları ile paterni öğren
177
- self.successful_signal_profile = {
178
- 'volatility_kde': gaussian_kde(profile_data['volatility']),
179
- 'adx_kde': gaussian_kde(profile_data['adx']),
180
- 'volatility_range': (np.min(profile_data['volatility']), np.max(profile_data['volatility'])),
181
- 'adx_range': (np.min(profile_data['adx']), np.max(profile_data['adx']))
182
- }
183
- print("Successful signal profile created.")
184
 
185
- def get_confidence_score(self, current_context):
186
- if not self.successful_signal_profile: return 0.5 # Profil yoksa nötr skor
187
 
188
- # Mevcut durum, başarılı paternin ne kadar "içinde"?
189
- # Yoğunluk fonksiyonundan olasılık alıyoruz
190
- vol_score = self.successful_signal_profile['volatility_kde'].evaluate([current_context['volatility']])[0]
191
- adx_score = self.successful_signal_profile['adx_kde'].evaluate([current_context['adx']])[0]
192
-
193
- # Skorları normalize etmek için maksimum yoğunluk değerlerini kullanabiliriz
194
- # Basitlik için, şimdilik aralık kontrolü yapalım
195
- norm_vol_score = np.interp(vol_score, [0, self.successful_signal_profile['volatility_kde'].pdf(self.successful_signal_profile['volatility_range']).max()], [0, 1])
196
- norm_adx_score = np.interp(adx_score, [0, self.successful_signal_profile['adx_kde'].pdf(self.successful_signal_profile['adx_range']).max()], [0, 1])
 
 
 
197
 
198
- # İki skorun ortalamasını alarak nihai güven skorunu oluştur
199
- confidence = (norm_vol_score + norm_adx_score) / 2
200
- return confidence
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
- # ==============================================================================
203
- # 3. ANA UYGULAMA VE ARAYÜZ
204
- # ==============================================================================
205
- def run_intelligent_analysis(stock_symbol, analysis_period, interval_choice):
206
- if not stock_symbol: return "Please enter a stock symbol!", "...", None
207
-
208
- interval_map = {"Günlük (Daily)": "1d", "Haftalık (Weekly)": "1wk"}
209
- interval = interval_map[interval_choice]
210
-
211
- try:
212
- ticker = yf.Ticker(stock_symbol.strip().upper())
213
- full_data = ticker.history(period=analysis_period, interval=interval)
214
- if len(full_data) < 150: return f"Insufficient data ({len(full_data)} points).", "...", None
215
 
216
- status_msg = f"Data fetched: {len(full_data)} points ({interval_choice})\n"
 
 
217
 
218
- # 1. Öğrenme
219
- engine = SignalFeedbackEngine(full_data, interval)
220
- optimal_params = engine.find_optimal_parameters()
221
- engine.learn_successful_signal_profile(optimal_params)
222
- status_msg += "Learning from historical signals complete.\n"
 
 
 
 
 
 
 
 
223
 
224
- # 2. Canlı Analiz
225
- analyzer = SpectralStockAnalyzer(full_data, interval)
226
- all_signals = analyzer.process_signal_chain(**optimal_params)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
- current_signal = None
229
- # Son 5 gün içinde sinyal var mı diye kontrol et
230
- if all_signals and (full_data.index[-1] - all_signals[-1]['date']).days < 5:
231
- current_signal = all_signals[-1]
232
- status_msg += "Potential signal detected in the current period.\n"
 
 
 
 
233
  else:
234
- status_msg += "No active signal in the current period.\n"
235
-
236
- # 3. Raporlama
237
- # ... Rapor ve JSON oluşturma ...
238
- results = f"## INTELLIGENT ANALYSIS REPORT: {stock_symbol.upper()}\n"
239
- results += "### Step 1: Learning from Past Performance\n"
240
- results += f"The model analyzed past data to find parameters that maximize **Signal Quality Score** (Success Rate × Avg. Return).\n"
241
- results += "**Optimal Parameters Found:**\n"
242
- for key, val in optimal_params.items():
243
- results += f"- **{key.replace('_', ' ').title()}:** {val:.4f}\n"
244
-
245
- if engine.successful_signal_profile:
246
- vol_range = engine.successful_signal_profile['volatility_range']
247
- adx_range = engine.successful_signal_profile['adx_range']
248
- results += "\n**Learned Profile of a 'Good' Signal (DNA):**\n"
249
- results += f"- **Optimal Volatility Range:** {vol_range[0]:.2f} - {vol_range[1]:.2f}\n"
250
- results += f"- **Optimal ADX (Trend Strength) Range:** {adx_range[0]:.1f} - {adx_range[1]:.1f}\n"
251
-
252
- results += "\n### Step 2: Current Market Analysis\n"
253
- if current_signal:
254
- confidence = engine.get_confidence_score(current_signal['context'])
255
- current_signal['confidence_score'] = confidence
256
-
257
- color = "green" if confidence > 0.7 else "orange" if confidence > 0.5 else "red"
258
-
259
- results += f"**POTENTIAL BUY SIGNAL DETECTED** on {current_signal['date'].strftime('%Y-%m-%d')}\n"
260
- results += f"> **Confidence Score:** <span style='color:{color}; font-weight:bold;'>{confidence:.1%}</span>\n"
261
- results += f"> This score indicates how closely the current market conditions match the DNA of historical successful signals.\n\n"
262
- results += "**Current Market Context:**\n"
263
- results += f"- **Volatility:** {current_signal['context']['volatility']:.2f} (Historical sweet spot: {vol_range[0]:.2f}-{vol_range[1]:.2f})\n"
264
- results += f"- **ADX:** {current_signal['context']['adx']:.1f} (Historical sweet spot: {adx_range[0]:.1f}-{adx_range[1]:.1f})\n"
265
  else:
266
- results += "**No active buy signal detected in the last 5 periods.** The model is waiting for market conditions to align with its learned success profile.\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
- # JSON oluşturma
269
- json_output = {
270
- "symbol": stock_symbol.upper(),
271
- "analysis_timestamp": datetime.now().isoformat(),
272
- "optimal_parameters": optimal_params,
273
- "learned_profile": {
274
- 'volatility_range': engine.successful_signal_profile['volatility_range'] if engine.successful_signal_profile else None,
275
- 'adx_range': engine.successful_signal_profile['adx_range'] if engine.successful_signal_profile else None
276
- },
277
- "current_signal": current_signal,
278
- "historical_signals_with_optimal_params": all_signals
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  }
 
 
280
 
281
- # Datetime ve numpy türlerini serileştirilebilir hale getir
282
- def json_converter(o):
283
- if isinstance(o, (datetime, pd.Timestamp)): return o.isoformat()
284
- if isinstance(o, (np.integer, np.int64)): return int(o)
285
- if isinstance(o, (np.floating, np.float64)): return float(o)
286
- if isinstance(o, np.ndarray): return o.tolist()
287
- if np.isnan(o): return None
288
- return o
289
-
290
- return status_msg, results, json.dumps(json_output, default=json_converter, indent=2)
291
-
292
- except Exception as e:
293
- import traceback
294
- return f"An error occurred: {e}\n{traceback.format_exc()}", "...", None
295
-
296
-
297
- def create_interface():
298
- with gr.Blocks(theme=gr.themes.Soft(), title="Intelligent Spectral Analysis") as demo:
299
- gr.HTML("""<div style="text-align: center; background: linear-gradient(90deg, #1A2980 0%, #26D0CE 100%); color: white; padding: 25px; border-radius: 8px;">
300
- <h1>Intelligent Spectral Analyzer</h1>
301
- <p>Self-Learning Quantitative Model with Signal Feedback & Pattern Recognition</p>
302
- </div>""")
303
 
304
  with gr.Row():
305
  with gr.Column(scale=1):
306
- stock_input = gr.Textbox(label="Stock Symbol", placeholder="e.g., NVDA, GOOGL, TSLA")
307
- period_input = gr.Dropdown(label="Analysis Period", choices=["1y", "2y", "5y", "10y"], value="5y")
308
- interval_input = gr.Dropdown(label="Analysis Interval", choices=["Günlük (Daily)", "Haftalık (Weekly)"], value="Günlük (Daily)")
309
- analyze_btn = gr.Button("START INTELLIGENT ANALYSIS", variant="primary")
310
- status_output = gr.Textbox(label="Process Log", interactive=False, lines=15)
311
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  with gr.Column(scale=2):
313
- results_output = gr.Markdown(value="Analysis report will appear here...")
314
- with gr.Accordion("Show Raw JSON Output for Integration", open=False):
315
- json_output_display = gr.JSON(label="JSON Data")
316
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  analyze_btn.click(
318
- fn=run_intelligent_analysis,
319
- inputs=[stock_input, period_input, interval_input],
320
- outputs=[status_output, results_output, json_output_display]
321
  )
322
-
323
- gr.HTML("""<div style="margin-top: 20px; padding: 15px; background-color: #f2f2f2; border-radius: 8px;">
324
- <h4>How It Works (Self-Learning Logic):</h4>
325
- <ol>
326
- <li><strong>Historical Simulation:</strong> The model runs its DSP strategy on past data with many different parameter sets.</li>
327
- <li><strong>Signal Validation:</strong> It checks the outcome of every historical signal it generated. Signals that led to profit are marked 'Successful'.</li>
328
- <li><strong>Pattern Recognition (Learning):</strong> It analyzes all 'Successful' signals to find their common characteristics (the "DNA"). What was the market volatility and trend strength like when they occurred?</li>
329
- <li><strong>Intelligent Prediction:</strong> It uses the parameters that produced the best historical signals to analyze the current market. If a new signal appears, it's compared against the learned 'DNA' to generate a final <strong>Confidence Score</strong>.</li>
330
- </ol>
331
- </div>""")
332
  return demo
333
 
 
334
  if __name__ == "__main__":
335
- demo = create_interface()
336
- demo.launch(share=True)
 
 
 
 
 
 
1
+ """
2
+ Professional Quantitative Finance Analysis Platform
3
+ Hugging Face Gradio Application
4
+ """
5
  import gradio as gr
6
+ import json
7
  import numpy as np
8
  import pandas as pd
9
+ from datetime import datetime
 
 
 
10
  import warnings
 
 
 
 
 
11
  warnings.filterwarnings('ignore')
12
 
13
+ # Import custom modules
14
+ from src.data_fetcher import DataFetcher
15
+ from src.spectral_analyzer import SpectralAnalyzer
16
+ from src.bayesian_engine import BayesianAnalyzer
17
+ from src.monte_carlo import MonteCarloEngine
18
+ from src.pattern_recognition import PatternRecognizer
19
+ from src.ml_models import MLMomentumPredictor
20
+ from src.visualization import Visualizer
21
+ from src.pdf_report import PDFReportGenerator
22
+ from src.config import config, TIMEFRAMES
23
+
24
+ class QuantitativeAnalysisPlatform:
25
+ """Main analysis platform orchestrating all modules"""
26
+
27
+ def __init__(self):
28
+ self.data_fetcher = DataFetcher()
29
+ self.spectral_analyzer = SpectralAnalyzer()
30
+ self.bayesian_analyzer = BayesianAnalyzer()
31
+ self.mc_engine = MonteCarloEngine()
32
+ self.pattern_recognizer = PatternRecognizer()
33
+ self.ml_predictor = MLMomentumPredictor(model_type='xgboost')
34
+ self.visualizer = Visualizer()
 
 
 
 
 
 
 
35
 
36
+ def run_complete_analysis(
37
+ self,
38
+ symbol: str,
39
+ timeframe: str = '1d',
40
+ period: str = '2y'
41
+ ):
42
+ """
43
+ Execute comprehensive analysis pipeline
 
 
 
44
 
45
+ Returns:
46
+ Tuple of (html_charts, status_message, results_markdown, pdf_path)
47
+ """
48
+ try:
49
+ status_log = []
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
+ # 1. Fetch Data
52
+ status_log.append(f"📊 Fetching {symbol} data ({timeframe} interval)...")
53
+ success, msg = self.data_fetcher.fetch_data(symbol, timeframe, period)
54
+ if not success:
55
+ return None, f"❌ {msg}", "", None
56
+ status_log.append(f"✅ {msg}")
57
 
58
+ # 2. Spectral Analysis (Multi-Frequency)
59
+ status_log.append("🔬 Performing multi-frequency spectral analysis...")
60
+ prices = self.data_fetcher.get_clean_prices()
61
+ spectral_results = self.spectral_analyzer.analyze(prices)
62
+ status_log.append(f"✅ Analyzed {len(spectral_results)} frequency bands")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
+ # 3. Pattern Recognition
65
+ status_log.append("🎯 Detecting technical patterns...")
66
+ ohlc = self.data_fetcher.get_ohlcv()
67
+ candlestick_patterns = self.pattern_recognizer.detect_candlestick_patterns(ohlc)
68
+ chart_patterns = self.pattern_recognizer.detect_chart_patterns(
69
+ prices, self.data_fetcher.data.index
70
+ )
71
+ status_log.append(f"✅ Found {len(candlestick_patterns)} candlestick patterns, "
72
+ f"{len(chart_patterns)} chart patterns")
73
 
74
+ # 4. ML-Based Prediction (Self-Supervised)
75
+ status_log.append("🤖 Training ML models with self-supervised learning...")
76
+ X, y = self.ml_predictor.prepare_features(self.data_fetcher.data)
77
+ ml_metrics = self.ml_predictor.self_supervised_training(X, y, optimize_params=True)
78
+ status_log.append(f"✅ ML Model R²: {ml_metrics['final_r2']:.3f}")
79
+
80
+ # 5. Monte Carlo Simulations
81
+ status_log.append("🎲 Running Monte Carlo simulations (10,000+ paths)...")
82
+ returns = self.data_fetcher.get_returns()
83
+ current_price = prices[-1]
84
+ mc_results = self.mc_engine.simulate_all_models(
85
+ current_price, returns, T=30, n_sims=10000
86
+ )
87
+ status_log.append(f"✅ Completed {len(mc_results)} Monte Carlo models")
88
+
89
+ # 6. Bayesian Analysis
90
+ status_log.append("📈 Performing Bayesian inference...")
91
+ volatility = self.data_fetcher.calculate_volatility().iloc[-1]
92
+ adx_value = 25.0 # Simplified - would calculate actual ADX
93
+ regime_probs = self.bayesian_analyzer.estimate_regime_probabilities(
94
+ volatility, adx_value, returns[-50:]
95
+ )
96
+ status_log.append(f"✅ Estimated market regime probabilities")
97
+
98
+ # 7. Calculate Multi-Band Momentum
99
+ status_log.append("⚡ Calculating multi-frequency momentum signals...")
100
+ momentum_signals = self.spectral_analyzer.get_multi_band_momentum(window_size=30)
101
+ composite_momentum = self.spectral_analyzer.get_composite_momentum(window_size=30)
102
+ status_log.append("✅ Generated momentum signals for all frequency bands")
103
+
104
+ # 8. Generate Visualizations
105
+ status_log.append("📊 Creating interactive visualizations...")
106
+ mc_stats = {}
107
+ for model_name in ['gbm', 'jump_diffusion', 'garch', 'heston']:
108
+ if model_name in mc_results:
109
+ mc_stats[model_name] = self.mc_engine.calculate_statistics(model_name)
110
+
111
+ # Generate comprehensive dashboard
112
+ fig = self.visualizer.create_comprehensive_dashboard(
113
+ self.data_fetcher.data,
114
+ spectral_results,
115
+ mc_results,
116
+ {}, # ML predictions placeholder
117
+ candlestick_patterns + chart_patterns
118
+ )
119
+
120
+ # Save to HTML
121
+ html_path = f"analysis_{symbol}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
122
+ self.visualizer.export_to_html(fig, html_path)
123
+ status_log.append(f"✅ Generated interactive charts: {html_path}")
124
+
125
+ # 9. Generate PDF Report
126
+ status_log.append("📄 Generating comprehensive PDF report...")
127
+ pdf_gen = PDFReportGenerator()
128
+
129
+ pdf_gen.add_title_page(symbol, datetime.now().strftime('%Y-%m-%d'))
130
+
131
+ pdf_gen.add_executive_summary({
132
+ 'current_price': current_price,
133
+ 'market_regime': self.data_fetcher.detect_market_regime(),
134
+ 'volatility': volatility,
135
+ 'momentum_status': 'Positive' if composite_momentum[-1] > 0 else 'Negative',
136
+ 'ml_r2': ml_metrics['final_r2']
137
+ })
138
+
139
+ pdf_gen.add_frequency_analysis(spectral_results)
140
+ pdf_gen.add_monte_carlo_results(mc_stats)
141
+ pdf_gen.add_bayesian_analysis({'regime_probabilities': regime_probs})
142
+ pdf_gen.add_pattern_detection(candlestick_patterns + chart_patterns)
143
+
144
+ pdf_path = pdf_gen.generate()
145
+ status_log.append(f"✅ PDF report generated: {pdf_path}")
146
+
147
+ # 10. Prepare Results Markdown
148
+ results_md = self._generate_results_markdown(
149
+ symbol,
150
+ spectral_results,
151
+ mc_stats,
152
+ regime_probs,
153
+ ml_metrics,
154
+ candlestick_patterns,
155
+ chart_patterns,
156
+ composite_momentum
157
+ )
158
+
159
+ status_message = "\n".join(status_log)
160
+
161
+ # Return HTML chart
162
+ with open(html_path, 'r') as f:
163
+ html_content = f.read()
164
 
165
+ return html_content, status_message, results_md, pdf_path
 
166
 
167
+ except Exception as e:
168
+ return None, f"❌ Analysis error: {str(e)}", "", None
169
+
170
+ def _generate_results_markdown(
171
+ self,
172
+ symbol,
173
+ spectral_results,
174
+ mc_stats,
175
+ regime_probs,
176
+ ml_metrics,
177
+ candlestick_patterns,
178
+ chart_patterns,
179
+ composite_momentum
180
+ ):
181
+ """Generate detailed results in markdown format"""
182
 
183
+ md = f"""
184
+ # 📊 Professional Quantitative Analysis Report: {symbol}
185
 
186
+ ## 🎯 Executive Summary
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
+ **Analysis Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
 
189
 
190
+ **Current Market Assessment:**
191
+ - **Composite Momentum:** {composite_momentum[-1]:.4f}
192
+ - **Momentum Direction:** {'📈 Bullish' if composite_momentum[-1] > 0 else '📉 Bearish'}
193
+ - **ML Model Performance:** R² = {ml_metrics['final_r2']:.3f}
194
+
195
+ ---
196
+
197
+ ## 🔬 Multi-Frequency Spectral Analysis
198
+
199
+ Analysis across Low, Mid, and High frequency bands reveals dominant market cycles:
200
+
201
+ """
202
 
203
+ for band_name, result in spectral_results.items():
204
+ band_config = result['band_config']
205
+ dominant_freqs = result['dominant_frequencies']
206
+
207
+ md += f"""
208
+ ### {band_config.name}
209
+
210
+ **Period Range:** {band_config.min_period:.0f} - {band_config.max_period:.0f} days
211
+
212
+ **Dominant Cycles:**
213
+
214
+ """
215
+ for i, freq in enumerate(dominant_freqs[:3], 1):
216
+ md += f"""
217
+ {i}. **Period: {freq['period_days']:.1f} days**
218
+ - Frequency: {freq['frequency']:.4f} cycles/day
219
+ - Amplitude: {freq['amplitude']:.0f}
220
+ - Statistical Significance: {freq['significance']:.1%}
221
+ - Z-Score: {freq['z_score']:.2f}
222
+
223
+ """
224
 
225
+ md += f"""
226
+ ---
227
+
228
+ ## 🎲 Monte Carlo Simulation Results ({config.MC_SIMULATIONS:,} simulations)
 
 
 
 
 
 
 
 
 
229
 
230
+ Probabilistic price forecasts over {config.MC_TIME_HORIZON} days:
231
+
232
+ """
233
 
234
+ for model_name, stats in mc_stats.items():
235
+ md += f"""
236
+ ### {model_name.upper().replace('_', ' ')} Model
237
+
238
+ - **Expected Price:** ${stats['mean_final_price']:.2f}
239
+ - **Median Price:** ${stats['median_final_price']:.2f}
240
+ - **95% Confidence Interval:** ${stats['percentile_5']:.2f} - ${stats['percentile_95']:.2f}
241
+ - **Probability of Profit:** {stats['prob_profit']:.1%}
242
+ - **Expected Return:** {stats['expected_return']:.2%}
243
+ - **Value at Risk (95%):** ${stats['var_95']:.2f}
244
+ - **Conditional VaR (95%):** ${stats['cvar_95']:.2f}
245
+
246
+ """
247
 
248
+ md += f"""
249
+ ---
250
+
251
+ ## 📈 Bayesian Market Regime Analysis
252
+
253
+ **Estimated Regime Probabilities:**
254
+
255
+ - **Range-Bound Market:** {regime_probs.get('range_bound', 0):.1%}
256
+ - **Trending Market:** {regime_probs.get('trending', 0):.1%}
257
+ - **High Volatility Regime:** {regime_probs.get('high_volatility', 0):.1%}
258
+
259
+ ---
260
+
261
+ ## 🤖 Machine Learning Performance
262
+
263
+ **Self-Supervised Learning Results:**
264
+
265
+ - **Average MSE (Cross-Validation):** {ml_metrics['avg_mse']:.6f}
266
+ - **Average MAE:** {ml_metrics['avg_mae']:.6f}
267
+ - **Average R² Score:** {ml_metrics['avg_r2']:.3f}
268
+ - **Final R² Score:** {ml_metrics['final_r2']:.3f}
269
+
270
+ Model continuously learns from past predictions to improve accuracy.
271
+
272
+ ---
273
+
274
+ ## 🎯 Pattern Recognition Results
275
+
276
+ """
277
 
278
+ if candlestick_patterns:
279
+ md += f"""
280
+ ### Candlestick Patterns ({len(candlestick_patterns)} detected)
281
+
282
+ Recent patterns:
283
+
284
+ """
285
+ for pattern in candlestick_patterns[-5:]:
286
+ md += f"- **{pattern['pattern']}** on {pattern['date']} - Signal: {pattern['signal']}\n"
287
  else:
288
+ md += "\n### Candlestick Patterns\n\nNo significant candlestick patterns detected.\n"
289
+
290
+ if chart_patterns:
291
+ md += f"""
292
+
293
+ ### Chart Patterns ({len(chart_patterns)} detected)
294
+
295
+ """
296
+ for pattern in chart_patterns:
297
+ md += f"- **{pattern['pattern']}** - Signal: {pattern['signal']}\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  else:
299
+ md += "\n### Chart Patterns\n\nNo chart patterns detected.\n"
300
+
301
+ md += """
302
+
303
+ ---
304
+
305
+ ## ⚠️ Risk Disclosure
306
+
307
+ This analysis is for **educational and informational purposes only**. It does NOT constitute:
308
+ - Financial advice
309
+ - Investment recommendations
310
+ - An offer to buy or sell securities
311
+
312
+ **Key Limitations:**
313
+ - Models are based on historical data and assumptions
314
+ - Past performance does not guarantee future results
315
+ - All investments carry risk, including potential loss of principal
316
+ - Market conditions can change rapidly and unexpectedly
317
+
318
+ **Always consult with a qualified financial advisor before making investment decisions.**
319
+
320
+ ---
321
+
322
+ ## 🔧 Technical Details
323
+
324
+ **Analysis Configuration:**
325
+ - Bayesian MCMC Draws: {config.BAYESIAN_DRAWS:,}
326
+ - Monte Carlo Simulations: {config.MC_SIMULATIONS:,}
327
+ - ML Cross-Validation Splits: {config.ML_VALIDATION_SPLITS}
328
+ - Frequency Bands Analyzed: {len(config.FREQUENCY_BANDS)}
329
+
330
+ **Powered by:**
331
+ - PyMC (Bayesian Inference)
332
+ - XGBoost/LightGBM (Machine Learning)
333
+ - SciPy (Signal Processing)
334
+ - Plotly (Interactive Visualizations)
335
+ """
336
 
337
+ return md
338
+
339
+
340
+ def create_gradio_interface():
341
+ """Create Gradio UI"""
342
+
343
+ platform = QuantitativeAnalysisPlatform()
344
+
345
+ def analyze_wrapper(symbol, timeframe, period):
346
+ """Wrapper for Gradio"""
347
+ html, status, results, pdf = platform.run_complete_analysis(symbol, timeframe, period)
348
+ return html, status, results, pdf
349
+
350
+ with gr.Blocks(
351
+ theme=gr.themes.Soft(),
352
+ title="Professional Quantitative Finance Platform",
353
+ css="""
354
+ .main-header {
355
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
356
+ color: white;
357
+ padding: 30px;
358
+ border-radius: 10px;
359
+ text-align: center;
360
+ margin-bottom: 30px;
361
+ box-shadow: 0 10px 30px rgba(0,0,0,0.2);
362
+ }
363
+ .feature-box {
364
+ background: #f8f9fa;
365
+ padding: 20px;
366
+ border-radius: 8px;
367
+ border-left: 4px solid #667eea;
368
+ margin: 10px 0;
369
  }
370
+ """
371
+ ) as demo:
372
 
373
+ gr.HTML("""
374
+ <div class="main-header">
375
+ <h1>🚀 Professional Quantitative Finance Analysis Platform</h1>
376
+ <p style="font-size: 18px; margin-top: 10px;">
377
+ Multi-Frequency Spectral Analysis Bayesian Inference • Monte Carlo Simulation<br/>
378
+ Machine Learning Pattern Recognition • Comprehensive Reporting
379
+ </p>
380
+ </div>
381
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
382
 
383
  with gr.Row():
384
  with gr.Column(scale=1):
385
+ gr.HTML("<h3>⚙️ Analysis Configuration</h3>")
386
+
387
+ symbol_input = gr.Textbox(
388
+ label="Stock Symbol",
389
+ placeholder="AAPL, MSFT, GOOGL, TSLA...",
390
+ value="AAPL"
391
+ )
392
+
393
+ timeframe_input = gr.Dropdown(
394
+ label="Time Interval",
395
+ choices=['1d', '1h', '15m', '5m'],
396
+ value='1d',
397
+ info="Select data granularity"
398
+ )
399
+
400
+ period_input = gr.Dropdown(
401
+ label="Historical Period",
402
+ choices=['1mo', '3mo', '6mo', '1y', '2y', '5y'],
403
+ value='2y',
404
+ info="Amount of historical data to analyze"
405
+ )
406
+
407
+ analyze_btn = gr.Button(
408
+ "🚀 START COMPREHENSIVE ANALYSIS",
409
+ variant="primary",
410
+ size="lg"
411
+ )
412
+
413
+ status_output = gr.Textbox(
414
+ label="Analysis Status",
415
+ lines=15,
416
+ interactive=False
417
+ )
418
+
419
  with gr.Column(scale=2):
420
+ gr.HTML("<h3>📊 Interactive Visualizations</h3>")
421
+ charts_output = gr.HTML(
422
+ value="<div style='text-align: center; padding: 50px; color: #666;'>"
423
+ "Interactive charts will appear here after analysis</div>"
424
+ )
425
+
426
+ gr.HTML("<hr style='margin: 30px 0;'>")
427
+
428
+ with gr.Row():
429
+ with gr.Column():
430
+ results_output = gr.Markdown(
431
+ value="Detailed analysis results will appear here..."
432
+ )
433
+
434
+ gr.HTML("<hr style='margin: 30px 0;'>")
435
+
436
+ with gr.Row():
437
+ pdf_output = gr.File(
438
+ label="📄 Download Comprehensive PDF Report",
439
+ interactive=False
440
+ )
441
+
442
+ gr.HTML("""
443
+ <div class="feature-box">
444
+ <h3>🎯 Advanced Features</h3>
445
+ <ul>
446
+ <li><strong>Multi-Frequency Decomposition:</strong> Separate analysis of low, mid, and high frequency components</li>
447
+ <li><strong>Self-Supervised Learning:</strong> ML models that learn from past predictions</li>
448
+ <li><strong>Bayesian Inference:</strong> Probabilistic market regime detection and parameter optimization</li>
449
+ <li><strong>Monte Carlo Simulation:</strong> Multiple stochastic models (GBM, Jump Diffusion, GARCH, Heston)</li>
450
+ <li><strong>Pattern Recognition:</strong> Technical patterns + ML-based clustering with DTW</li>
451
+ <li><strong>Professional Reporting:</strong> Interactive HTML dashboards + comprehensive PDF reports</li>
452
+ </ul>
453
+ </div>
454
+ """)
455
+
456
  analyze_btn.click(
457
+ fn=analyze_wrapper,
458
+ inputs=[symbol_input, timeframe_input, period_input],
459
+ outputs=[charts_output, status_output, results_output, pdf_output]
460
  )
461
+
 
 
 
 
 
 
 
 
 
462
  return demo
463
 
464
+
465
  if __name__ == "__main__":
466
+ demo = create_gradio_interface()
467
+ demo.launch(
468
+ server_name="0.0.0.0",
469
+ server_port=7860,
470
+ share=True,
471
+ show_error=True
472
+ )