易得程序化交易技术论坛

登录 | 注册

积分: 0 |用户组: 游客

搜索
查看: 1949|回复: 1

求之前涨停的收盘价跟当前K线收盘价最接近的位置

[复制链接]

22

主题

65

帖子

1423

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1423
发表于 2022-9-10 12:38:59 | 显示全部楼层 |阅读模式

  1. function recentlike // 求之前涨停的收盘价跟当前K线收盘价最接近的位置
  2. begin
  3.     minprice := 99999999;
  4.     findpos := -1;
  5.     for i = barpos downto 2 do
  6.     begin
  7.         upStop := c[i]/c[i-1] >= 1.096;   // 涨停, 涨停的算法自己调整一下
  8.         if (upStop) then
  9.         begin
  10.             diff := abs(c[barpos]-c[i]); // 差值
  11.             if (diff < minprice) then
  12.             begin
  13.                 minprice := diff;
  14.                 findpos := i;
  15.             end
  16.         end
  17.     end
  18.     return findpos;  // 返回之前涨停的收盘价跟当前K线收盘价最接近的位置
  19. end


  20. if (IsLastBar) then // 只算最后一根K线,不然每根K线重复找一遍很慢
  21.     a:recentlike;
复制代码
回复

使用道具 举报

8

主题

37

帖子

1586

积分

金牌会员

Rank: 6Rank: 6

积分
1586
QQ
发表于 2025-3-9 15:37:57 | 显示全部楼层
本帖最后由 cheetor 于 2025-3-9 15:54 编辑

优化后代码
  1. function RecentLike()
  2. begin
  3.     min_diff := Infinity;  // 初始化为无穷大
  4.     find_pos := -1;        // 未找到时返回-1
  5.    
  6.     // 从当前K线向前遍历到第2根K线(确保i-1有效)
  7.     if (BarPos >= 1) then
  8.     begin
  9.         for i = BarPos downto 1 do  // 索引从0开始时调整为 downto 0
  10.         begin
  11.             // 涨停判断:当日收盘价 >= 前一日收盘价 * 1.096
  12.             is_up_limit := (C[i] >= C[i-1] * 1.096);
  13.             
  14.             if (is_up_limit) then
  15.             begin
  16.                 // 计算当前收盘价与涨停K线收盘价的绝对差值
  17.                 current_diff := Abs(C[BarPos] - C[i]);
  18.                
  19.                 // 更新最小差值及位置
  20.                 if (current_diff < min_diff) then
  21.                 begin
  22.                     min_diff := current_diff;
  23.                     find_pos := i;
  24.                 end
  25.             end
  26.         end
  27.     end
  28.    
  29.     return find_pos;
  30. end

  31. // 仅在最后一根K线调用以提升性能
  32. if (IsLastBar) then
  33.     a:RecentLike();
复制代码


优化说明
1. 涨停判断逻辑优化
  • 原问题:原代码通过 C/C[i-1] >= 1.096 判断涨停,可能因浮点数精度问题导致误差(例如 1.0955 四舍五入后误判)。
  • 改进:改用乘法避免除法精度问题:
    1. is_up_limit := (C[i] >= C[i-1] * 1.096);
    复制代码

2. 索引边界处理
  • 原问题:未明确处理 BarPos < 2 时的越界风险。
  • 改进:增加条件 if (BarPos >= 1),确保 i-1 有效(假设索引从0开始)。
3. 变量命名与初始化
  • 原问题:minprice 和 findpos 的命名易混淆(实际记录的是差值而非价格)。
  • 改进:
    • min_diff:更清晰表示最小差值。
    • Infinity 初始化:避免硬编码 99999999,适配极端值场景。

4. 性能优化
  • 限制调用频率:通过 IsLastBar 仅在最后一根K线计算,避免历史K线重复遍历。
  • 短路逻辑(可选) :若允许近似值,可设定阈值(如 min_diff < 0.01)时提前终止循环,但需权衡准确性。

边界案例测试[td]
场景数据示例预期输出
无涨停历史全部K线涨幅<10%-1
多个涨停且差值相同涨停价分别为10, 20, 当前价15最近的位置(i最大)
首个K线为涨停索引0的K线涨停(需平台支持i=0)0

应用场景
  • 量化策略:

    • 寻找近期涨停后回调到特定价位的股票,作为买入信号。
    • 示例:if RecentLike() != -1 and C < C[RecentLike()] then Buy;
  • 技术分析:

    • 结合成交量分析涨停有效性(如放量涨停后缩量回调)。
  • 风险控制:

    • 监控股价远离最近涨停价时触发预警。


高级优化思路(如需高频计算)
  • 缓存涨停位置:
    1. // 全局缓存涨停位置数组
    2. var up_limit_bars = Array();

    3. // 每根K线更新缓存
    4. if (BarPos > 0) then
    5. begin
    6.     is_up_limit := (C[BarPos] >= C[BarPos-1] * 1.096);
    7.     if (is_up_limit) then
    8.         up_limit_bars.Push(BarPos);
    9. end

    10. // 快速查询函数
    11. function FastRecentLike()
    12. begin
    13.     min_diff := Infinity;
    14.     find_pos := -1;
    15.     foreach (i in up_limit_bars) do
    16.     begin
    17.         current_diff := Abs(C[BarPos] - C[i]);
    18.         if (current_diff < min_diff) then
    19.             find_pos := i;
    20.     end
    21.     return find_pos;
    22. end
    复制代码

  • 增量更新:
    维护动态窗口内的涨停位置,减少遍历范围。


通过上述优化,函数在准确性、鲁棒性和代码可读性上均有提升,同时平衡了性能需求


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|小黑屋|易得程序化 ( 粤ICP备2022064048号 )

GMT+8, 2025-4-28 16:26 , Processed in 0.053134 second(s), 19 queries .

快速回复 返回顶部 返回列表