红叶堪摘楼主2025-04-24 06:30
只看TA
用ai生成了个代码,你看看就知道原理了。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from scipy.signal import savgol_filter
from scipy.optimize import curve_fit
# 获取示例数据
def get_stock_data(ticker= SPY , period= 2y ):
stock = yf.Ticker(ticker)
df = stock.history(period=period)
return df
# 计算55日均线及其斜率
def calculate_ma_slope(df, ma_period=55, slope_window=5):
# 计算均线
df[‘MA55‘] = df[‘Close‘].rolling(window=ma_period).mean()
# 计算每日斜率 (一阶导数)
df[‘Slope‘] = df[‘MA55‘].diff(1)
# 计算平滑斜率 (使用N日窗口)
df[‘SmoothSlope‘] = df[‘MA55‘].diff(slope_window) / slope_window
# 计算斜率变化 (二阶导数)
df[‘SlopeChange‘] = df[‘Slope‘].diff(1)
# 计算平滑斜率变化
df[‘SmoothSlopeChange‘] = df[‘SmoothSlope‘].diff(1)
return df
# 使用多项式拟合识别圆润变化
def polynomial_fit(df, window=30, degree=3):
# 初始化结果列
df[‘PolySlope‘] = np.nan
df[‘PolySlopeChange‘] = np.nan
df[‘Curvature‘] = np.nan
# 定义多项式函数
def poly_func(x, *params):
y = 0
for i, param in enumerate(params):
y += param * (x ** i)
return y
for i in range(window, len(df)):
try:
# 选取窗口数据
y = df[‘MA55‘].iloc[i-window:i].values
x = np.arange(len(y))
# 拟合多项式
params, _ = curve_fit(poly_func, x, y, p0=[0]*(degree+1))
# 计算多项式拟合的斜率(一阶导数)
deriv1 = np.zeros(degree)
for j in range(degree):
deriv1[j] = (j+1) * params[j+1] * (window-1)**j
slope = np.sum(deriv1)
# 计算斜率变化(二阶导数)
deriv2 = np.zeros(degree-1)
for j in range(degree-1):
deriv2[j] = (j+1)*(j+2) * params[j+2] * (window-1)**j
slope_change = np.sum(deriv2)
# 计算曲率
curvature = abs(slope_change) / ((1 + slope**2)**(1.5))
# 保存结果
df.iloc[i, df.columns.get_loc(‘PolySlope‘)] = slope
df.iloc[i, df.columns.get_loc(‘PolySlopeChange‘)] = slope_change
df.iloc[i, df.columns.get_loc(‘Curvature‘)] = curvature
except:
continue
return df
# 使用Savitzky-Golay滤波器平滑数据
def smooth_data(df, window=21, poly=3):
df[‘MA55_Smooth‘] = savgol_filter(df[‘MA55‘].dropna(), window, poly)
return df
# 识别圆润变化点
def identify_rounded_turns(df, threshold=0.7):
df[‘RoundedTurn‘] = 0
# 寻找斜率变化方向改变且曲率较高的点
for i in range(2, len(df)):
# 斜率由负变正或由正变负
slope_change_direction = (df[‘PolySlope‘].iloc[i-1] * df[‘PolySlope‘].iloc
= 0)
# 曲率较高(使用百分比排名)high_curvature = df[‘Curvature‘].iloc df[‘Curvature‘].quantile(threshold)
# 二阶导数变化平滑
smooth_change = abs(df[‘PolySlopeChange‘].iloc - df[‘PolySlopeChange‘].iloc[i-1]) \
abs(df[‘PolySlopeChange‘].iloc[i-1] - df[‘PolySlopeChange‘].iloc[i-2])
if slope_change_direction and high_curvature and smooth_change:
df.iloc[i, df.columns.get_loc(‘RoundedTurn‘)] = 1 if df[‘PolySlope‘].iloc 0 else -1
return df
# 可视化结果def plot_results(df):plt.figure(figsize=(14, 12))
# 价格与均线ax1 = plt.subplot(4, 1, 1)ax1.plot(df.index, df[‘Close‘], label=‘价格‘, alpha=0.5)
ax1.plot(df.index, df[‘MA55‘], label=‘55日均线‘, linewidth=2)
ax1.scatter(df[df[‘RoundedTurn‘] == 1].index,
df[df[‘RoundedTurn‘] == 1][‘MA55‘],
color=‘green‘, marker=‘^‘, s=100, label=‘圆润上升转折‘)
ax1.scatter(df[df[‘RoundedTurn‘] == -1].index,
df[df[‘RoundedTurn‘] == -1][‘MA55‘],
color=‘red‘, marker=‘v‘, s=100, label=‘圆润下降转折‘)
ax1.set_title(‘价格与55日均线‘)
ax1.legend()
# 斜率
ax2 = plt.subplot(4, 1, 2, sharex=ax1)
ax2.plot(df.index, df[‘PolySlope‘], label=‘多项式拟合斜率‘, color=‘blue‘)
ax2.axhline(y=0, color=‘r‘, linestyle=‘-‘, alpha=0.3)
ax2.set_title(‘55日均线斜率‘)
ax2.legend()
# 斜率变化
ax3 = plt.subplot(4, 1, 3, sharex=ax1)
ax3.plot(df.index, df[‘PolySlopeChange‘], label=‘斜率变化‘, color=‘purple‘)
ax3.axhline(y=0, color=‘r‘, linestyle=‘-‘, alpha=0.3)
ax3.set_title(‘斜率变化率(二阶导数)‘)
ax3.legend()
# 曲率
ax4 = plt.subplot(4, 1, 4, sharex=ax1)
ax4.plot(df.index, df[‘Curvature‘], label=‘曲率‘, color=‘green‘)
ax4.set_title(‘曲率 - 衡量圆润度‘)
ax4.legend()
plt.tight_layout()
plt.show()
# 主函数
def main():
# 获取数据
print( 获取示例数据... )
df = get_stock_data()
# 计算55日均线及其斜率
print( 计算均线斜率... )
df = calculate_ma_slope(df)
# 平滑数据
print( 平滑数据... )
df = smooth_data(df)
# 多项式拟合识别圆润变化
print( 进行多项式拟合分析... )
df = polynomial_fit(df)
# 识别圆润变化点
print( 识别圆润变化点... )
df = identify_rounded_turns(df)
# 移除NaN值
df = df.dropna()
# 显示结果
print( 显示结果... )
plot_results(df)
return df
# 运行程序
if __name__ == __main__ :
result_df = main()
# 展示最近的圆润变化点
recent_turns = result_df[result_df[‘RoundedTurn‘] != 0].tail(5)
print( \n最近的圆润变化点: )
print(recent_turns[[‘Close‘, ‘MA55‘, ‘PolySlope‘, ‘PolySlopeChange‘, ‘Curvature‘, ‘RoundedTurn‘]])
辣死你可乎2025-04-24 00:02
圆润是一个模糊买点,我觉得也是我的突破方向。想上一个台阶估计就不能所在精确买点里。关于圆润我有点疑问,就是它的成本会不会太高了。它等于是追涨吧。但你不是又说10-30cm做反趋势比较好吗?比如你举的舒
[展开]
第890楼