""" 演示分段选择枢轴点的逻辑 展示如何将枢轴点按时间分为3段,并在每段中选择最具代表性的点 """ import numpy as np import sys import os sys.path.append(os.path.join(os.path.dirname(__file__), "..", "src")) def demo_segmentation(pivot_indices, pivot_values, mode="upper"): """ 演示分段选择逻辑 Args: pivot_indices: 枢轴点的时间索引 (X坐标) pivot_values: 枢轴点的价格值 (Y坐标) mode: "upper" 或 "lower" """ print("\n" + "="*70) print(f"分段选择演示 - {mode.upper()} 模式") print("="*70) # 按时间排序 sort_idx = np.argsort(pivot_indices) x_sorted = pivot_indices[sort_idx] y_sorted = pivot_values[sort_idx] n = len(x_sorted) print(f"\n[步骤1] 按时间排序所有枢轴点") print(f" 枢轴点总数: {n}") print(f" 时间索引 (X): {x_sorted}") print(f" 价格值 (Y): {y_sorted}") # 判断是否需要分段 if n <= 4: print(f"\n[步骤2] 点数 <= 4,直接使用所有点(不分段)") selected_mask = np.ones(n, dtype=bool) selected_x = x_sorted selected_y = y_sorted print(f" 选中索引: {list(range(n))}") print(f" 选中点数: {n}") return selected_x, selected_y # 分段逻辑 print(f"\n[步骤2] 点数 > 4,进行分段选择") segment_size = n // 3 print(f" 每段大小: {n} // 3 = {segment_size}") segments = [ range(0, min(segment_size, n)), range(segment_size, min(2 * segment_size, n)), range(2 * segment_size, n), ] print(f"\n[步骤3] 分3段,并在每段中选择代表性点") print(f" 选择规则: {mode.upper()} 模式 -> 每段选{'最高点' if mode == 'upper' else '最低点'}") selected_mask = np.zeros(n, dtype=bool) selected_details = [] for seg_num, seg in enumerate(segments, 1): if len(seg) == 0: continue seg_list = list(seg) seg_x = x_sorted[seg_list] seg_y = y_sorted[seg_list] print(f"\n 第{seg_num}段:") print(f" 索引范围: [{seg.start}, {seg.stop})") print(f" 包含点数: {len(seg_list)}") print(f" 时间索引: {seg_x}") print(f" 价格值: {seg_y}") if mode == "upper": best_idx_in_seg = np.argmax(seg_y) print(f" 最高价格: {seg_y[best_idx_in_seg]:.2f}") else: best_idx_in_seg = np.argmin(seg_y) print(f" 最低价格: {seg_y[best_idx_in_seg]:.2f}") selected_global_idx = seg_list[best_idx_in_seg] selected_mask[selected_global_idx] = True print(f" → 选中: 索引{selected_global_idx} (时间={x_sorted[selected_global_idx]}, 价格={y_sorted[selected_global_idx]:.2f})") selected_details.append({ 'seg': seg_num, 'idx': selected_global_idx, 'x': x_sorted[selected_global_idx], 'y': y_sorted[selected_global_idx] }) selected_x = x_sorted[selected_mask] selected_y = y_sorted[selected_mask] print(f"\n[步骤4] 选中的枢轴点总结") print(f" 选中点数: {len(selected_x)}/{n}") print(f" 选中时间: {selected_x}") print(f" 选中价格: {selected_y}") print(f"\n[步骤5] 线性回归拟合") if len(selected_x) >= 2: a, b = np.polyfit(selected_x, selected_y, deg=1) print(f" 拟合直线: y = {a:.6f} * x + {b:.2f}") print(f" 斜率: {a:.6f} ({'下降' if a < 0 else '上升' if a > 0 else '水平'})") else: print(f" 点数不足,无法拟合") return selected_x, selected_y def main(): print("\n" + "="*70) print("分段选择枢轴点 - 原理演示") print("="*70) # 示例1: 6个高点枢轴点 (模拟SZ002343的情况) print("\n" + "█"*70) print("示例1: 6个高点枢轴点 - 上沿拟合") print("█"*70) # 假设的6个高点枢轴点 (时间索引, 价格) ph_indices = np.array([40, 80, 120, 160, 200, 230]) ph_values = np.array([9.8, 9.5, 10.0, 9.7, 9.2, 8.9]) demo_segmentation(ph_indices, ph_values, mode="upper") # 示例2: 4个低点枢轴点 print("\n\n" + "█"*70) print("示例2: 4个低点枢轴点 - 下沿拟合") print("█"*70) pl_indices = np.array([60, 140, 200, 235]) pl_values = np.array([5.2, 6.5, 7.4, 6.8]) demo_segmentation(pl_indices, pl_values, mode="lower") # 示例3: 8个高点枢轴点(更多点的情况) print("\n\n" + "█"*70) print("示例3: 8个高点枢轴点 - 上沿拟合") print("█"*70) ph_indices_large = np.array([20, 50, 80, 110, 140, 170, 200, 230]) ph_values_large = np.array([42.5, 41.8, 42.0, 41.2, 40.5, 40.0, 39.5, 39.0]) demo_segmentation(ph_indices_large, ph_values_large, mode="upper") print("\n" + "="*70) print("总结") print("="*70) print(""" 分段选择的核心思想: 1. 将时间轴均匀分为3段 (前1/3、中1/3、后1/3) 2. 在每段中选择最具代表性的点: - 上沿:选该段的最高点(形成下边界) - 下沿:选该段的最低点(形成上边界) 3. 用选中的3个点进行线性回归,拟合趋势线 优点: ✓ 时间均衡:确保前、中、后都有点参与拟合 ✓ 代表性强:每段选最极值点,确保线是真正的边界 ✓ 稳定性好:多点回归比两点连线更稳健 ✓ 覆盖性好:确保趋势线能包络所有枢轴点 """) if __name__ == "__main__": main()