我正在编写一个应用程序,其目的是优化交易策略。为简单起见,假设我们只有一个交易策略“输入此处”,然后另一个说“如果在交易中退出”然后让我们有两个模型:一个说我们应该承担多少风险(如何如果我们在市场的错误方面,我们就会失去很多,而另一方则说我们应该获得多少利润(即如果市场同意我们将获得多少利润)。
为简单起见,我将历史实现的交易称为刻度。这意味着如果我“在28号线上输入”这意味着我将以此交易的价格在我的数据集中进行第28次交易时的交易。刻度按时间顺序存储在我的数据集中。
现在,想象整个数据集的输入策略会出现500个条目。对于每个条目,我可以预先计算确切的条目。我还可以计算每个入口点的退出策略确定的退出点(再次作为刻度数)。对于每个条目,我还可以预先计算模拟的损失和利润以及这些损失或利润将被击中的标记。还有待完成的最后一件事是计算首先会发生什么,即退出战略,退出亏损或退出利润。
因此,我遍历交易数组并计算exitTick [i] = min(exitTickByStrat [i],exitTickByLoss [i],exitTickByProfit [i])。整个过程都是血腥的慢(让我说我这样做100M次)。我怀疑缓存未命中是罪魁祸首。问题是:这可以以某种方式加快吗?我必须遍历4个非平凡长度的数组。我提出的一个建议是将数据分组为四元组,即有一个结构数组,如(entryTick,exitOnStrat,exitOnLoss,exitOnProfit)。由于更好的缓存可预测性,这可能会更快,但我不能肯定地说。为什么到目前为止我没有测试过,仪器分析器不知何故不适用于我的应用程序的发布二进制文件,而采样分析器似乎让我不可靠(我已经尝试过英特尔的分析器)。
所以最后的问题是:这个问题可以加快吗?使用发布二进制文件进行内存分析的最佳分析器是什么?我在Win7,VS2010上工作。
编辑: 非常感谢大家。我试图尽可能地简化我原来的问题,因此造成了混乱。只是为了确保它是可读的 - 目标意味着设想/实现的利润,停止意味着设想/实现的损失。
优化器是一种蛮力的优化器。因此,我有一些策略设置(例如指标期间,无论如何),然后是最小/最大breakEvenAfter / breakEvenBy,然后是公式,以便给出停止/目标值的刻度。这些公式也是优化的对象。因此,我有一个像
这样的优化结构for each in params
{
calculateEntries()
for each in beSettings
{
precalculateBeData()
for each in targetFormulaSettings
{
precalculateTargetsAndRespectiveExitTicks
for each in stopFormulaSettings
{
precalulcateStopsAndRespectiveExitsTicks
evaluateExitsAndDetermineImprovement()
}
}
}
}
所以我尽可能地预先计算东西,并且只在需要时计算一些东西。在30秒内,计算在evaluateExitsAndDetermineImprovement()函数中花费25秒,这就像我在原始问题中描述的那样,即选择min(exitOnPattern,exitOnStop,exitOnTarget)。我需要调用100M次函数的原因是因为我有100M组合所有参数组合。但是在最后一个循环中只有exitOnStops数组发生了变化。如果有帮助,我可以发布一些代码。我很感谢所有的评论!
答案 0 :(得分:1)
我对交易策略知之甚少,但我通常做一些优化。 嗯,有很多优化方法。 就像,容器的类型,使用不同的min函数(我认为boost比stl库中的函数稍微快一点),尝试减少相同的计算等。 您还可以通过使用更快的函数来提高速度,或者通过重新设计算法进行优化。
对于性能分析,我在Win7 x64下使用GlowCode,也可以用于发布版本。
答案 1 :(得分:0)
也许我完全误解了你的系统,但是:
什么是你“预先计算”什么时候和为什么 100M次?
我不知道它是否会对您有所帮助,但它可能会显着简化您的系统 - 有两种常见的交易策略:(描述是我和不官方)
1)“定点退出” - 当交易发生时,所有出口点都计算一次,并定期根据市场情况/价格进行检查。
2)“可变点退出” - 当市场移动时,重新计算退出点(通常锁定更多利润/减少损失)。
在案例1)中,实际计算只发生一次,因此它应该非常快 在案例2)中,计算将每次都进行,但可以通过多种不同的方式进行优化 - 其中之一是您可以存储由退出点索引的交易,并且仅获取并重新计算接近实际市场情况的交易。
我不确定您指的是哪个缓存未命中?你的数据缓存? CPU缓存?
答案 2 :(得分:0)
所以,经过一些工作,我理解了Alexandre C的建议。当我运行cache-miss profiling时,我发现在15%的evaluateExits()函数调用中,我只有30K缓存未命中,因此该函数的性能不能被缓存阻碍。因此,我不得不“开始相信”VTune实际上产生了有效的结果,尽管很奇怪。由于VTune输出的分析与当前线程的名称不匹配,我决定开始一个新的thread。谢谢大家的意见和建议。