| import gradio as ui |
| import yfinance as yf |
| import pandas as pd |
| from prophet import Prophet |
| import plotly.graph_objects as go |
| from huggingface_hub import InferenceClient |
|
|
| |
| MARKET_ASSETS = { |
| "✡️ מדד תל אביב 125 (ישראל)": "^TA125.TA", |
| "S&P 500": "^GSPC", |
| "Nasdaq 100 (טכנולוגיה)": "^NDX", |
| "Dow Jones 30": "^DJI", |
| "VIX (מדד הפחד והחרדה)": "^VIX", |
| "DAX 40 (גרמניה)": "^GDAXI", |
| "FTSE 100 (בריטניה)": "^FTSE", |
| "Nikkei 225 (יפן)": "^N225", |
| "זהב (Gold)": "GC=F", |
| "נפט גולמי (Crude Oil)": "CL=F", |
| "ביטקוין (Bitcoin USD)": "BTC-USD" |
| } |
|
|
| client = InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct") |
| PRECOMPUTED_CACHE = {} |
|
|
| def get_llm_analysis(asset_symbol, asset_name, summary_stats, character): |
| """מנוע ה-LLM המתוקן - משתמש ב-chat_completion יציב ומהיר יותר""" |
| |
| |
| if character == "סבתא פולנייה (ציפי)": |
| system_instruction = "אתה סבתא פולנייה פולשנית, פסימיסטית ומודאגת מאוד בשם ציפי. את חושבת שלשים כסף בבורסה זה הימור מסוכן שיגמור את החסכונות של הנכדים, ומזכירה שצריך לאכול משהו חם. דברי בסגנון פולני קלאסי ומשעשע." |
| elif character == "הרבי מהאינסטגרם (רב ברוך)": |
| system_instruction = "אתה 'הרבי מהאינסטגרם' בשם הרב ברוך. אתה מוצא השגחה פרטית ופסוקים בכל גרף. אם המניה עולה - זה חסדי שמיים, אם היא יורדת - זה ניסיון מלמעלה. שלב ביטויים כמו 'ברוך השם', 'בעזרת השם', ו'לתת מעשר'." |
| else: |
| system_instruction = "אתה מוישי, ברוקר חרדי מבוול סטריט (ניו יורק). אתה מדבר בקצב מהיר, משלב המון מילים באנגלית (Yiddish-English כמו Listen, My friend, Oh my god, Buy the dip, Gvalt). אתה לחוץ על כסף, מקצוען אבל עם אופי חסידי-אמריקאי תזזיתי." |
|
|
| |
| user_prompt = f""" |
| נתח בקצרה (עד 4 שורות) ובעברית את הנכס/מניה הבאה: {asset_name} (סימול: {asset_symbol}). |
| נתונים פיננסיים אחרונים מהשוק: |
| {summary_stats} |
| |
| התשובה חייבת להיות נאמנה לחלוטין לדמות שלך, ולשלב את הנתונים הפיננסיים בצורה הומוריסטית ובשפה עשירה. |
| """ |
| |
| try: |
| |
| response = client.chat_completion( |
| model="meta-llama/Llama-3.2-3B-Instruct", |
| messages=[ |
| {"role": "system", "content": system_instruction}, |
| {"role": "user", "content": user_prompt} |
| ], |
| max_tokens=250, |
| temperature=0.8 |
| ) |
| return response.choices[0].message.content.strip() |
| except Exception as e: |
| |
| print(f"LLM Error: {e}") |
| return f"אוי גוואלד! השרת אומר: '{str(e)[:50]}...'. כנראה עין הרע, תנסה ללחוץ שוב!" |
| def run_calculation(ticker_symbol, asset_name, history_period="2y", forecast_days=60): |
| """פונקציית ליבה שמבצעת את הורדת הנתונים וחישוב ה-Prophet""" |
| ticker = yf.Ticker(ticker_symbol) |
| df = ticker.history(period=history_period) |
| if df.empty or len(df) < 15: |
| return None, None |
| |
| |
| df_prophet = df.reset_index()[['Date', 'Close']] |
| df_prophet['Date'] = df_prophet['Date'].dt.tz_localize(None) |
| df_prophet.columns = ['ds', 'y'] |
| |
| model = Prophet(daily_seasonality=False, weekly_seasonality=True, yearly_seasonality=True) |
| model.fit(df_prophet) |
| future = model.make_future_dataframe(periods=int(forecast_days)) |
| forecast = model.predict(future) |
| |
| |
| fig = go.Figure() |
| fig.add_trace(go.Scatter(x=df_prophet['ds'], y=df_prophet['y'], name='מה שקרה בפועל', line=dict(color='#0d47a1', width=3))) |
| |
| df_future = forecast.iloc[-int(forecast_days):] |
| fig.add_trace(go.Scatter( |
| x=pd.concat([df_future['ds'], df_future['ds'].iloc[::-1]]), |
| y=pd.concat([df_future['yhat_upper'], df_future['yhat_lower'].iloc[::-1]]), |
| fill='toself', fillcolor='rgba(100, 181, 246, 0.2)', line=dict(color='rgba(255,255,255,0)'), hoverinfo="skip", name='טווח הסטייה המשוער' |
| )) |
| fig.add_trace(go.Scatter(x=df_future['ds'], y=df_future['yhat'], name='התחזית של JEWMINI', line=dict(color='#1e88e5', width=3, dash='dash'))) |
| |
| fig.update_layout( |
| title=f"📊 מגמות ונבואות עבור {asset_name}", xaxis_title="תאריך", yaxis_title="מחיר שוק", |
| hovermode="x unified", template="plotly_white", margin=dict(l=20, r=20, t=60, b=20), |
| plot_bgcolor='white', paper_bgcolor='white' |
| ) |
| |
| |
| last_price = df_prophet['y'].iloc[-1] |
| start_price = df_prophet['y'].iloc[0] |
| total_change = ((last_price - start_price) / start_price) * 100 |
| future_price = df_future['yhat'].iloc[-1] |
| predicted_change = ((future_price - last_price) / last_price) * 100 |
| |
| summary_stats = ( |
| f"מחיר נוכחי בשוק: {last_price:,.2f}\n" |
| f"תשואה היסטורית בתקופה: {total_change:+.2f}%\n" |
| f"מחיר חזוי לעוד {forecast_days} ימים: {future_price:,.2f} ({predicted_change:+.2f}%)" |
| ) |
| |
| return summary_stats, fig |
|
|
| def precompute_all_assets(): |
| """פונקציה שרצה בטעינת האפליקציה וממלאת את הזיכרון מראש""" |
| for name, symbol in MARKET_ASSETS.items(): |
| if name.startswith("--"): |
| continue |
| try: |
| summary, fig = run_calculation(symbol, name) |
| if summary and fig: |
| PRECOMPUTED_CACHE[name] = {"summary": summary, "fig": fig, "symbol": symbol} |
| except Exception as e: |
| pass |
|
|
| |
| precompute_all_assets() |
|
|
| def analyze_and_forecast(selected_asset, custom_ticker, history_period, forecast_days, character): |
| if custom_ticker and custom_ticker.strip(): |
| ticker_symbol = custom_ticker.strip().upper() |
| asset_name = f"מניית {ticker_symbol}" |
| summary_stats, fig = run_calculation(ticker_symbol, asset_name, history_period, forecast_days) |
| if not summary_stats: |
| return f"שגיאה: לא נמצאו נתונים עבור הסימול '{ticker_symbol}'.", None, "שגיאה" |
| else: |
| if selected_asset.startswith("--"): |
| return "נו באמת, תבחר נכס אמיתי כמו בנאדם.", None, "אויש נו." |
| |
| if history_period == "2y" and forecast_days == 60 and selected_asset in PRECOMPUTED_CACHE: |
| summary_stats = PRECOMPUTED_CACHE[selected_asset]["summary"] |
| fig = PRECOMPUTED_CACHE[selected_asset]["fig"] |
| ticker_symbol = PRECOMPUTED_CACHE[selected_asset]["symbol"] |
| asset_name = selected_asset |
| else: |
| ticker_symbol = MARKET_ASSETS[selected_asset] |
| asset_name = selected_asset |
| summary_stats, fig = run_calculation(ticker_symbol, asset_name, history_period, forecast_days) |
|
|
| llm_insights = get_llm_analysis(ticker_symbol, asset_name, summary_stats, character) |
| return summary_stats, fig, llm_insights |
|
|
|
|
| |
| blue_white_theme = ui.themes.Default( |
| primary_hue="blue", |
| secondary_hue="sky", |
| neutral_hue="slate" |
| ).set( |
| body_background_fill="white", |
| body_text_color="#0d47a1", |
| block_background_fill="#f1f8ff", |
| block_border_width="2px", |
| block_border_color="#90caf9", |
| button_primary_background_fill="#0d47a1", |
| button_primary_background_fill_hover="#1565c0", |
| button_primary_text_color="white" |
| ) |
|
|
| custom_css = """ |
| body { direction: rtl !important; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } |
| .markdown-text h1 { color: #0d47a1 !important; border-bottom: 3px solid #0d47a1; padding-bottom: 10px; } |
| .markdown-text h3 { color: #1565c0 !important; } |
| """ |
|
|
| with ui.Blocks(theme=blue_white_theme, css=custom_css, title="JEWMINI AI") as demo: |
| |
| |
| ui.Markdown(""" |
| # ✡️ JEWMINI AI - חמ״ל פיננסי כחול-לבן |
| דשבורד פיננסי חכם למדדים ומניות מהארץ ומהעולם. המערכת משתמשת במודל החיזוי **Prophet** ובבינה מלאכותית מבוססת דמויות לניתוח השוק. |
| """) |
| |
| with ui.Row(): |
| |
| with ui.Column(scale=1): |
| ui.Markdown("### 🕵️♂️ 1. האנליסט שלך") |
| character_dropdown = ui.Dropdown( |
| choices=["סבתא פולנייה (ציפי)", "הרבי מהאינסטגרם (רב ברוך)", "מוישי הברוקר מוול סטריט"], |
| value="סבתא פולנייה (ציפי)", |
| label="בחר דמות לניתוח השוק" |
| ) |
| |
| ui.Markdown("### 🔍 2. נכס או מניה") |
| selected_asset = ui.Dropdown( |
| choices=list(MARKET_ASSETS.keys()), |
| value="✡️ מדד תל אביב 125 (ישראל)", |
| label="בחר נכס מהרשימה" |
| ) |
| |
| custom_ticker = ui.Textbox( |
| label="או הקלד סימול חופשי (למשל: AAPL, NVDA, TSLA)", |
| placeholder="הקלד באנגלית..." |
| ) |
| |
| ui.Markdown("### ⚙️ הגדרות המודל") |
| history_radio = ui.Radio( |
| choices=["1y", "2y", "5y"], value="2y", label="טווח היסטוריית למידה" |
| ) |
| forecast_slider = ui.Slider( |
| minimum=7, maximum=180, value=60, step=1, label="טווח החיזוי העתידי (בימים)" |
| ) |
| |
| |
| btn = ui.Button("🚀 הפעל ניתוח ונבואה", variant="primary") |
| |
| |
| with ui.Column(scale=2): |
| with ui.Group(): |
| ui.Markdown("### 💬 ניתוח אנליטי (JEWMINI Insights)") |
| llm_output = ui.Textbox(show_label=False, interactive=False, lines=5) |
| |
| output_text = ui.Textbox(label="📊 נתונים מספריים ותחזית", interactive=False, lines=3) |
| output_chart = ui.Plot(label="📈 גרף הנביא (כחול-לבן)") |
|
|
| |
| inputs = [selected_asset, custom_ticker, history_radio, forecast_slider, character_dropdown] |
| outputs = [output_text, output_chart, llm_output] |
| |
| btn.click(fn=analyze_and_forecast, inputs=inputs, outputs=outputs) |
| demo.load(fn=analyze_and_forecast, inputs=inputs, outputs=outputs) |
|
|
| if __name__ == "__main__": |
| demo.launch() |