4

我已经尝试过使用循环实现的标准方法。如果在刻度数据上完成,这将需要很长时间,因为传递的 px 列表会很大。有没有一种不使用循环的有效方法。可能以某种方式使用列表?

tlstop: {[ls; entry; loss; pxs]
origentry: entry;
i:0;
curloss: 0f;
exitpx: 0n;
while[(i<count pxs) and (curloss>loss);
        curpx: pxs[i];
        curpnl: $[ls=`l; curpx-entry; entry-curpx];
        exitpx: $[curpnl<=loss; curpx; exitpx];  
        entry: $[curpnl>curloss; curpx; entry];
        curloss: curpnl;
        i: i+1;
];
exitpx: $[exitpx=0n; last pxs; exitpx];
ans: $[ls=`l; exitpx-origentry; origentry-exitpx];
ans
};
/tlstop[`s; 100.0; -2.0; (99 98 97 96 93)]
4

2 回答 2

1

矢量化...

/ trailing stop for long
{[stoplossAtStart;prices]
previous:prev prices;
xtreme:maxs previous;
sl:stoplossAtStart + sums (0|0,1_deltas[prices]) * 0b,1_(&). prices>/:(previous;xtreme);
sl
};

/ trailing stop for short   
{[stoplossAtStart;prices]
previous:prev prices;
xtreme:mins previous;
sl:stoplossAtStart + sums (0&0,1_deltas[prices]) * 0b,1_(&). prices</:(previous;xtreme);
sl
};
于 2013-06-28T11:38:14.743 回答
1

正如您在下面看到的,在大约三行非常冗长的 q 或一行简洁的 q 中惯用地实现您的算法是微不足道的,如果您想惹恼您的同事。

q)pxs:100 101 102 101 100 99 98 //Our price ticks.
q)pxs
100 101 102 101 100 99 98
q)entry:({max (x;y)}\) pxs //Calculate entry prices for each tick.
q)entry
100 101 102 102 102 102 102
q)(pxs-entry) <= -2 //Determine tick where stop loss condition is triggered.
0000111b
q)first pxs where (pxs-entry) <= -2 //Calculate the price at which we would exit.
100
q)first pxs where (pxs-entry) <= -5 //We get null (0N) if stop loss is not triggered.
0N

我应该指出,这仅在您进行研究时才有用,如果您想计算实时交易系统的止损,则不是这样做的方法。运行时间和内存相对于您拥有的滴答数线性增加,因此到一天结束时它会很慢并且会占用内存。

真正做到这一点的方法是维护每个未平仓头寸的入场价格表,并设置一个函数,该函数在每次由您的代码工厂推送(当然是异步的)报价到您的应用程序时运行。此功能可以更新您的入场价格或将退出事件推送给您的交易经理。关键是运行时和内存复杂度应该相对于您处理的滴答数保持不变。

于 2013-06-28T04:40:20.150 回答