File size: 11,770 Bytes
e9131f0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | 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 יציב ומהיר יותר"""
# 1. מגדירים את ה-System Prompt (האופי של הדמות)
if character == "סבתא פולנייה (ציפי)":
system_instruction = "אתה סבתא פולנייה פולשנית, פסימיסטית ומודאגת מאוד בשם ציפי. את חושבת שלשים כסף בבורסה זה הימור מסוכן שיגמור את החסכונות של הנכדים, ומזכירה שצריך לאכול משהו חם. דברי בסגנון פולני קלאסי ומשעשע."
elif character == "הרבי מהאינסטגרם (רב ברוך)":
system_instruction = "אתה 'הרבי מהאינסטגרם' בשם הרב ברוך. אתה מוצא השגחה פרטית ופסוקים בכל גרף. אם המניה עולה - זה חסדי שמיים, אם היא יורדת - זה ניסיון מלמעלה. שלב ביטויים כמו 'ברוך השם', 'בעזרת השם', ו'לתת מעשר'."
else:
system_instruction = "אתה מוישי, ברוקר חרדי מבוול סטריט (ניו יורק). אתה מדבר בקצב מהיר, משלב המון מילים באנגלית (Yiddish-English כמו Listen, My friend, Oh my god, Buy the dip, Gvalt). אתה לחוץ על כסף, מקצוען אבל עם אופי חסידי-אמריקאי תזזיתי."
# 2. הבקשה הספציפית (User Prompt)
user_prompt = f"""
נתח בקצרה (עד 4 שורות) ובעברית את הנכס/מניה הבאה: {asset_name} (סימול: {asset_symbol}).
נתונים פיננסיים אחרונים מהשוק:
{summary_stats}
התשובה חייבת להיות נאמנה לחלוטין לדמות שלך, ולשלב את הנתונים הפיננסיים בצורה הומוריסטית ובשפה עשירה.
"""
try:
# שימוש במודל Llama 3.2 יציב ומהיר דרך chat_completion
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:
# אם יש שגיאה, נדפיס אותה ללוגים של Hugging Face כדי שנוכל לראות אותה, ונחזיר הודעה משעשעת
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
# חיזוי Prophet
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)
# בניית גרף Plotly בצבעי כחול-לבן-תכלת
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
# --- 🔵 עיצוב כחול-לבן מותאם אישית (Custom Theme & CSS) ⚪ ---
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() |