diff --git a/main.py b/main.py index d17a3ae..a568aef 100644 --- a/main.py +++ b/main.py @@ -5,13 +5,17 @@ from cycle_detector import CycleDetector # Load data from CSV file instead of database data = pd.read_csv('data/btcusd_1-day_data.csv') + # Convert datetime column to datetime type -one_month_ago = pd.to_datetime('2025-04-05') -daily_data = data[pd.to_datetime(data['datetime']) >= one_month_ago] +start_date = pd.to_datetime('2025-04-01') +stop_date = pd.to_datetime('2025-05-06') + +daily_data = data[(pd.to_datetime(data['datetime']) >= start_date) & + (pd.to_datetime(data['datetime']) < stop_date)] print(f"Number of data points: {len(daily_data)}") trend_detector = TrendDetectorSimple(daily_data, verbose=True) -trends = trend_detector.detect_trends(width=1) +trends = trend_detector.detect_trends() trend_detector.plot_trends(trends) #trend_detector = TrendDetectorMACD(daily_data, True) diff --git a/trend_detector_simple.py b/trend_detector_simple.py index 80777f0..c2544f2 100644 --- a/trend_detector_simple.py +++ b/trend_detector_simple.py @@ -33,7 +33,7 @@ class TrendDetectorSimple: self.logger.info(f"Initialized TrendDetectorSimple with {len(self.data)} data points") - def detect_trends(self, width): + def detect_trends(self): """ Detect trends by identifying local minima and maxima in the price data using scipy.signal.find_peaks. @@ -45,13 +45,13 @@ class TrendDetectorSimple: Returns: - DataFrame with columns for timestamps, prices, and trend indicators """ - self.logger.info(f"Detecting trends with width {width}") + self.logger.info(f"Detecting trends") df = self.data.copy() close_prices = df['close'].values - max_peaks, _ = find_peaks(close_prices, width=width) - min_peaks, _ = find_peaks(-close_prices, width=width) + max_peaks, _ = find_peaks(close_prices) + min_peaks, _ = find_peaks(-close_prices) self.logger.info(f"Found {len(min_peaks)} local minima and {len(max_peaks)} local maxima") @@ -63,7 +63,38 @@ class TrendDetectorSimple: for peak in min_peaks: df.at[peak, 'is_min'] = True - + # Find consecutive peaks and add the valley in between + if len(max_peaks) >= 2: + for i in range(len(max_peaks) - 1): + start_idx = max_peaks[i] + end_idx = max_peaks[i + 1] + + # Find the minimum value between these two peaks + segment = close_prices[start_idx:end_idx + 1] + valley_idx = start_idx + np.argmin(segment) + + # Add to min_peaks if not already there + if valley_idx not in min_peaks: + min_peaks = np.append(min_peaks, valley_idx) + df.at[valley_idx, 'is_min'] = True + self.logger.info(f"Added valley at index {valley_idx} between peaks {start_idx} and {end_idx}") + + # Find consecutive valleys and add the peak in between + if len(min_peaks) >= 2: + min_peaks = np.sort(min_peaks) # Sort after potential additions + for i in range(len(min_peaks) - 1): + start_idx = min_peaks[i] + end_idx = min_peaks[i + 1] + + # Find the maximum value between these two valleys + segment = close_prices[start_idx:end_idx + 1] + peak_idx = start_idx + np.argmax(segment) + + # Add to max_peaks if not already there + if peak_idx not in max_peaks: + max_peaks = np.append(max_peaks, peak_idx) + df.at[peak_idx, 'is_max'] = True + self.logger.info(f"Added peak at index {peak_idx} between valleys {start_idx} and {end_idx}") result = df[['datetime', 'close', 'is_min', 'is_max']]