garvitcoder

stock market

Jun 21st, 2026
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.72 KB | None | 0 0
  1. import datetime
  2. import tkinter as tk
  3. from tkinter import messagebox, ttk
  4.  
  5. import matplotlib.pyplot as plt
  6. import numpy as np
  7. import pandas as pd
  8. import yfinance as yf
  9. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
  10. from sklearn.ensemble import RandomForestRegressor
  11. from sklearn.metrics import mean_squared_error
  12. from sklearn.model_selection import train_test_split
  13.  
  14.  
  15. class StockPredictorApp:
  16.  
  17. def __init__(self, root):
  18. self.root = root
  19. self.root.title("Real-Time Stock Predictor & Analytics AI")
  20. self.root.geometry("1100x700")
  21. self.root.configure(bg="#2c3e50")
  22.  
  23. # Layout Setup
  24. self.create_widgets()
  25.  
  26. def create_widgets(self):
  27. # --- Top Control Panel ---
  28. control_frame = tk.Frame(self.root, bg="#34495e", bd=2, relief=tk.RIDGE)
  29. control_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=10)
  30.  
  31. # Ticker Input
  32. tk.Label(
  33. control_frame,
  34. text="Stock Ticker (e.g., AAPL, SPY):",
  35. fg="white",
  36. bg="#34495e",
  37. font=("Arial", 11, "bold"),
  38. ).grid(row=0, column=0, padx=10, pady=10, sticky="w")
  39. self.ticker_entry = tk.Entry(control_frame, font=("Arial", 11), width=10)
  40. self.ticker_entry.insert(0, "AAPL")
  41. self.ticker_entry.grid(row=0, column=1, padx=5, pady=10)
  42.  
  43. # Date Range inputs
  44. tk.Label(
  45. control_frame,
  46. text="Start Date (YYYY-MM-DD):",
  47. fg="white",
  48. bg="#34495e",
  49. font=("Arial", 11),
  50. ).grid(row=0, column=2, padx=10, pady=10)
  51. self.start_entry = tk.Entry(control_frame, font=("Arial", 11), width=12)
  52. self.start_entry.insert(0, "2020-01-01")
  53. self.start_entry.grid(row=0, column=3, padx=5, pady=10)
  54.  
  55. tk.Label(
  56. control_frame,
  57. text="End Date (YYYY-MM-DD):",
  58. fg="white",
  59. bg="#34495e",
  60. font=("Arial", 11),
  61. ).grid(row=0, column=4, padx=10, pady=10)
  62. self.end_entry = tk.Entry(control_frame, font=("Arial", 11), width=12)
  63. self.end_entry.insert(0, datetime.datetime.now().strftime("%Y-%m-%d"))
  64. self.end_entry.grid(row=0, column=5, padx=5, pady=10)
  65.  
  66. # Action Button
  67. self.predict_btn = tk.Button(
  68. control_frame,
  69. text="Run Prediction Model",
  70. command=self.process_stock_data,
  71. bg="#2ecc71",
  72. fg="white",
  73. font=("Arial", 11, "bold"),
  74. relief=tk.RAISED,
  75. cursor="hand2",
  76. )
  77. self.predict_btn.grid(row=0, column=6, padx=20, pady=10)
  78.  
  79. # --- Dashboard Metrics Layout ---
  80. self.metrics_frame = tk.Frame(self.root, bg="#2c3e50")
  81. self.metrics_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=5)
  82.  
  83. self.last_close_label = self.create_metric_box(
  84. self.metrics_frame, "Last Close Price", "N/A", "#2980b9", 0
  85. )
  86. self.predicted_label = self.create_metric_box(
  87. self.metrics_frame, "Next Day Prediction", "N/A", "#d35400", 1
  88. )
  89. self.mse_label = self.create_metric_box(
  90. self.metrics_frame, "Model Error (MSE)", "N/A", "#7f8c8d", 2
  91. )
  92.  
  93. # --- Data Plot Frame ---
  94. self.plot_frame = tk.Frame(self.root, bg="white", bd=2, relief=tk.SUNKEN)
  95. self.plot_frame.pack(
  96. side=tk.BOTTOM, fill=tk.BOTH, expand=True, padx=10, pady=10
  97. )
  98.  
  99. def create_metric_box(self, parent, title, initial_val, color, col_idx):
  100. box = tk.Frame(parent, bg=color, bd=2, relief=tk.GROOVE, width=250, height=80)
  101. box.grid(row=0, column=col_idx, padx=15, pady=5)
  102. box.grid_propagate(False)
  103.  
  104. title_lbl = tk.Label(
  105. box, text=title, fg="#ecf0f1", bg=color, font=("Arial", 10, "italic")
  106. )
  107. title_lbl.pack(pady=2)
  108.  
  109. val_lbl = tk.Label(
  110. box, text=initial_val, fg="white", bg=color, font=("Arial", 16, "bold")
  111. )
  112. val_lbl.pack(pady=5)
  113. return val_lbl
  114.  
  115. def process_stock_data(self):
  116. ticker = self.ticker_entry.get().strip().upper()
  117. start_date = self.start_entry.get().strip()
  118. end_date = self.end_entry.get().strip()
  119.  
  120. if not ticker:
  121. messagebox.showerror("Error", "Please enter a valid stock ticker.")
  122. return
  123.  
  124. self.predict_btn.config(text="Processing...", state=tk.DISABLED)
  125. self.root.update_idletasks()
  126.  
  127. try:
  128. # 1. Fetching Data safely
  129. df = yf.download(ticker, start=start_date, end=end_date)
  130. if df.empty:
  131. raise ValueError("No data returned. Check ticker name or dates.")
  132.  
  133. # Flatten multi-level columns if returned by newer yfinance versions
  134. if isinstance(df.columns, pd.MultiIndex):
  135. if ticker in df.columns.levels[1]:
  136. df = df.xs(ticker, axis=1, level=1)
  137. else:
  138. df.columns = df.columns.get_level_values(0)
  139.  
  140. # 2. Feature Engineering
  141. df["MA10"] = df["Close"].rolling(window=10).mean()
  142. df["MA50"] = df["Close"].rolling(window=50).mean()
  143. df["Returns"] = df["Close"].pct_change()
  144. df["Volatility"] = df["Returns"].rolling(window=10).std()
  145.  
  146. # Target variable: Next day's closing price
  147. df["Target"] = df["Close"].shift(-1)
  148.  
  149. # Clean up missing rows caused by rolling calculations
  150. df.dropna(inplace=True)
  151.  
  152. if len(df) < 60:
  153. raise ValueError(
  154. "Not enough data days within range to train the ML model safely."
  155. )
  156.  
  157. # Define Features & Target arrays
  158. feature_cols = ["Close", "MA10", "MA50", "Volatility"]
  159. X = df[feature_cols].values
  160. y = df["Target"].values
  161.  
  162. # 3. Machine Learning Model Setup
  163. # FIXED: 'test_size=0.2' replaces the old typo parameter
  164. X_train, X_test, y_train, y_test = train_test_split(
  165. X, y, test_size=0.2, shuffle=False
  166. )
  167.  
  168. model = RandomForestRegressor(n_estimators=100, random_state=42)
  169. model.fit(X_train, y_train)
  170.  
  171. # Evaluate Test Performance
  172. test_preds = model.predict(X_test)
  173. mse = mean_squared_error(y_test, test_preds)
  174.  
  175. # Predict Future (Next Day)
  176. latest_features = X[-1].reshape(1, -1)
  177. next_day_pred = model.predict(latest_features)[0]
  178. last_actual_close = float(df["Close"].iloc[-1])
  179.  
  180. # Update Metrics UI
  181. self.last_close_label.config(text=f"${last_actual_close:.2f}")
  182. self.predicted_label.config(text=f"${next_day_pred:.2f}")
  183. self.mse_label.config(text=f"{mse:.4f}")
  184.  
  185. # 4. Clear Old Charts & Render New Graphic
  186. for widget in self.plot_frame.winfo_children():
  187. widget.destroy()
  188.  
  189. self.update_chart(df, y_test, test_preds, ticker)
  190.  
  191. except Exception as e:
  192. messagebox.showerror("Execution Error", f"An error occurred:\n{str(e)}")
  193. finally:
  194. self.predict_btn.config(text="Run Prediction Model", state=tk.NORMAL)
  195.  
  196. def update_chart(self, df, y_test, test_preds, ticker):
  197. fig, ax = plt.subplots(figsize=(10, 4.5), dpi=100)
  198. ax.set_facecolor("#f8f9fa")
  199.  
  200. # Sync test split timelines
  201. test_dates = df.index[-len(y_test) :]
  202.  
  203. ax.plot(
  204. df.index,
  205. df["Close"],
  206. label="Historical Full Trend",
  207. color="#7f8c8d",
  208. alpha=0.5,
  209. )
  210. ax.plot(
  211. test_dates,
  212. y_test,
  213. label="Actual Test Split Price",
  214. color="#2ecc71",
  215. linewidth=1.5,
  216. )
  217. ax.plot(
  218. test_dates,
  219. test_preds,
  220. label="AI Predicted Path",
  221. color="#e74c3c",
  222. linestyle="--",
  223. linewidth=1.5,
  224. )
  225.  
  226. ax.set_title(
  227. f"{ticker} - Actual vs AI Model Backtest Tracking",
  228. fontsize=12,
  229. fontweight="bold",
  230. color="#2c3e50",
  231. )
  232. ax.set_xlabel("Timeline", fontsize=10)
  233. ax.set_ylabel("Price (USD)", fontsize=10)
  234. ax.legend(loc="upper left")
  235. ax.grid(True, linestyle=":", alpha=0.6)
  236.  
  237. fig.tight_layout()
  238.  
  239. canvas = FigureCanvasTkAgg(fig, master=self.plot_frame)
  240. canvas.draw()
  241. canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
  242.  
  243.  
  244. if __name__ == "__main__":
  245. root = tk.Tk()
  246. app = StockPredictorApp(root)
  247. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment