diff --git a/bitcoin_trend_analysis.py b/bitcoin_trend_analysis.py index a52b240..799b2a1 100644 --- a/bitcoin_trend_analysis.py +++ b/bitcoin_trend_analysis.py @@ -5,7 +5,22 @@ from scipy.signal import find_peaks import matplotlib.pyplot as plt import matplotlib from sklearn.linear_model import LinearRegression -from matplotlib.widgets import Slider +from sqlalchemy import create_engine, Column, Integer, String, Float, MetaData, Table +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy.exc import OperationalError + + +Base = declarative_base() + +class PriceExtreme(Base): + __tablename__ = 'price_extremes' + + id = Column(Integer, primary_key=True, autoincrement=True) + timestamp = Column(String) + price = Column(Float) + type = Column(String) + prominence = Column(Float) class BitcoinTrendAnalysis: @@ -28,7 +43,6 @@ class BitcoinTrendAnalysis: print("Failed to load data. DataFrame is empty or None.") def adaptive_find_peaks(self, smooth_prices, window, factor, distance): - print(factor) prominences = np.zeros_like(smooth_prices) for i in range(len(smooth_prices)): @@ -38,12 +52,11 @@ class BitcoinTrendAnalysis: local_min = np.min(smooth_prices[start:end]) prominences[i] = (local_max - local_min) * factor - print(prominences) peaks, _ = find_peaks(smooth_prices, prominence=prominences, distance=distance) valleys, _ = find_peaks(-smooth_prices, prominence=prominences, distance=distance) return peaks, valleys, prominences - def analyze_trends_peaks(self, resample_window='D', smoothing_window=10, prominence_factor=0.5, window=30, + def analyze_trends_peaks(self, resample_window='D', smoothing_window=1, prominence_factor=0.5, window=30, distance=None): matplotlib.use('TkAgg') @@ -54,6 +67,7 @@ class BitcoinTrendAnalysis: self.df = self.df.resample(resample_window).agg({'Close': 'last'}) prices = self.df['Close'].values smooth_prices = pd.Series(prices).rolling(window=smoothing_window).mean() + print(f"Smooth prices: {len(smooth_prices)} vs prices {len(prices)}") fig, ax = plt.subplots(figsize=(14, 7)) plt.subplots_adjust(bottom=0.25) @@ -62,18 +76,65 @@ class BitcoinTrendAnalysis: distance=distance) ax.plot(self.df.index, smooth_prices, label='Bitcoin Smooth Price') + ax.plot(self.df.index, prices, label='Bitcoin Price') ax.scatter(self.df.index[peaks], smooth_prices[peaks], color='green', s=100, marker='^', label='Local Maxima') ax.scatter(self.df.index[valleys], smooth_prices[valleys], color='red', s=100, marker='v', label='Local Minima') - for peak, valley in zip(peaks, valleys): - ax.plot([self.df.index[peak], self.df.index[valley]], [smooth_prices[peak], smooth_prices[valley]], - color='orange', lw=1) - ax.set_title(f'Bitcoin Price Trends Analysis\nfactor={prominence_factor}') ax.set_xlabel('Date') ax.set_ylabel('Price') ax.legend() ax.grid(True) + + engine = create_engine('sqlite:///bitcoin_trends.db') + Base.metadata.create_all(engine) + + Session = sessionmaker(bind=engine) + session = Session() + + try: + session.query(PriceExtreme).delete() + except OperationalError as e: + print(f"Error occurred: {e}. The table may not exist.") + + extremes_to_insert = [] + + with open(f'peaks_and_valleys_{resample_window}_{smoothing_window}_{prominence_factor}_{window}_{distance}.txt', 'w') as file: + for peak in peaks: + peak_date = self.df.index[peak].strftime('%Y-%m-%d %H:%M:%S') + peak_price = float(smooth_prices[peak]) + peak_prominence = float(prominences[peak]) + extremes_to_insert.append( + PriceExtreme( + timestamp=peak_date, + price=peak_price, + type='peak', + prominence=peak_prominence + ) + ) + file.write(f"Peak: {peak_date}, Price: {peak_price}, Prominence: {peak_prominence}\n") + + for valley in valleys: + valley_date = self.df.index[valley].strftime('%Y-%m-%d %H:%M:%S') + valley_price = float(smooth_prices[valley]) + valley_prominence = float(prominences[valley]) + extremes_to_insert.append( + PriceExtreme( + timestamp=valley_date, + price=valley_price, + type='valley', + prominence=valley_prominence + ) + ) + file.write(f"Valley: {valley_date}, Price: {valley_price}, Prominence: {valley_prominence}\n") + + session.bulk_save_objects(extremes_to_insert) + + session.commit() + session.close() + + print(f"Saved {len(peaks)} peaks and {len(valleys)} valleys to bitcoin_trends.db") + print("Peaks and valleys written to peaks_and_valleys.txt") plt.show()