如何对加密货币数据集分段并计算7天/21天周期的BTC价格斜率?
解决加密货币多周期斜率计算问题
核心思路
先明确两个前提:确保你的时间戳y是按时间升序排列的;要计算的是「价格随时间变化的斜率」(即时间为自变量,价格为因变量),因此linregress的参数顺序应为linregress(时间戳, 价格),这和你原代码的参数顺序相反,需要注意。
下面分两种常见场景给出实现方案:
场景1:非重叠连续时间块(每7天/21天为一个独立分段)
把数据集按固定时间跨度切分成非重叠的块,最后不足周期长度的剩余数据单独作为一个块计算斜率。
用Pandas实现(推荐,适合结构化数据集)
import pandas as pd from scipy.stats import linregress # 假设你的数据存储在DataFrame中,包含'timestamp'(时间戳列)和'price'(价格列) df['timestamp'] = pd.to_datetime(df['timestamp']) # 转成datetime格式 df = df.set_index('timestamp') # 设置时间为索引 # 定义要计算的周期 periods = ['7D', '21D'] for period in periods: # 按时间窗口分组,非重叠 grouped = df.groupby(pd.Grouper(freq=period)) period_slopes = [] for _, group in grouped: if len(group) < 2: # 至少2个数据点才能计算斜率 period_slopes.append(None) continue # 把时间索引转成秒级数值,作为自变量x time_values = group.index.astype('int64') // 10**9 price_values = group['price'].values # 计算斜率 slope, _, _, _, _ = linregress(time_values, price_values) period_slopes.append(slope) print(f"{period} 周期的斜率列表:", period_slopes)
用Numpy实现(适合纯数组格式数据)
import numpy as np from scipy.stats import linregress def get_period_slopes(X, y, period_days): # 先确保数据按时间戳升序排列 sorted_idx = np.argsort(y) X_sorted = X[sorted_idx] y_sorted = y[sorted_idx] period_seconds = period_days * 24 * 3600 # 转成秒级时间跨度 slopes = [] start_idx = 0 total_points = len(X_sorted) while start_idx < total_points: start_time = y_sorted[start_idx] end_time = start_time + period_seconds # 找到当前时间块的结束索引 end_idx = np.searchsorted(y_sorted, end_time, side='right') # 提取当前块的数据 seg_X = X_sorted[start_idx:end_idx] seg_y = y_sorted[start_idx:end_idx] if len(seg_X) >= 2: slope, _, _, _, _ = linregress(seg_y, seg_X) slopes.append(slope) else: slopes.append(None) start_idx = end_idx return slopes # 计算7天和21天斜率 slopes_7d = get_period_slopes(X, y, 7) slopes_21d = get_period_slopes(X, y, 21) print("7天周期斜率:", slopes_7d) print("21天周期斜率:", slopes_21d)
场景2:滚动时间窗口(重叠连续窗口,每个数据点对应一个周期斜率)
以每个数据点为终点,取过去7天/21天的所有数据计算斜率,适合观察随时间变化的趋势连续性。
import pandas as pd from scipy.stats import linregress # 预处理数据(同场景1) df['timestamp'] = pd.to_datetime(df['timestamp']) df = df.set_index('timestamp') window_sizes = ['7D', '21D'] def calc_slope(window): if len(window) < 2: return None time_vals = window.index.astype('int64') // 10**9 price_vals = window['price'].values slope, _, _, _, _ = linregress(time_vals, price_vals) return slope for window in window_sizes: # 按时间跨度生成滚动窗口,计算每个窗口的斜率 df[f'{window}_slope'] = df.rolling(window=window).apply(calc_slope, raw=False) print(f"{window} 滚动窗口斜率已添加到DataFrame")
注意事项
- 时间戳单位:如果你的时间戳是毫秒级,需要把
period_seconds改成period_days * 24 * 3600 * 1000,对应调整代码中的时间转换逻辑。 - 异常处理:如果某段数据点少于2个,无法计算线性回归,代码中返回
None,你可以根据需求改为0或其他默认值。
内容的提问来源于stack exchange,提问作者shayanTH78
相关产品推荐
相关产品推荐

