Spaces:
Running
Running
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() | |