褚宏光 6d545eb231 Enhance converging triangle detection with new features and documentation updates
- Added support for a detailed chart mode in plot_converging_triangles.py, allowing users to visualize all pivot points and fitting lines.
- Improved pivot fitting logic to utilize multiple representative points, enhancing detection accuracy and reducing false positives.
- Introduced a new real-time detection mode with flexible zone parameters for better responsiveness in stock analysis.
- Updated README.md and USAGE.md to reflect new features and usage instructions.
- Added multiple documentation files detailing recent improvements, including pivot point fitting and visualization enhancements.
- Cleaned up and archived outdated scripts to streamline the project structure.
2026-01-26 16:21:36 +08:00

173 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
演示分段选择枢轴点的逻辑
展示如何将枢轴点按时间分为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()