More analysis WIP
This commit is contained in:
parent
1decd0d0ce
commit
cbc6a7493d
4
main.py
4
main.py
@ -15,8 +15,8 @@ daily_data = data[(pd.to_datetime(data['datetime']) >= start_date) &
|
||||
print(f"Number of data points: {len(daily_data)}")
|
||||
|
||||
trend_detector = TrendDetectorSimple(daily_data, verbose=True)
|
||||
trends = trend_detector.detect_trends()
|
||||
trend_detector.plot_trends(trends)
|
||||
trends, analysis_results = trend_detector.detect_trends()
|
||||
trend_detector.plot_trends(trends, analysis_results)
|
||||
|
||||
#trend_detector = TrendDetectorMACD(daily_data, True)
|
||||
#trends = trend_detector.detect_trends_MACD_signal()
|
||||
|
||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -3,6 +3,7 @@ import numpy as np
|
||||
import logging
|
||||
from scipy.signal import find_peaks
|
||||
import matplotlib.dates as mdates
|
||||
from scipy import stats
|
||||
|
||||
class TrendDetectorSimple:
|
||||
def __init__(self, data, verbose=False):
|
||||
@ -63,11 +64,50 @@ class TrendDetectorSimple:
|
||||
for peak in min_peaks:
|
||||
df.at[peak, 'is_min'] = True
|
||||
|
||||
result = df[['datetime', 'close', 'is_min', 'is_max']]
|
||||
result = df[['datetime', 'close', 'is_min', 'is_max']].copy()
|
||||
|
||||
return result
|
||||
# Perform linear regression on min_peaks and max_peaks
|
||||
self.logger.info("Performing linear regression on min and max peaks")
|
||||
min_prices = df['close'].iloc[min_peaks].values
|
||||
max_prices = df['close'].iloc[max_peaks].values
|
||||
|
||||
# Linear regression for min peaks if we have at least 2 points
|
||||
min_slope, min_intercept, min_r_value, _, _ = stats.linregress(min_peaks, min_prices)
|
||||
# Linear regression for max peaks if we have at least 2 points
|
||||
max_slope, max_intercept, max_r_value, _, _ = stats.linregress(max_peaks, max_prices)
|
||||
|
||||
def plot_trends(self, trend_data):
|
||||
# Calculate Simple Moving Averages (SMA) for 7 and 15 periods
|
||||
self.logger.info("Calculating SMA-7 and SMA-15")
|
||||
|
||||
# Calculate SMA values and exclude NaN values
|
||||
sma_7 = df['close'].rolling(window=7).mean().dropna().values
|
||||
sma_15 = df['close'].rolling(window=15).mean().dropna().values
|
||||
|
||||
# Add SMA values to regression_results
|
||||
analysis_results = {}
|
||||
analysis_results['linear_regression'] = {
|
||||
'min': {
|
||||
'slope': min_slope,
|
||||
'intercept': min_intercept,
|
||||
'r_squared': min_r_value ** 2
|
||||
},
|
||||
'max': {
|
||||
'slope': max_slope,
|
||||
'intercept': max_intercept,
|
||||
'r_squared': max_r_value ** 2
|
||||
}
|
||||
}
|
||||
analysis_results['sma'] = {
|
||||
'7': sma_7,
|
||||
'15': sma_15
|
||||
}
|
||||
|
||||
self.logger.info(f"Min peaks regression: slope={min_slope:.4f}, intercept={min_intercept:.4f}, r²={min_r_value**2:.4f}")
|
||||
self.logger.info(f"Max peaks regression: slope={max_slope:.4f}, intercept={max_intercept:.4f}, r²={max_r_value**2:.4f}")
|
||||
|
||||
return result, analysis_results
|
||||
|
||||
def plot_trends(self, trend_data, analysis_results):
|
||||
"""
|
||||
Plot the price data with detected trends using a candlestick chart.
|
||||
|
||||
@ -116,12 +156,35 @@ class TrendDetectorSimple:
|
||||
min_indices = trend_data.index[trend_data['is_min'] == True].tolist()
|
||||
if min_indices:
|
||||
min_y = [df['close'].iloc[i] for i in min_indices]
|
||||
ax.scatter(min_indices, min_y, color='black', s=200, marker='^', label='Local Minima', zorder=100)
|
||||
ax.scatter(min_indices, min_y, color='darkred', s=200, marker='^', label='Local Minima', zorder=100)
|
||||
|
||||
max_indices = trend_data.index[trend_data['is_max'] == True].tolist()
|
||||
if max_indices:
|
||||
max_y = [df['close'].iloc[i] for i in max_indices]
|
||||
ax.scatter(max_indices, max_y, color='black', s=200, marker='v', label='Local Maxima', zorder=100)
|
||||
ax.scatter(max_indices, max_y, color='darkgreen', s=200, marker='v', label='Local Maxima', zorder=100)
|
||||
|
||||
if analysis_results:
|
||||
x_vals = np.arange(len(df))
|
||||
# Minima regression line (support)
|
||||
min_slope = analysis_results['linear_regression']['min']['slope']
|
||||
min_intercept = analysis_results['linear_regression']['min']['intercept']
|
||||
min_line = min_slope * x_vals + min_intercept
|
||||
ax.plot(x_vals, min_line, 'g--', linewidth=2, label='Minima Regression')
|
||||
|
||||
# Maxima regression line (resistance)
|
||||
max_slope = analysis_results['linear_regression']['max']['slope']
|
||||
max_intercept = analysis_results['linear_regression']['max']['intercept']
|
||||
max_line = max_slope * x_vals + max_intercept
|
||||
ax.plot(x_vals, max_line, 'r--', linewidth=2, label='Maxima Regression')
|
||||
|
||||
# SMA-7 line
|
||||
sma_7 = analysis_results['sma']['7']
|
||||
ax.plot(x_vals, sma_7, 'y-', linewidth=2, label='SMA-7')
|
||||
|
||||
# SMA-15 line
|
||||
# sma_15 = analysis_results['sma']['15']
|
||||
# valid_idx_15 = ~np.isnan(sma_15)
|
||||
# ax.plot(x_vals[valid_idx_15], sma_15[valid_idx_15], 'm-', linewidth=2, label='SMA-15')
|
||||
|
||||
# Set title and labels
|
||||
ax.set_title('Price Candlestick Chart with Local Minima and Maxima', fontsize=14)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user