Bullishway's picture
Update app.py
2448902 verified
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()