如何在同一张表的signal信号区间内实现action列单次触发?
Q语言实现单信号周期内仅触发一次止盈/止损
问题场景
你维护着一张股票信号记录表:
signal列:非0n值表示新信号触发,对应触发时的股价tp/sl列:基于信号价计算的止盈、止损价格price列:实时滚动的股票价格action列:标记止盈(TP)/止损触发,但当前逻辑会在同一信号周期内多次触发(如示例中第5、6行均标记TP)
需求:每个信号周期内仅保留首次触发的止盈/止损标记,后续直到下一个信号出现前不再标记。
示例原始表:
t:([] price:0.6623 0.6627 0.6630 0.6631 0.6639 0.6641 0.6638; signal:0.6623 0n 0n 0n 0n 0n 0.6638; tp:0.6633 0.6633 0.6633 0.6633 0.6633 0.6633 0.6648; sl:0.6613 0.6613 0.6613 0.6613 0.6613 0.6613 0.6628; action:` `` `` `` `` `TP `TP `)
解决方案
核心思路是按信号触发点分组,在每个分组内仅保留首次触发的action标记:
// 生成信号分组ID:每次遇到非0n的signal,分组号递增 groupIds: 0 scan {[prev; s] prev + (not null s)} 0, signal[1:]; // 按分组ID处理action:仅保留每组内第一个非空的触发标记,其余置空 update action: raze {first[where x<>``] @[x; 1_where x<>``;:; ``]} each group action by groupIds from t
执行后得到的目标表:
| price | signal | tp | sl | action |
|---|---|---|---|---|
| 0.6623 | 0.6623 | 0.6633 | 0.6613 | `` |
| 0.6627 | 0n | 0.6633 | 0.6613 | `` |
| 0.6630 | 0n | 0.6633 | 0.6613 | `` |
| 0.6631 | 0n | 0.6633 | 0.6613 | `` |
| 0.6639 | 0n | 0.6633 | 0.6613 | `TP | |
| 0.6641 | 0n | 0.6633 | 0.6613 | `` |
| 0.6638 | 0.6638 | 0.6648 | 0.6628 | `` |
代码解释
- 分组ID生成:用
scan遍历signal列,每遇到非空信号就递增分组号,将连续的同一信号周期归为一组。 - 分组处理action:对每个分组的
action列表,定位所有非空触发标记的位置,仅保留第一个,其余非空值替换为空符号`。
也可以用一行代码整合逻辑:
update action: raze {y@[y;1_where y<>``;:;``]} each group action by 0 scan {prev+(not null x)} 0,signal[1:] from t
内容的提问来源于stack exchange,提问作者vicefreak04
相关产品推荐
相关产品推荐

