import yfinance as yf import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout import tensorflow as tf import random import matplotlib.pyplot as plt import gradio as gr # تابع فرمت‌بندی قیمت def format_price(price): if price >= 1: return f"{price:.3f} USD" # تا ۳ رقم اعشار elif price >= 0.01: return f"{price:.6f} USD" # تا ۶ رقم اعشار else: return f"{price:.10f} USD" # تا ۱۰ رقم اعشار برای مقادیر خیلی کوچک def run_prediction(symbol): symbol = symbol.upper() # دانلود داده‌ها data = yf.download(symbol, start='2010-01-01', end='2025-12-31', interval='1d') data = data[['Close', 'Volume']].dropna() # مقیاس‌بندی scaler = MinMaxScaler() scaled_data = scaler.fit_transform(data) def create_dataset(data, time_step=60): X, y = [], [] for i in range(time_step, len(data)): X.append(data[i-time_step:i]) y.append(data[i,0]) return np.array(X), np.array(y) time_step = 60 X, y = create_dataset(scaled_data, time_step) train_size = int(len(X)*0.8) X_train, X_test = X[:train_size], X[train_size:] y_train, y_test = y[:train_size], y[train_size:] # مدل tf.random.set_seed(42) np.random.seed(42) random.seed(42) model = Sequential() model.add(LSTM(50, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2]))) model.add(Dropout(0.2)) model.add(LSTM(50)) model.add(Dropout(0.2)) model.add(Dense(1)) model.compile(optimizer='adam', loss='mean_squared_error') model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=32, verbose=0) # پیش‌بینی گذشته pred_past = model.predict(X, verbose=0) pred_past_full = np.zeros((len(pred_past), scaled_data.shape[1])) pred_past_full[:,0] = pred_past[:,0] pred_past_real = scaler.inverse_transform(pred_past_full)[:,0] # پیش‌بینی ۷ هفته آینده (برای نمایش روی چارت) pred_input = scaled_data[-time_step:] pred_input = pred_input.reshape(1, time_step, X_train.shape[2]) predicted_prices = [] for _ in range(7): pred = model.predict(pred_input, verbose=0) predicted_prices.append(pred[0,0]) next_input = np.append(pred_input[0,1:,:], [[pred[0,0], 0]], axis=0) pred_input = next_input.reshape(1, time_step, X_train.shape[2]) predicted_prices_full = np.zeros((7, scaled_data.shape[1])) predicted_prices_full[:,0] = predicted_prices predicted_prices_real = scaler.inverse_transform(predicted_prices_full)[:,0] # بررسی روند if predicted_prices_real[-1] > predicted_prices_real[0]: trend_status = "upward" status_color = 'green' else: trend_status = "downward" status_color = 'red' # رسم نمودار (۷ هفته) plt.figure(figsize=(12,6)) plt.plot(data.index, data['Close'], label=f'{symbol} Close Price') plt.plot(data.index[time_step:], pred_past_real, label='Predicted on Past Data', alpha=0.7) future_dates = pd.date_range(start=data.index[-1]+pd.Timedelta(days=1), periods=7) plt.plot(future_dates, predicted_prices_real, marker='o', label='Predicted Price (7 weeks)') plt.yscale('log') plt.title(f'{symbol} Price Prediction - Long Scale - Weekly Timeframe chart') plt.xlabel('Date') plt.ylabel('Price (USD)') plt.legend() # متن‌های روی نمودار (فقط ۳ هفته اول) ax = plt.gca() y_min = data['Close'].min() y_max = data['Close'].max() y_middle = (y_min + y_max) / 2 y_range = y_max - y_min x_left = data.index[0] plt.text(x_left, y_middle + 0.05*y_range, "Next targets in next weeks:", fontsize=12, color='blue', ha='left', va='bottom', bbox=dict(facecolor='white', alpha=0.5, edgecolor='none')) pred_text = "\n".join([format_price(price) for price in predicted_prices_real[:3]]) # فقط ۳ هفته plt.text(x_left, y_middle + 0.05*y_range - 0.02*y_range, pred_text, fontsize=12, color='black', ha='left', va='top', bbox=dict(facecolor='white', alpha=0.5, edgecolor='none')) x_right = data.index[-1] y_text = y_min + 0.02*y_range plt.text(x_right, y_text + 0.01*y_range, "Overall trend for next weeks is", fontsize=14, color='purple', ha='right', va='bottom', bbox=dict(facecolor='white', alpha=0.5, edgecolor='none')) plt.text(x_right, y_text, trend_status, fontsize=12, color=status_color, verticalalignment='center', bbox=dict(facecolor='white', alpha=0.7, edgecolor='none')) plt.savefig("plot.png") plt.close() # متن خروجی Gradio (فقط ۳ هفته) prices_output = "\n".join([format_price(p) for p in predicted_prices_real[:3]]) trend_output = f"Overall trend for next weeks is {trend_status}" return "plot.png", prices_output, trend_output # رابط Gradio interface = gr.Interface( fn=run_prediction, inputs=gr.Textbox(label="Enter Symbol in Yahoo Finance format (e.g.,BTC-USD for Bitcoin)"), outputs=[ gr.Image(type="filepath", label="Prediction Chart"), gr.Textbox(label="Predicted Prices (next 3 weeks)"), gr.Textbox(label="Trend Status") ], title="Market Trend Predictor (LSTM by AI)" ) interface.launch()