diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..54640d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python cache +__pycache__/ +*.pyc + +# Generated files +Stocks Trend Analyzer/charts/generated_charts.png + +# OS files +.DS_Store +Thumbs.db diff --git a/Stocks Trend Analyzer/algorithms/__pycache__/local_high_low.cpython-312.pyc b/Stocks Trend Analyzer/algorithms/__pycache__/local_high_low.cpython-312.pyc index f761fc7..39736f7 100644 Binary files a/Stocks Trend Analyzer/algorithms/__pycache__/local_high_low.cpython-312.pyc and b/Stocks Trend Analyzer/algorithms/__pycache__/local_high_low.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/algorithms/__pycache__/max_profit.cpython-312.pyc b/Stocks Trend Analyzer/algorithms/__pycache__/max_profit.cpython-312.pyc index 350b077..f9b7840 100644 Binary files a/Stocks Trend Analyzer/algorithms/__pycache__/max_profit.cpython-312.pyc and b/Stocks Trend Analyzer/algorithms/__pycache__/max_profit.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/algorithms/__pycache__/moving_average.cpython-312.pyc b/Stocks Trend Analyzer/algorithms/__pycache__/moving_average.cpython-312.pyc index 2618ba8..3e9a515 100644 Binary files a/Stocks Trend Analyzer/algorithms/__pycache__/moving_average.cpython-312.pyc and b/Stocks Trend Analyzer/algorithms/__pycache__/moving_average.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/algorithms/__pycache__/trend_analysis.cpython-312.pyc b/Stocks Trend Analyzer/algorithms/__pycache__/trend_analysis.cpython-312.pyc index 18ac1f7..87157b8 100644 Binary files a/Stocks Trend Analyzer/algorithms/__pycache__/trend_analysis.cpython-312.pyc and b/Stocks Trend Analyzer/algorithms/__pycache__/trend_analysis.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/charts/generated_charts.png b/Stocks Trend Analyzer/charts/generated_charts.png index ce5cf34..2908808 100644 Binary files a/Stocks Trend Analyzer/charts/generated_charts.png and b/Stocks Trend Analyzer/charts/generated_charts.png differ diff --git a/Stocks Trend Analyzer/data/bitcoin.csv b/Stocks Trend Analyzer/data/bitcoin.csv new file mode 100644 index 0000000..c46599c --- /dev/null +++ b/Stocks Trend Analyzer/data/bitcoin.csv @@ -0,0 +1,16 @@ +Date,Open,High,Low,Close,Volume +2025-12-15,88,154.4,89,974.1,85,228.8,61.65B +2025-12-14,90,248.3,90,472.3,87,657.9,32.26B +2025-12-13,90,272.0,90,638.1,89,781.3,23.47B +2025-12-12,92,510.4,92,744.6,89,498.1,49.84B +2025-12-11,92,005.0,93,539.4,89,324.1,65.64B +2025-12-10,92,685.7,94,458.1,91,608.0,61.84B +2025-12-09,90,636.1,94,591.4,89,592.2,68.38B +2025-12-08,90,413.6,92,269.1,89,640.7,51.82B +2025-12-07,89,209.8,91,736.8,87,747.6,38.67B +2025-12-06,89,333.6,90,176.5,88,929.5,30.14B +2025-12-05,92,082.8,92,676.4,88,218.4,61.14B +2025-12-04,93,437.2,94,043.9,90,933.2,60.28B +2025-12-03,91,286.8,94,077.0,91,020.8,79.02B +2025-12-02,86,315.2,92,285.4,86,189.8,87.36B +2025-12-01,90,372.2,90,372.2,83,858.1,105.96B diff --git a/Stocks Trend Analyzer/data/sample_stock.csv b/Stocks Trend Analyzer/data/sample_stock.csv deleted file mode 100644 index 76a2664..0000000 --- a/Stocks Trend Analyzer/data/sample_stock.csv +++ /dev/null @@ -1,31 +0,0 @@ -Date,Open,High,Low,Close,Volume -2025-01-01,100.48,103.21,95.71,96.42,9011 -2025-01-02,95.73,98.3,92.34,96.2,8149 -2025-01-03,96.53,100.91,94.99,97.69,16825 -2025-01-04,97.47,99.73,95.98,99.08,18880 -2025-01-05,98.9,101.76,94.69,98.26,17359 -2025-01-06,98.75,103.36,97.18,97.47,18492 -2025-01-07,95.77,99.5,91.78,93.97,18054 -2025-01-08,92.52,92.69,90.88,92.51,17941 -2025-01-09,93.87,97.74,91.87,96.69,14700 -2025-01-10,98.66,99.76,96.61,99.69,12564 -2025-01-11,98.0,99.36,96.76,99.03,8224 -2025-01-12,100.45,100.73,97.67,98.95,7465 -2025-01-13,99.7,101.17,97.55,98.47,14068 -2025-01-14,99.19,101.1,98.49,100.05,6906 -2025-01-15,101.86,104.23,99.88,100.54,9267 -2025-01-16,99.62,103.21,98.78,100.49,5985 -2025-01-17,101.12,103.82,98.33,102.45,14911 -2025-01-18,102.89,107.87,99.56,101.7,17957 -2025-01-19,101.7,104.58,101.61,102.57,7957 -2025-01-20,104.4,105.55,101.4,103.48,5973 -2025-01-21,103.48,104.27,99.8,101.41,7414 -2025-01-22,101.36,104.88,100.89,100.94,12764 -2025-01-23,99.5,100.58,95.4,99.54,6201 -2025-01-24,101.0,102.53,99.01,100.3,16380 -2025-01-25,99.18,101.11,94.55,100.29,19366 -2025-01-26,99.98,103.97,95.96,101.16,9757 -2025-01-27,101.83,103.05,100.06,100.07,10752 -2025-01-28,101.75,103.04,97.61,97.7,10156 -2025-01-29,97.24,98.62,96.74,98.42,5265 -2025-01-30,96.68,100.41,94.86,96.18,12069 diff --git a/Stocks Trend Analyzer/data/sample_stock01.csv b/Stocks Trend Analyzer/data/sample_stock01.csv new file mode 100644 index 0000000..899e40f --- /dev/null +++ b/Stocks Trend Analyzer/data/sample_stock01.csv @@ -0,0 +1,31 @@ +Date,Open,High,Low,Close,Volume +2025-01-01,100.8,104.41,98.55,103.52,5910 +2025-01-02,102.49,105.15,99.4,100.36,17068 +2025-01-03,100.92,102.51,97.73,99.88,19659 +2025-01-04,98.15,98.46,96.78,97.77,17942 +2025-01-05,96.61,98.16,95.1,96.99,13654 +2025-01-06,96.34,100.55,92.06,98.72,17089 +2025-01-07,99.43,102.19,98.4,99.12,8436 +2025-01-08,99.69,99.94,95.71,98.63,16571 +2025-01-09,100.19,103.05,98.61,101.49,11236 +2025-01-10,102.02,103.64,97.59,101.01,19578 +2025-01-11,102.92,106.95,100.83,104.81,15520 +2025-01-12,105.19,107.96,102.09,102.23,7623 +2025-01-13,103.87,106.91,98.99,106.17,7965 +2025-01-14,107.58,108.58,106.64,106.98,11963 +2025-01-15,107.23,109.42,104.71,106.0,16172 +2025-01-16,105.59,105.88,104.21,104.29,10746 +2025-01-17,104.03,108.23,101.55,107.05,5934 +2025-01-18,105.06,106.6,104.79,105.35,9696 +2025-01-19,103.88,108.43,100.1,102.09,8837 +2025-01-20,103.46,106.52,101.96,106.22,10350 +2025-01-21,107.82,108.05,102.93,103.45,19102 +2025-01-22,103.45,105.14,98.49,102.96,11855 +2025-01-23,104.57,107.22,101.3,102.62,8859 +2025-01-24,103.78,104.17,102.05,102.39,8064 +2025-01-25,101.09,105.23,96.33,102.9,10909 +2025-01-26,104.54,109.33,100.68,107.19,5533 +2025-01-27,108.86,113.82,108.35,109.06,8063 +2025-01-28,110.08,112.13,109.85,111.38,5375 +2025-01-29,112.78,113.62,112.76,113.17,5828 +2025-01-30,112.03,115.34,108.71,110.05,9076 diff --git a/Stocks Trend Analyzer/data/sample_stock02.csv b/Stocks Trend Analyzer/data/sample_stock02.csv new file mode 100644 index 0000000..9e11d76 --- /dev/null +++ b/Stocks Trend Analyzer/data/sample_stock02.csv @@ -0,0 +1,31 @@ +Date,Open,High,Low,Close,Volume +2025-01-01,101.41,101.74,98.5,98.76,14332 +2025-01-02,98.48,99.45,96.62,98.73,5585 +2025-01-03,97.12,99.75,93.87,94.26,12038 +2025-01-04,95.28,95.85,93.6,94.76,17009 +2025-01-05,95.14,98.79,94.78,97.04,8954 +2025-01-06,97.88,98.61,94.82,98.5,10182 +2025-01-07,99.04,102.57,94.95,96.14,7993 +2025-01-08,95.51,98.85,93.99,97.3,5549 +2025-01-09,96.69,100.55,93.07,93.2,18224 +2025-01-10,92.5,93.23,87.59,91.23,11763 +2025-01-11,91.56,95.36,89.62,93.97,18197 +2025-01-12,92.98,96.86,92.81,94.64,9283 +2025-01-13,94.77,98.72,90.0,98.33,12147 +2025-01-14,96.51,96.57,94.89,96.17,5161 +2025-01-15,94.58,98.54,91.84,98.46,8591 +2025-01-16,99.11,102.3,94.82,102.25,15905 +2025-01-17,102.69,105.59,102.3,104.67,17318 +2025-01-18,105.48,107.27,104.47,105.44,10945 +2025-01-19,106.9,107.1,103.04,106.67,16433 +2025-01-20,107.3,111.41,104.69,109.39,17978 +2025-01-21,108.39,110.91,107.86,108.79,14117 +2025-01-22,106.99,108.36,102.41,104.31,13821 +2025-01-23,102.39,107.22,101.8,103.84,17412 +2025-01-24,105.17,106.51,100.94,103.95,9882 +2025-01-25,104.99,108.95,100.32,105.89,5410 +2025-01-26,107.47,107.99,106.47,107.41,13221 +2025-01-27,108.09,111.4,103.45,111.17,10558 +2025-01-28,111.57,116.11,107.77,108.64,8004 +2025-01-29,110.37,110.61,108.42,109.53,16612 +2025-01-30,109.33,112.36,106.55,112.05,13022 diff --git a/Stocks Trend Analyzer/data/sample_stock03.csv b/Stocks Trend Analyzer/data/sample_stock03.csv new file mode 100644 index 0000000..4e53582 --- /dev/null +++ b/Stocks Trend Analyzer/data/sample_stock03.csv @@ -0,0 +1,31 @@ +Date,Open,High,Low,Close,Volume +2025-01-01,100.93,104.9,99.08,99.77,15210 +2025-01-02,100.31,102.4,96.52,101.39,10881 +2025-01-03,100.48,104.11,98.39,101.23,11772 +2025-01-04,101.04,104.12,96.25,99.0,17810 +2025-01-05,99.14,100.83,95.3,97.33,17595 +2025-01-06,95.54,95.72,95.11,95.58,13414 +2025-01-07,96.51,99.01,92.23,98.83,17530 +2025-01-08,97.32,99.49,93.0,96.73,12801 +2025-01-09,95.28,97.27,93.24,96.35,15185 +2025-01-10,94.42,96.85,91.71,94.65,17157 +2025-01-11,93.16,95.95,88.49,91.15,8168 +2025-01-12,92.19,95.75,89.4,93.63,19000 +2025-01-13,91.9,94.94,91.01,91.98,13420 +2025-01-14,91.63,94.45,89.67,90.71,5258 +2025-01-15,88.88,89.66,84.62,87.42,6393 +2025-01-16,88.44,90.84,85.27,88.25,13772 +2025-01-17,88.45,90.84,88.05,88.99,14996 +2025-01-18,90.38,94.11,86.66,91.35,6479 +2025-01-19,91.97,94.8,89.21,89.73,13860 +2025-01-20,89.42,93.23,88.94,89.65,8816 +2025-01-21,89.78,91.7,88.91,91.53,14919 +2025-01-22,90.19,92.64,89.49,92.22,16733 +2025-01-23,93.33,97.92,91.8,92.94,18898 +2025-01-24,93.55,94.75,92.77,94.67,6126 +2025-01-25,94.29,98.47,91.28,93.34,5306 +2025-01-26,91.4,93.37,87.24,89.12,5931 +2025-01-27,89.79,93.56,85.89,86.08,15499 +2025-01-28,85.68,89.39,83.9,84.06,7531 +2025-01-29,84.73,85.94,83.93,85.1,11372 +2025-01-30,86.63,88.01,83.96,85.36,19958 diff --git a/Stocks Trend Analyzer/data/sample_stock04.csv b/Stocks Trend Analyzer/data/sample_stock04.csv new file mode 100644 index 0000000..3c62544 --- /dev/null +++ b/Stocks Trend Analyzer/data/sample_stock04.csv @@ -0,0 +1,31 @@ +Date,Open,High,Low,Close,Volume +2025-01-01,100.71,104.27,95.83,100.67,10119 +2025-01-02,99.79,104.41,95.1,98.57,7723 +2025-01-03,97.13,101.93,96.65,97.09,17824 +2025-01-04,95.89,100.53,91.0,100.31,14583 +2025-01-05,99.63,103.82,97.11,97.15,18120 +2025-01-06,98.26,99.52,94.82,96.38,19377 +2025-01-07,95.66,99.85,92.87,95.25,5381 +2025-01-08,94.12,98.43,93.67,97.63,19272 +2025-01-09,98.68,100.55,97.58,98.96,5578 +2025-01-10,98.77,99.41,98.41,99.39,18643 +2025-01-11,98.65,100.62,98.57,99.7,11129 +2025-01-12,98.91,99.69,98.2,99.03,5221 +2025-01-13,100.64,101.92,98.79,100.19,8132 +2025-01-14,98.27,102.43,95.84,101.49,5032 +2025-01-15,100.23,103.07,97.94,101.36,6140 +2025-01-16,100.29,102.73,99.69,100.79,14664 +2025-01-17,101.26,102.3,96.63,98.58,8000 +2025-01-18,98.12,100.42,97.18,99.66,14370 +2025-01-19,100.21,104.95,99.37,104.73,13898 +2025-01-20,106.62,109.41,106.01,106.48,16317 +2025-01-21,104.86,109.66,102.37,103.11,5870 +2025-01-22,103.27,105.77,100.22,104.53,10683 +2025-01-23,102.88,103.35,102.69,102.9,10716 +2025-01-24,104.71,108.87,103.9,107.93,15040 +2025-01-25,106.69,109.13,103.57,108.64,10042 +2025-01-26,109.78,110.29,106.38,110.1,15391 +2025-01-27,111.54,116.27,110.26,112.55,16325 +2025-01-28,114.02,118.65,109.72,117.57,10995 +2025-01-29,115.74,117.72,115.48,116.02,9344 +2025-01-30,116.7,121.21,116.49,119.59,19109 diff --git a/Stocks Trend Analyzer/doc/Project Proposal DSA pdf.pdf b/Stocks Trend Analyzer/doc/Project Proposal DSA pdf.pdf new file mode 100644 index 0000000..c80e71e Binary files /dev/null and b/Stocks Trend Analyzer/doc/Project Proposal DSA pdf.pdf differ diff --git a/Stocks Trend Analyzer/doc/TrendSight_Report.pdf b/Stocks Trend Analyzer/doc/TrendSight_Report.pdf new file mode 100644 index 0000000..f09a8da Binary files /dev/null and b/Stocks Trend Analyzer/doc/TrendSight_Report.pdf differ diff --git a/Stocks Trend Analyzer/dsa/__pycache__/array_list.cpython-312.pyc b/Stocks Trend Analyzer/dsa/__pycache__/array_list.cpython-312.pyc index af2cba3..4cb3611 100644 Binary files a/Stocks Trend Analyzer/dsa/__pycache__/array_list.cpython-312.pyc and b/Stocks Trend Analyzer/dsa/__pycache__/array_list.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/dsa/__pycache__/queue.cpython-312.pyc b/Stocks Trend Analyzer/dsa/__pycache__/queue.cpython-312.pyc index aa5079b..9c184f1 100644 Binary files a/Stocks Trend Analyzer/dsa/__pycache__/queue.cpython-312.pyc and b/Stocks Trend Analyzer/dsa/__pycache__/queue.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/dsa/__pycache__/stack.cpython-312.pyc b/Stocks Trend Analyzer/dsa/__pycache__/stack.cpython-312.pyc index 1ed8dd7..eff88e4 100644 Binary files a/Stocks Trend Analyzer/dsa/__pycache__/stack.cpython-312.pyc and b/Stocks Trend Analyzer/dsa/__pycache__/stack.cpython-312.pyc differ diff --git a/Stocks Trend Analyzer/main.py b/Stocks Trend Analyzer/main.py index 4c4e1ec..999218a 100644 --- a/Stocks Trend Analyzer/main.py +++ b/Stocks Trend Analyzer/main.py @@ -1,3 +1,4 @@ +import customtkinter as ctk import tkinter as tk from tkinter import filedialog, messagebox import csv @@ -15,50 +16,77 @@ class StockAnalyzerApp: def __init__(self, master): self.master = master master.title("Stocks Trend Analyzer") - master.geometry("950x700") + master.geometry("1100x720") + ctk.set_appearance_mode("dark") + ctk.set_default_color_theme("blue") # Variables self.prices = ArrayList() self.dates = ArrayList() - self.window_size = tk.IntVar(value=5) # Default moving average window + self.window_size = tk.IntVar(value=5) - # Widgets - self.label = tk.Label(master, text="Stocks Trend Analyzer", font=("Arial", 18)) - self.label.pack(pady=10) + # ------------------ LAYOUT ------------------- + self.main_frame = ctk.CTkFrame(master) + self.main_frame.pack(fill="both", expand=True, padx=10, pady=10) - self.load_button = tk.Button(master, text="Load CSV", command=self.load_csv) - self.load_button.pack(pady=5) + # Left Control Panel + self.left_panel = ctk.CTkFrame(self.main_frame, width=260) + self.left_panel.pack(side="left", fill="y", padx=10, pady=10) - frame = tk.Frame(master) - frame.pack(pady=5) - tk.Label(frame, text="Moving Average Window:").pack(side=tk.LEFT) - self.window_entry = tk.Entry(frame, textvariable=self.window_size, width=5) - self.window_entry.pack(side=tk.LEFT) + # Right Chart Panel + self.right_panel = ctk.CTkFrame(self.main_frame) + self.right_panel.pack(side="right", fill="both", expand=True, padx=10, pady=10) - self.analyze_button = tk.Button(master, text="Analyze Trends", command=self.analyze) - self.analyze_button.pack(pady=5) + # ------------------ LEFT PANEL UI ------------------- + ctk.CTkLabel(self.left_panel, text="Stocks Trend Analyzer", font=("Arial", 22)).pack(pady=15) - self.save_button = tk.Button(master, text="Save Chart", command=self.save_chart) - self.save_button.pack(pady=5) + ctk.CTkButton(self.left_panel, text="Load CSV", command=self.load_csv, width=220).pack(pady=10) - self.figure = plt.Figure(figsize=(8,5), dpi=100) + ctk.CTkLabel(self.left_panel, text="Moving Average Window:", anchor="w").pack(pady=5) + self.window_entry = ctk.CTkEntry(self.left_panel, textvariable=self.window_size, width=80) + self.window_entry.pack(pady=5) + + ctk.CTkButton(self.left_panel, text="Analyze Trends", command=self.analyze, width=220).pack(pady=15) + + ctk.CTkButton(self.left_panel, text="Save Chart", command=self.save_chart, width=220).pack(pady=15) + + # Results Panel (Buy/Sell Info) + ctk.CTkLabel(self.left_panel, text="Analysis Summary", font=("Arial", 18)).pack(pady=10) + + self.buy_label = ctk.CTkLabel(self.left_panel, text="Buy Day: -", font=("Arial", 14)) + self.buy_label.pack(pady=3) + + self.sell_label = ctk.CTkLabel(self.left_panel, text="Sell Day: -", font=("Arial", 14)) + self.sell_label.pack(pady=3) + + self.profit_label = ctk.CTkLabel(self.left_panel, text="Max Profit: -", font=("Arial", 14)) + self.profit_label.pack(pady=3) + + # ------------------ CHART AREA ------------------- + self.figure = plt.Figure(figsize=(7, 5), dpi=100) self.ax = self.figure.add_subplot(111) - self.canvas = FigureCanvasTkAgg(self.figure, master) - self.canvas.get_tk_widget().pack(pady=20) + + self.canvas = FigureCanvasTkAgg(self.figure, self.right_panel) + self.canvas.get_tk_widget().pack(fill="both", expand=True) + + # ------------------ FUNCTIONS ------------------- def load_csv(self): file_path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")]) if not file_path: return try: - with open(file_path, 'r') as csvfile: + with open(file_path, "r") as csvfile: reader = csv.DictReader(csvfile) self.prices.clear() self.dates.clear() + for row in reader: - self.dates.append(row['Date']) - self.prices.append(float(row['Close'])) + self.dates.append(row["Date"]) + self.prices.append(float(row["Close"])) + messagebox.showinfo("Success", f"Loaded {self.prices.size()} records.") + except Exception as e: messagebox.showerror("Error", f"Failed to load CSV: {e}") @@ -72,7 +100,7 @@ def analyze(self): if window < 1: raise ValueError except ValueError: - messagebox.showwarning("Warning", "Window size must be a positive integer.") + messagebox.showwarning("Warning", "Window size must be positive.") return # Trend detection @@ -81,54 +109,58 @@ def analyze(self): # Moving Average ma_module = MovingAverage(window) - moving_avg = ma_module.calculate([self.prices.get(i) for i in range(self.prices.size())]) + moving_avg = ma_module.calculate( + [self.prices.get(i) for i in range(self.prices.size())] + ) # Max Profit - max_profit_module = MaxProfit([self.prices.get(i) for i in range(self.prices.size())]) + price_list = [self.prices.get(i) for i in range(self.prices.size())] + max_profit_module = MaxProfit(price_list) buy_day, sell_day, profit = max_profit_module.best_interval() - # Local High/Low - lh_module = LocalHighLow([self.prices.get(i) for i in range(self.prices.size())]) + # Local Extremes + lh_module = LocalHighLow(price_list) extremes = lh_module.find_local_extremes() - # Plotting + # Plot self.ax.clear() - x_vals = [i for i in range(self.prices.size())] - y_vals = [self.prices.get(i) for i in range(self.prices.size())] + x_vals = list(range(self.prices.size())) + y_vals = price_list - self.ax.plot(x_vals, y_vals, label="Close Price", color="blue") - self.ax.plot(x_vals, moving_avg, label=f"{window}-Day MA", color="orange") + self.ax.plot(x_vals, y_vals, label="Close Price") + self.ax.plot(x_vals, moving_avg, label=f"{window}-Day MA") - # Mark buy/sell - self.ax.scatter(buy_day, y_vals[buy_day], marker="^", color="green", s=100, label="Buy") - self.ax.scatter(sell_day, y_vals[sell_day], marker="v", color="red", s=100, label="Sell") + # Buy/Sell Markers + self.ax.scatter(buy_day, y_vals[buy_day], color="green", marker="^", s=100) + self.ax.scatter(sell_day, y_vals[sell_day], color="red", marker="v", s=100) - # Mark local highs/lows + # High / Low Points for idx, kind, price in extremes: - color = "purple" if kind == "High" else "brown" - self.ax.scatter(idx, price, color=color, marker="o", s=50) + self.ax.scatter(idx, price, color="purple" if kind == "High" else "brown") self.ax.set_title("Stock Trend Analysis") - self.ax.set_xlabel("Day Index") - self.ax.set_ylabel("Price") self.ax.legend() self.canvas.draw() - messagebox.showinfo("Analysis Complete", f"Max Profit: {profit:.2f} (Buy day {buy_day}, Sell day {sell_day})") - - def save_chart(self): + # Update Labels + self.buy_label.configure(text=f"Buy Day: {buy_day}") + self.sell_label.configure(text=f"Sell Day: {sell_day}") + self.profit_label.configure(text=f"Max Profit: {profit:.2f}") + def save_chart(self): project_dir = os.path.abspath(os.path.dirname(__file__)) - charts_dir = os.path.join(project_dir, "charts") os.makedirs(charts_dir, exist_ok=True) - # Save chart - save_path = os.path.join(charts_dir, "generated_charts.png") + save_path = os.path.join(charts_dir, "generated_chart.png") self.figure.savefig(save_path) - messagebox.showinfo("Saved", f"Chart saved to {save_path}") + messagebox.showinfo("Saved", f"Chart saved to:\n{save_path}") + + +# ------------------ MAIN ------------------- if __name__ == "__main__": - root = tk.Tk() + ctk.set_appearance_mode("dark") + root = ctk.CTk() app = StockAnalyzerApp(root) root.mainloop()