kaganseyda commited on
Commit
fc3352e
·
verified ·
1 Parent(s): cac0e86

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -508
app.py CHANGED
@@ -1,523 +1,181 @@
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
- from typing import Dict, List
11
- import warnings
12
- warnings.filterwarnings('ignore')
13
-
14
- # Import custom modules
15
- from src.data_fetcher import DataFetcher
16
- from src.spectral_analyzer import SpectralAnalyzer
17
- from src.bayesian_engine import BayesianAnalyzer
18
- from src.monte_carlo import MonteCarloEngine
19
- from src.pattern_recognition import PatternRecognizer
20
- from src.ml_models import MLMomentumPredictor
21
- from src.visualization import Visualizer
22
- from src.pdf_report import PDFReportGenerator
23
- from src.config import config, TIMEFRAMES
24
- import plotly.graph_objects as go
25
-
26
- class QuantitativeAnalysisPlatform:
27
- """Main analysis platform orchestrating all modules"""
 
 
 
 
 
 
28
 
29
- def __init__(self):
30
- self.data_fetcher = DataFetcher()
31
- self.spectral_analyzer = SpectralAnalyzer()
32
- self.bayesian_analyzer = BayesianAnalyzer()
33
- self.mc_engine = MonteCarloEngine()
34
- self.pattern_recognizer = PatternRecognizer()
35
- self.ml_predictor = MLMomentumPredictor(model_type='xgboost')
36
- self.visualizer = Visualizer()
37
-
38
- def run_complete_analysis(
39
- self,
40
- symbol: str,
41
- timeframe: str = '1d',
42
- period: str = '2y'
43
- ):
44
- """
45
- Execute comprehensive analysis pipeline
46
 
47
- Returns:
48
- Tuple of (html_charts, status_message, results_markdown, pdf_path)
49
- """
50
- try:
51
- status_log = []
52
-
53
- # 1. Fetch Data
54
- status_log.append(f"📊 Fetching {symbol} data ({timeframe} interval)...")
55
- success, msg = self.data_fetcher.fetch_data(symbol, timeframe, period)
56
- if not success:
57
- return None, f"❌ {msg}", "", None
58
- status_log.append(f"✅ {msg}")
59
-
60
- # 2. Spectral Analysis (Multi-Frequency)
61
- status_log.append("🔬 Performing multi-frequency spectral analysis...")
62
- prices = self.data_fetcher.get_clean_prices()
63
- spectral_results = self.spectral_analyzer.analyze(prices)
64
- status_log.append(f"✅ Analyzed {len(spectral_results)} frequency bands")
65
-
66
- # 3. Pattern Recognition
67
- status_log.append("🎯 Detecting technical patterns...")
68
- ohlc = self.data_fetcher.get_ohlcv()
69
- candlestick_patterns = self.pattern_recognizer.detect_candlestick_patterns(ohlc)
70
- chart_patterns = self.pattern_recognizer.detect_chart_patterns(
71
- prices, self.data_fetcher.data.index
72
- )
73
- status_log.append(f"✅ Found {len(candlestick_patterns)} candlestick patterns, "
74
- f"{len(chart_patterns)} chart patterns")
75
-
76
- # 4. ML-Based Prediction (Self-Supervised)
77
- status_log.append("🤖 Training ML models with self-supervised learning...")
78
- X, y = self.ml_predictor.prepare_features(self.data_fetcher.data)
79
- ml_metrics = self.ml_predictor.self_supervised_training(X, y, optimize_params=True)
80
- status_log.append(f"✅ ML Model R²: {ml_metrics['final_r2']:.3f}")
81
-
82
- # 5. Monte Carlo Simulations
83
- status_log.append("🎲 Running Monte Carlo simulations (10,000+ paths)...")
84
- returns = self.data_fetcher.get_returns()
85
- current_price = prices[-1]
86
- mc_results = self.mc_engine.simulate_all_models(
87
- current_price, returns, T=30, n_sims=10000
88
- )
89
- status_log.append(f"✅ Completed {len(mc_results)} Monte Carlo models")
90
-
91
- # 6. Bayesian Analysis
92
- status_log.append("📈 Performing Bayesian inference...")
93
- volatility = self.data_fetcher.calculate_volatility().iloc[-1]
94
- adx_value = 25.0 # Simplified - would calculate actual ADX
95
- regime_probs = self.bayesian_analyzer.estimate_regime_probabilities(
96
- volatility, adx_value, returns[-50:]
97
- )
98
- status_log.append(f"✅ Estimated market regime probabilities")
99
-
100
- # 7. Calculate Multi-Band Momentum
101
- status_log.append("⚡ Calculating multi-frequency momentum signals...")
102
- momentum_signals = self.spectral_analyzer.get_multi_band_momentum(window_size=30)
103
- composite_momentum = self.spectral_analyzer.get_composite_momentum(window_size=30)
104
- status_log.append("✅ Generated momentum signals for all frequency bands")
105
-
106
- # 8. Generate Visualizations
107
- status_log.append("📊 Creating interactive visualizations...")
108
- mc_stats = {}
109
- for model_name in ['gbm', 'jump_diffusion', 'garch', 'heston']:
110
- if model_name in mc_results:
111
- mc_stats[model_name] = self.mc_engine.calculate_statistics(model_name)
112
-
113
- # Detect buy signals from momentum
114
- buy_signals = self._detect_buy_signals_from_momentum(
115
- composite_momentum, prices, self.data_fetcher.data.index
116
- )
117
-
118
- # Generate all charts
119
- charts = self.visualizer.create_comprehensive_dashboard(
120
- dates=self.data_fetcher.data.index,
121
- original_prices=prices,
122
- spectral_results=spectral_results,
123
- momentum_signals=momentum_signals,
124
- mc_results=mc_results,
125
- buy_signals=buy_signals,
126
- current_price=current_price
127
- )
128
-
129
- # Save to HTML
130
- html_path = f"analysis_{symbol}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
131
- self.visualizer.export_to_html(charts, html_path)
132
- status_log.append(f"✅ Generated {len(charts)} interactive charts: {html_path}")
133
-
134
- # 9. Generate PDF Report
135
- status_log.append("📄 Generating comprehensive PDF report...")
136
- pdf_gen = PDFReportGenerator()
137
-
138
- pdf_gen.add_title_page(symbol, datetime.now().strftime('%Y-%m-%d'))
139
-
140
- pdf_gen.add_executive_summary({
141
- 'current_price': current_price,
142
- 'market_regime': self.data_fetcher.detect_market_regime(),
143
- 'volatility': volatility,
144
- 'momentum_status': 'Positive' if composite_momentum[-1] > 0 else 'Negative',
145
- 'ml_r2': ml_metrics['final_r2']
146
- })
147
-
148
- pdf_gen.add_frequency_analysis(spectral_results)
149
- pdf_gen.add_monte_carlo_results(mc_stats)
150
- pdf_gen.add_bayesian_analysis({'regime_probabilities': regime_probs})
151
- pdf_gen.add_pattern_detection(candlestick_patterns + chart_patterns)
152
-
153
- pdf_path = pdf_gen.generate()
154
- status_log.append(f"✅ PDF report generated: {pdf_path}")
155
-
156
- # 10. Prepare Results Markdown
157
- results_md = self._generate_results_markdown(
158
- symbol,
159
- spectral_results,
160
- mc_stats,
161
- regime_probs,
162
- ml_metrics,
163
- candlestick_patterns,
164
- chart_patterns,
165
- composite_momentum,
166
- buy_signals
167
- )
168
-
169
- status_message = "\n".join(status_log)
170
-
171
- # Return charts as HTML embeds for Gradio
172
- charts_html = self._create_gradio_html(charts)
173
-
174
- return charts_html, status_message, results_md, pdf_path
175
-
176
- except Exception as e:
177
- import traceback
178
- error_detail = traceback.format_exc()
179
- return None, f"❌ Analysis error: {str(e)}\n\n{error_detail}", "", None
180
 
181
- def _detect_buy_signals_from_momentum(
182
- self,
183
- composite_momentum: np.ndarray,
184
- prices: np.ndarray,
185
- dates: pd.DatetimeIndex
186
- ) -> List[Dict]:
187
- """Detect buy signals from momentum crossovers"""
188
- signals = []
189
- threshold = -0.3
190
-
191
- for i in range(1, len(composite_momentum)-1):
192
- # Momentum turning up from oversold
193
- if (composite_momentum[i-1] < threshold and
194
- composite_momentum[i] > composite_momentum[i-1] and
195
- composite_momentum[i+1] > composite_momentum[i]):
196
-
197
- signals.append({
198
- 'date': dates[i].strftime('%Y-%m-%d'),
199
- 'price': float(prices[i]),
200
- 'momentum': float(composite_momentum[i])
201
- })
202
-
203
- return signals
204
 
205
- def _create_gradio_html(self, charts: Dict[str, go.Figure]) -> str:
206
- """Convert charts to HTML for Gradio display"""
207
- html_parts = ["""
208
- <div style='background: white; padding: 20px;'>
209
- <h1 style='text-align: center; color: #333;'>📊 Interactive Analysis Charts</h1>
210
- """]
211
-
212
- for chart_name, fig in charts.items():
213
- title = chart_name.replace('_', ' ').title()
214
- html_parts.append(f"<h2 style='color: #666; margin-top: 40px;'>{title}</h2>")
215
- html_parts.append(fig.to_html(include_plotlyjs='cdn', div_id=chart_name))
216
-
217
- html_parts.append("</div>")
218
- return "\n".join(html_parts)
219
 
220
- def _generate_results_markdown(
221
- self,
222
- symbol,
223
- spectral_results,
224
- mc_stats,
225
- regime_probs,
226
- ml_metrics,
227
- candlestick_patterns,
228
- chart_patterns,
229
- composite_momentum,
230
- buy_signals
231
- ):
232
- """Generate detailed results in markdown format"""
233
-
234
- md = f"""
235
- # 📊 Professional Quantitative Analysis Report: {symbol}
236
-
237
- ## 🎯 Executive Summary
238
-
239
- **Analysis Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
240
-
241
- **Current Market Assessment:**
242
- - **Composite Momentum:** {composite_momentum[-1]:.4f}
243
- - **Momentum Direction:** {'📈 Bullish' if composite_momentum[-1] > 0 else '📉 Bearish'}
244
- - **ML Model Performance:** R² = {ml_metrics['final_r2']:.3f}
245
-
246
- ---
247
-
248
- ## 🔬 Multi-Frequency Spectral Analysis
249
-
250
- Analysis across Low, Mid, and High frequency bands reveals dominant market cycles:
251
-
252
- """
253
-
254
- for band_name, result in spectral_results.items():
255
- band_config = result['band_config']
256
- dominant_freqs = result['dominant_frequencies']
257
-
258
- md += f"""
259
- ### {band_config.name}
260
-
261
- **Period Range:** {band_config.min_period:.0f} - {band_config.max_period:.0f} days
262
-
263
- **Dominant Cycles:**
264
-
265
- """
266
- for i, freq in enumerate(dominant_freqs[:3], 1):
267
- md += f"""
268
- {i}. **Period: {freq['period_days']:.1f} days**
269
- - Frequency: {freq['frequency']:.4f} cycles/day
270
- - Amplitude: {freq['amplitude']:.0f}
271
- - Statistical Significance: {freq['significance']:.1%}
272
- - Z-Score: {freq['z_score']:.2f}
273
-
274
- """
275
-
276
- md += f"""
277
- ---
278
-
279
- ## 🎲 Monte Carlo Simulation Results ({config.MC_SIMULATIONS:,} simulations)
280
-
281
- Probabilistic price forecasts over {config.MC_TIME_HORIZON} days:
282
-
283
- """
284
-
285
- for model_name, stats in mc_stats.items():
286
- md += f"""
287
- ### {model_name.upper().replace('_', ' ')} Model
288
-
289
- - **Expected Price:** ${stats['mean_final_price']:.2f}
290
- - **Median Price:** ${stats['median_final_price']:.2f}
291
- - **95% Confidence Interval:** ${stats['percentile_5']:.2f} - ${stats['percentile_95']:.2f}
292
- - **Probability of Profit:** {stats['prob_profit']:.1%}
293
- - **Expected Return:** {stats['expected_return']:.2%}
294
- - **Value at Risk (95%):** ${stats['var_95']:.2f}
295
- - **Conditional VaR (95%):** ${stats['cvar_95']:.2f}
296
-
297
- """
298
-
299
- md += f"""
300
- ---
301
-
302
- ## 📈 Bayesian Market Regime Analysis
303
-
304
- **Estimated Regime Probabilities:**
305
-
306
- - **Range-Bound Market:** {regime_probs.get('range_bound', 0):.1%}
307
- - **Trending Market:** {regime_probs.get('trending', 0):.1%}
308
- - **High Volatility Regime:** {regime_probs.get('high_volatility', 0):.1%}
309
-
310
- ---
311
-
312
- ## 🤖 Machine Learning Performance
313
-
314
- **Self-Supervised Learning Results:**
315
-
316
- - **Average MSE (Cross-Validation):** {ml_metrics['avg_mse']:.6f}
317
- - **Average MAE:** {ml_metrics['avg_mae']:.6f}
318
- - **Average R² Score:** {ml_metrics['avg_r2']:.3f}
319
- - **Final R² Score:** {ml_metrics['final_r2']:.3f}
320
-
321
- Model continuously learns from past predictions to improve accuracy.
322
-
323
- ---
324
-
325
- ## 🎯 Pattern Recognition Results
326
-
327
- """
328
-
329
- if candlestick_patterns:
330
- md += f"""
331
- ### Candlestick Patterns ({len(candlestick_patterns)} detected)
332
-
333
- Recent patterns:
334
-
335
- """
336
- for pattern in candlestick_patterns[-5:]:
337
- md += f"- **{pattern['pattern']}** on {pattern['date']} - Signal: {pattern['signal']}\n"
338
- else:
339
- md += "\n### Candlestick Patterns\n\nNo significant candlestick patterns detected.\n"
340
-
341
- if chart_patterns:
342
- md += f"""
343
-
344
- ### Chart Patterns ({len(chart_patterns)} detected)
345
-
346
- """
347
- for pattern in chart_patterns:
348
- md += f"- **{pattern['pattern']}** - Signal: {pattern['signal']}\n"
349
- else:
350
- md += "\n### Chart Patterns\n\nNo chart patterns detected.\n"
351
 
352
- md += """
353
-
354
- ---
355
-
356
- ## ⚠️ Risk Disclosure
357
-
358
- This analysis is for **educational and informational purposes only**. It does NOT constitute:
359
- - Financial advice
360
- - Investment recommendations
361
- - An offer to buy or sell securities
362
-
363
- **Key Limitations:**
364
- - Models are based on historical data and assumptions
365
- - Past performance does not guarantee future results
366
- - All investments carry risk, including potential loss of principal
367
- - Market conditions can change rapidly and unexpectedly
368
-
369
- **Always consult with a qualified financial advisor before making investment decisions.**
370
-
371
- ---
372
-
373
- ## 🔧 Technical Details
374
-
375
- **Analysis Configuration:**
376
- - Bayesian MCMC Draws: {config.BAYESIAN_DRAWS:,}
377
- - Monte Carlo Simulations: {config.MC_SIMULATIONS:,}
378
- - ML Cross-Validation Splits: {config.ML_VALIDATION_SPLITS}
379
- - Frequency Bands Analyzed: {len(config.FREQUENCY_BANDS)}
380
-
381
- **Powered by:**
382
- - PyMC (Bayesian Inference)
383
- - XGBoost/LightGBM (Machine Learning)
384
- - SciPy (Signal Processing)
385
- - Plotly (Interactive Visualizations)
386
- """
387
 
388
- return md
389
-
390
 
391
- def create_gradio_interface():
392
- """Create Gradio UI"""
 
393
 
394
- platform = QuantitativeAnalysisPlatform()
 
 
 
 
 
 
 
 
395
 
396
- def analyze_wrapper(symbol, timeframe, period):
397
- """Wrapper for Gradio"""
398
- html, status, results, pdf = platform.run_complete_analysis(symbol, timeframe, period)
399
- return html, status, results, pdf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
 
401
- with gr.Blocks(
402
- theme=gr.themes.Soft(),
403
- title="Professional Quantitative Finance Platform",
404
- css="""
405
- .main-header {
406
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
407
- color: white;
408
- padding: 30px;
409
- border-radius: 10px;
410
- text-align: center;
411
- margin-bottom: 30px;
412
- box-shadow: 0 10px 30px rgba(0,0,0,0.2);
413
- }
414
- .feature-box {
415
- background: #f8f9fa;
416
- padding: 20px;
417
- border-radius: 8px;
418
- border-left: 4px solid #667eea;
419
- margin: 10px 0;
420
- }
421
- """
422
- ) as demo:
423
-
424
- gr.HTML("""
425
- <div class="main-header">
426
- <h1>🚀 Professional Quantitative Finance Analysis Platform</h1>
427
- <p style="font-size: 18px; margin-top: 10px;">
428
- Multi-Frequency Spectral Analysis • Bayesian Inference • Monte Carlo Simulation<br/>
429
- Machine Learning • Pattern Recognition • Comprehensive Reporting
430
- </p>
431
- </div>
432
- """)
433
-
434
- with gr.Row():
435
- with gr.Column(scale=1):
436
- gr.HTML("<h3>⚙️ Analysis Configuration</h3>")
437
-
438
- symbol_input = gr.Textbox(
439
- label="Stock Symbol",
440
- placeholder="AAPL, MSFT, GOOGL, TSLA...",
441
- value="AAPL"
442
- )
443
-
444
- timeframe_input = gr.Dropdown(
445
- label="Time Interval",
446
- choices=['1d', '1h', '15m', '5m'],
447
- value='1d',
448
- info="Select data granularity"
449
- )
450
-
451
- period_input = gr.Dropdown(
452
- label="Historical Period",
453
- choices=['1mo', '3mo', '6mo', '1y', '2y', '5y'],
454
- value='2y',
455
- info="Amount of historical data to analyze"
456
- )
457
-
458
- analyze_btn = gr.Button(
459
- "🚀 START COMPREHENSIVE ANALYSIS",
460
- variant="primary",
461
- size="lg"
462
- )
463
-
464
- status_output = gr.Textbox(
465
- label="Analysis Status",
466
- lines=15,
467
- interactive=False
468
- )
469
-
470
- with gr.Column(scale=2):
471
- gr.HTML("<h3>📊 Interactive Visualizations</h3>")
472
- charts_output = gr.HTML(
473
- value="<div style='text-align: center; padding: 50px; color: #666;'>"
474
- "Interactive charts will appear here after analysis</div>"
475
- )
476
-
477
- gr.HTML("<hr style='margin: 30px 0;'>")
478
-
479
- with gr.Row():
480
- with gr.Column():
481
- results_output = gr.Markdown(
482
- value="Detailed analysis results will appear here..."
483
- )
484
-
485
- gr.HTML("<hr style='margin: 30px 0;'>")
486
-
487
- with gr.Row():
488
- pdf_output = gr.File(
489
- label="📄 Download Comprehensive PDF Report",
490
- interactive=False
491
- )
492
-
493
- gr.HTML("""
494
- <div class="feature-box">
495
- <h3>🎯 Advanced Features</h3>
496
- <ul>
497
- <li><strong>Multi-Frequency Decomposition:</strong> Separate analysis of low, mid, and high frequency components</li>
498
- <li><strong>Self-Supervised Learning:</strong> ML models that learn from past predictions</li>
499
- <li><strong>Bayesian Inference:</strong> Probabilistic market regime detection and parameter optimization</li>
500
- <li><strong>Monte Carlo Simulation:</strong> Multiple stochastic models (GBM, Jump Diffusion, GARCH, Heston)</li>
501
- <li><strong>Pattern Recognition:</strong> Technical patterns + ML-based clustering with DTW</li>
502
- <li><strong>Professional Reporting:</strong> Interactive HTML dashboards + comprehensive PDF reports</li>
503
- </ul>
504
- </div>
505
- """)
506
-
507
- analyze_btn.click(
508
- fn=analyze_wrapper,
509
- inputs=[symbol_input, timeframe_input, period_input],
510
- outputs=[charts_output, status_output, results_output, pdf_output]
511
- )
512
 
513
- return demo
514
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
515
 
516
  if __name__ == "__main__":
517
- demo = create_gradio_interface()
518
- demo.launch(
519
- server_name="0.0.0.0",
520
- server_port=7860,
521
- share=True,
522
- show_error=True
523
- )
 
1
+ import yfinance as yf
 
 
 
 
 
 
2
  import pandas as pd
3
+ import numpy as np
4
+ import mplfinance as mpf
5
+ import talib # pip install ta-lib
6
+ import gradio as gr
7
+ from datetime import date
8
+
9
+ # TALib formasyon fonksiyonlarını bir dictionary'de tutalım
10
+ TALIB_PATTERNS = {
11
+ "CDLSHOOTINGSTAR": talib.CDLSHOOTINGSTAR,
12
+ "CDLHAMMER": talib.CDLHAMMER,
13
+ "CDLDOJI": talib.CDLDOJI,
14
+ "CDLINVERTEDHAMMER": talib.CDLINVERTEDHAMMER,
15
+ "CDLENGULFING": talib.CDLENGULFING,
16
+ "CDLHARAMI": talib.CDLHARAMI,
17
+ "CDLMORNINGSTAR": talib.CDLMORNINGSTAR,
18
+ "CDLEVENINGSTAR": talib.CDLEVENINGSTAR,
19
+ "CDL3WHITESOLDIERS": talib.CDL3WHITESOLDIERS,
20
+ "CDL3BLACKCROWS": talib.CDL3BLACKCROWS,
21
+ # İstediğiniz diğer formasyonları ekleyebilirsiniz
22
+ }
23
+
24
+ def find_candlestick_patterns(df, pattern_name):
25
+ """
26
+ Verilen DataFrame'de TALib kullanarak mum çubuğu formasyonlarını bulur ve
27
+ mplfinance için addplot listesi döndürür.
28
 
29
+ Args:
30
+ df (pd.DataFrame): Hisse senedi verisi (Open, High, Low, Close sütunları ile).
31
+ pattern_name (str): TALib'deki formasyon fonksiyonunun adı (örn. "CDLSHOOTINGSTAR").
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ Returns:
34
+ list: mpf.make_addplot objelerinin listesi veya boş liste.
35
+ """
36
+ if pattern_name not in TALIB_PATTERNS:
37
+ return [] # Boş liste döndür
38
+
39
+ pattern_func = TALIB_PATTERNS[pattern_name]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ # TALib'e özel olarak sütun isimleri küçük harf olmalı
42
+ df_talib = df.rename(columns={
43
+ 'Open': 'open',
44
+ 'High': 'high',
45
+ 'Low': 'low',
46
+ 'Close': 'close',
47
+ 'Volume': 'volume'
48
+ })
49
+
50
+ pattern_result = pattern_func(df_talib['open'], df_talib['high'],
51
+ df_talib['low'], df_talib['close'])
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
+ apds = []
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ # Boğa (bullish) formasyonları için
56
+ bullish_signals = pattern_result[pattern_result == 100]
57
+ if not bullish_signals.empty:
58
+ bullish_plot_data = pd.Series(np.nan, index=df.index)
59
+ for idx in bullish_signals.index:
60
+ bullish_plot_data[idx] = df.loc[idx, 'Low'] * 0.98 # Mumun biraz altına
61
+ apds.append(
62
+ mpf.make_addplot(bullish_plot_data,
63
+ type='scatter',
64
+ marker='^', # Yukarı üçgen
65
+ markersize=100,
66
+ color='green',
67
+ panel=0,
68
+ alpha=0.7)
69
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
+ # Ayı (bearish) formasyonları için
72
+ bearish_signals = pattern_result[pattern_result == -100]
73
+ if not bearish_signals.empty:
74
+ bearish_plot_data = pd.Series(np.nan, index=df.index)
75
+ for idx in bearish_signals.index:
76
+ bearish_plot_data[idx] = df.loc[idx, 'High'] * 1.02 # Mumun biraz üstüne
77
+ apds.append(
78
+ mpf.make_addplot(bearish_plot_data,
79
+ type='scatter',
80
+ marker='v', # Aşağı üçgen
81
+ markersize=100,
82
+ color='red',
83
+ panel=0,
84
+ alpha=0.7)
85
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ return apds
 
88
 
89
+ def plot_stock_with_patterns(ticker_symbol, start_date, end_date, selected_patterns):
90
+ """
91
+ Belirtilen hisse senedi için grafik çizer ve seçilen formasyonları işaretler.
92
 
93
+ Args:
94
+ ticker_symbol (str): Hisse senedi kodu (örn. "MSFT").
95
+ start_date (str): Başlangıç tarihi (YYYY-MM-DD).
96
+ end_date (str): Bitiş tarihi (YYYY-MM-DD).
97
+ selected_patterns (list): Kullanıcının seçtiği formasyonların listesi.
98
+
99
+ Returns:
100
+ tuple: (str: Oluşturulan grafiğin dosya yolu, str: Durum mesajı)
101
+ """
102
 
103
+ # Tarih formatlarını kontrol edelim
104
+ try:
105
+ start = pd.to_datetime(start_date)
106
+ end = pd.to_datetime(end_date)
107
+ if start >= end:
108
+ return None, "Start date must be before end date."
109
+ except ValueError:
110
+ return None, "Invalid date format. Please use YYYY-MM-DD."
111
+
112
+ try:
113
+ # yfinance'tan veri çek
114
+ df = yf.download(ticker_symbol, start=start_date, end=end_date)
115
+ if df.empty:
116
+ return None, f"Could not download data for {ticker_symbol}. Please check the ticker symbol and date range."
117
+ except Exception as e:
118
+ return None, f"An error occurred while downloading data: {e}"
119
+
120
+ # mplfinance'ın beklediği sütun isimlerini kontrol edelim
121
+ # yfinance zaten 'Open', 'High', 'Low', 'Close', 'Volume' döndürüyor.
122
+ # Eğer küçük harf olsaydı df.columns = [col.capitalize() for col in df.columns] kullanırdık.
123
 
124
+ # Addplot listesini oluştur
125
+ all_apds = []
126
+ if selected_patterns: # Eğer hiç formasyon seçilmemişse boş kalır
127
+ for pattern_name in selected_patterns:
128
+ pattern_apds = find_candlestick_patterns(df, pattern_name)
129
+ all_apds.extend(pattern_apds)
130
+
131
+ # Grafiği oluştur ve bir dosyaya kaydet
132
+ # Geçici bir dosya adı kullanalım
133
+ fig_path = f"/tmp/stock_chart_{ticker_symbol}_{date.today().strftime('%Y%m%d%H%M%S')}.png"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
 
135
+ # mplfinance style ayarları
136
+ s = mpf.make_mpf_style(base_mpf_style='yahoo', mavcolors=['#1f77b4', '#ff7f0e', '#2ca02c']) # Moving Average renkleri
137
+
138
+ try:
139
+ fig, axlist = mpf.plot(
140
+ df,
141
+ type='candle',
142
+ volume=True,
143
+ addplot=all_apds if all_apds else None, # Eğer addplot boşsa None geç
144
+ style=s,
145
+ title=f"{ticker_symbol} Candlestick Chart with Selected Patterns",
146
+ ylabel='Price',
147
+ ylabel_lower='Volume',
148
+ returnfig=True,
149
+ figscale=1.5 # Grafik boyutunu ayarla
150
+ )
151
+ fig.savefig(fig_path)
152
+ return fig_path, "Chart generated successfully!"
153
+ except Exception as e:
154
+ return None, f"An error occurred while plotting the chart: {e}"
155
+
156
+ # Gradio arayüzü
157
+ iface = gr.Interface(
158
+ fn=plot_stock_with_patterns,
159
+ inputs=[
160
+ gr.Textbox(label="Ticker Symbol (e.g., MSFT, AAPL, ^GSPC for S&P 500)", value="MSFT"),
161
+ gr.Textbox(label="Start Date (YYYY-MM-DD)", value="2023-01-01"),
162
+ gr.Textbox(label="End Date (YYYY-MM-DD)", value=date.today().strftime("%Y-%m-%d")),
163
+ gr.CheckboxGroup(
164
+ label="Select Candlestick Patterns",
165
+ choices=list(TALIB_PATTERNS.keys()),
166
+ value=["CDLSHOOTINGSTAR", "CDLHAMMER"] # Varsayılan olarak seçili gelenler
167
+ )
168
+ ],
169
+ outputs=[
170
+ gr.Image(type="filepath", label="Stock Chart"),
171
+ gr.Textbox(label="Status")
172
+ ],
173
+ title="Interactive Stock Candlestick Chart with Technical Patterns",
174
+ description="Enter a stock ticker, date range, and select candlestick patterns to visualize them on the chart. "
175
+ "Patterns are marked with green (bullish) or red (bearish) triangles on the chart."
176
+ "\n\n**Note:** Some TALib patterns are for specific market conditions or require more data points to detect. "
177
+ "If a pattern is not found, no marker will appear for that pattern."
178
+ )
179
 
180
  if __name__ == "__main__":
181
+ iface.launch()