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)}")
|
print(f"Number of data points: {len(daily_data)}")
|
||||||
|
|
||||||
trend_detector = TrendDetectorSimple(daily_data, verbose=True)
|
trend_detector = TrendDetectorSimple(daily_data, verbose=True)
|
||||||
trends = trend_detector.detect_trends()
|
trends, analysis_results = trend_detector.detect_trends()
|
||||||
trend_detector.plot_trends(trends)
|
trend_detector.plot_trends(trends, analysis_results)
|
||||||
|
|
||||||
#trend_detector = TrendDetectorMACD(daily_data, True)
|
#trend_detector = TrendDetectorMACD(daily_data, True)
|
||||||
#trends = trend_detector.detect_trends_MACD_signal()
|
#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
|
import logging
|
||||||
from scipy.signal import find_peaks
|
from scipy.signal import find_peaks
|
||||||
import matplotlib.dates as mdates
|
import matplotlib.dates as mdates
|
||||||
|
from scipy import stats
|
||||||
|
|
||||||
class TrendDetectorSimple:
|
class TrendDetectorSimple:
|
||||||
def __init__(self, data, verbose=False):
|
def __init__(self, data, verbose=False):
|
||||||
@ -63,11 +64,50 @@ class TrendDetectorSimple:
|
|||||||
for peak in min_peaks:
|
for peak in min_peaks:
|
||||||
df.at[peak, 'is_min'] = True
|
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
|
||||||
|
|
||||||
def plot_trends(self, trend_data):
|
# 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)
|
||||||
|
|
||||||
|
# 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.
|
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()
|
min_indices = trend_data.index[trend_data['is_min'] == True].tolist()
|
||||||
if min_indices:
|
if min_indices:
|
||||||
min_y = [df['close'].iloc[i] for i in 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()
|
max_indices = trend_data.index[trend_data['is_max'] == True].tolist()
|
||||||
if max_indices:
|
if max_indices:
|
||||||
max_y = [df['close'].iloc[i] for i in 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
|
# Set title and labels
|
||||||
ax.set_title('Price Candlestick Chart with Local Minima and Maxima', fontsize=14)
|
ax.set_title('Price Candlestick Chart with Local Minima and Maxima', fontsize=14)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user