问题标签 [hft]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
finance - 高频交易
在过去的几周里,我遇到了很多关于高频交易的文章。他们都在谈论计算机和软件对此的重要性,但是由于它们都是从财务角度编写的,因此没有详细说明软件的作用是什么?
谁能从程序员的角度解释一下什么是高频交易?为什么计算机/软件在这个领域如此重要?
embedded - 硬件上的 HFT 策略编码
到目前为止,硬件加速和嵌入式编程主要用于解析数据馈送和/或路由订单以进行交换。是否曾尝试编写更简单的高频交易策略,例如硬件股票做市?他们成功了吗?哪些公司在做这件事,使用了什么样的编程模型?
tcp - 高频交易 - TCP > UDP?
有人告诉我,对于需要低延迟的高频交易 (HFT) 系统,TCP 是通过 UDP 使用的。有人告诉我,使用 TCP 可以进行点对点连接,而使用 UDP 则不能,但是据我了解,您可以将 UDP 数据包发送到特定的 IP/端口。
本文中使用了几个论点来解释为什么 UDP > TCP 用于游戏,但我可以看到 HFT 的相关性。
为什么 TCP 会是用于 HFT 的更好协议?
(管理员:我之前的这个问题的帖子被默默地删除了,没有任何解释。如果我违反了使用条款,请提醒我这一点,而不是默默地删除这个问题)
c# - 在 HFT 中尝试并行订单处理是否有意义?
好吧,我认为对于那些熟悉 hft 的人来说,这是一个更理论的问题。我收到 FAST 的订单并处理它们。我每秒收到大约 2-3 千个订单。问题是我是否应该尝试同步或异步处理它们。
每次收到下一个订单时,我都需要执行以下操作:
- 更新相应工具的订单簿
- 更新依赖于该顺序的索引和指标
- 如果需要,更新策略并安排一些行动(买/卖东西等)
为了实现同步,我需要大约 200-300 µs(每秒能够处理 3000 个订单)。我想这应该足够了。
只是为了安排异步任务我花了我想~30 µs
优点和缺点:
同步:
- ++ 不需要同步东西!
- ++“收到订单”和“采取行动”之间的延迟较少,因为不需要安排任务或将数据/工作传递给另一个进程(在 hft 中非常重要!)。
- -- 但是“订单已收到”操作可能会延迟,因为我们可以在套接字缓冲区中等待上一个订单处理
异步:
- ++ 能够使用现代服务器的强大功能(例如,我的服务器有 24 个内核)
- ++ 在某些情况下更快,因为在处理先前的消息时不要等待。
- ++ 可以处理更多消息,或者每条消息可以做更多“复杂”的事情
- -- 需要同步很多东西可以减慢程序的速度
同步示例:我们收到更新的 MSFT 订单,然后更新 INTC 订单,并在不同的线程中处理它们。在这两种情况下,我们都会触发纳斯达克指数重新计算。所以纳斯达克指数的计算应该是同步的。然而,可以解决这个特殊问题以避免同步......这只是可能同步的一个例子。
所以问题是我应该同步还是异步处理订单更新。到目前为止,我对它们进行异步处理,并且每个仪器都有专用线程。因为我可以为不同的仪器(MSFT 和 INTC)处理异步更新的两个更新,但一个仪器(MSFT)的两个更新应该同步处理。
c# - 优化将股市指数传递给其他线程的无锁代码
我正在计算经常变化的股票市场指数,所以我决定给我的服务器(运行 2 * E5-2640)单独的“核心”(24 个虚拟可用核心之一),因为到目前为止我只有 5% CPU 负载,所以我有很多可用的空闲 CPU 电源。
由于我需要尽快对股市指数变化做出反应,我决定使用无锁代码。这是我将在现实生活中使用的示例:
输出:
与我使用BlockingCollection
异步执行方法比 BlockingCollection 更好的 18 微秒相比,平均有 2 微秒是相当惊人的?
我真的很想要这个微秒,因为我有很多空闲的 CPU 能力,而且在 HFT 中微秒很重要。
所以这个问题很简单——你看到我的例子有什么问题吗?我从来没有写过无锁代码,所以我想我可能会犯愚蠢的错误。我不使用自旋锁,因为我假设原始更改(int/double/decimal)是“原子的”,所以在第二个线程中,我总是收到以前的或新的值,但没有别的。
即,如果在一个线程中我将 int x 从 100 更改为 555,那么在第二个线程中我将拥有 100 或 555,但绝不会是 500 或 155 或其他任何值。
c# - 证券交易所指数应该是双数还是小数?
我在计算,比如说,纳斯达克指数。
所有股票价格都是十进制的,我可以将重量设为十进制或双倍 - 没关系。
纳斯达克 = weight1 * stock1 + weight2 * stock2 + .... + weightn * stockn。
由于股票价格是十进制的,因此将纳斯达克指数设为十进制似乎是有意义的。但我不想每次更新某些股票时都重新计算纳斯达克指数。相反,我想“缓存”以前的值,然后只计算差异。例如,如果 stock2 更改,则:
现在我需要同步纳斯达克指数,因为股票可以同时更新。例如,我可以在并行线程中收到 MSFT 和 INTC 的新价格。所以我必须写Interlocked.Add(ref nasdaq, diff * weight2);
参考我之前的问题如何使用无锁代码同步来自不同线程的添加? 但是我不能这样做,decimal
因为不支持小数。
好的,让我们尝试将nasdaq
索引声明为double
? 使用双打我可以做到Interlocked.Add
,但现在有另一个问题:因为每一步我都会从十进制转换为双精度,我会失去精度。然后我的“智能缓存算法”不会绝对“精确”。这意味着在我的索引的 100 000 000 次更新值变得完全错误之后,我无法处理。
所以不可能使用也double
不可能decimal
。
我确实只看到了一种可能的解决方案——我必须声明 nasdaq 索引,decimal
这样我才能继续使用我的“智能缓存算法”,所以我必须使用更复杂的“同步”机制,可能我必须使用自旋锁。
可能您可以看到更简单的解决方案?
algorithm - 将“平稳性”添加到长系列十进制值的算法
假设您想“保留”您的限价单以始终比当前报价便宜 0.10 美元购买“MSFT”。
因此,如果要约移动,您也应该移动您的订单。
例如,如果报价从 30.10 移至 30.11,您必须将订单从 30.00 移至 30.01
问题是,如果由于某种原因,报价在 30.10 和 30.11 之间频繁移动,您也会频繁移动您的订单。这太糟糕了,因为证券交易所对额外交易“收费”,所以我们应该尽可能少地保持交易数量。
所以我想让我的系列更“静止”。即我想将此类系列“30.00 30.01 30.00 30.01 30.00 30.01 30.02”替换为可能的系列“30.00 30.00 30.00 30.00 30.00 30.01 30.02”
我不知道“报价”将如何变化,但我需要“限制”我的订单的移动次数。
所以我建议使用这样简单的解决方案1:如果订单从Price1 移动到Price2,那么在下一个时间段(1 秒左右)内禁止将此订单移动到Price1。这将涵盖所有情况。例如:
- Price1 -> Price2 - 允许
- Price2 -> Price3 - 允许
- Price3 -> Price1 - 如果没有足够的时间,则下降
我也可以建议解决方案2:
而不是“当前报价”使用“最后一段时间的最低报价”。例如“最后一秒的最低报价”不会经常改变。
在“解决方案1”中,我立即对向上/向下变化做出反应,但过滤掉“重复”变化。但是,我仍然会“每期移动一次”。
在“解决方案2”中,我对向上变化做出“延迟”反应,并立即对向下变化做出反应,但有时我根本不会移动,因为每次最低报价重复时,我的“秒表”都会“重置”并“再次打勾”第二”。因此,如果“最低报价”每秒重复一次或更多,我将只停留在某个点而没有任何动作。
你觉得你能提出什么建议?
algorithm - 如何防止一系列整数经常具有相同的值
我有“在线”系列整数,所以每隔几毫秒我就有一个新数字。没有指定频率 - 有时我有很多数字,有时我没有数字。
实际上,这个数字就是所谓的股票“真实价格”。我在我的交易应用程序中使用它。
现在我只使用最后一个数字作为“真实价格”,所以我根本不跟踪系列。但是这种方法存在一些问题。让我们看看这个系列:
- 98; 最后 = 98
- 100; 最后 = 100
- 101; 最后 = 101
- 100; 最后 = 100
- 101; 最后 = 101
- 100; 最后 = 100
- 101; 最后 = 101
- 100; 最后 = 100
- 101; 最后 = 101
- 100; 最后 = 100
- 99; 最后 = 99
- 98; 最后 = 98
问题是在很短的时间内我的“真实价格”从 100 变为 101 并返回太多次。真实价格的每一次变化都意味着大量的工作(重新计算、下订单等),所以我不需要像那样改变真实价格。这种变化(100-101-100-101)是由于“测量问题”,我需要过滤它。我无法修复“测量”,所以我必须在这里修复它。
一种方法是使用“3LastAverage”算法:
- 98; 3lastAverage = 98
- 100; 3lastAverage = 99
- 101; 3lastAverage = 99.67 => 100
- 100; 3lastAverage = 100.33 => 100
- 101; 3lastAverage = 101
- 100; 3lastAverage = 100
- 101; 3lastAverage = 101
- 100; 3lastAverage = 100
- 101; 3lastAverage = 101
- 100; 3lastAverage = 100
- 99; 3lastAverage = 100
- 98; 3lastAverage = 99
如您所见,这种方法并不总是有效,我仍然有 100-101-100 问题。可能我可以使用更多的数字来计算“平均值”......但由于这样的例子,这种方法对我不起作用:
- 99; 3lastAverage = 99(我想要 99)
- 100; 3lastAverage = 100(我想要 100)
- 101; 3lastAverage = 100(我想要 101)
- 102; 3lastAverage = 101(我想要 102)
- 103; 3lastAverage = 103(我想要 103)
一般来说,当事情进展顺利时,我需要 truePrice 只是最后一个数字!
所以,有“在线”系列的整数,我需要计算这个系列的所谓“真值”,它是这样定义的:
- 如果一切正常,那么这只是最后一个数字
- 如果系列中有太多相同的数字(因为测量问题),那么“真实值”不应该经常改变。应使用最合适的值
我的建议是:
- 只是禁止“真实价值”每秒有超过一次相同的价格。
例如:
- 0.000:98;真值 = 98
- 0.100:100;真值 = 100
- 0.200:101;真值 = 101
- 0.300:100;真值 = 101(100 已在 0.2 秒前的步骤 2 中使用)
- 0.400:98;真值 = 101(98 已在 0.4 秒前的步骤 1 中使用)
- 0.500:99;真值 = 99
- 0.600:100;真值 = 99(0.5 秒前在步骤 2 中使用了 100)
- 1.500:101;真值 = 101(自使用 101 以来已过去超过一秒)。
然而,这种方法也有这样的“错误”:
- 99 吨 = 99
- 100 吨 = 100
- 101 吨 = 101
- 102 吨 = 102
- 103 吨 = 103
- 102 吨 = 103
- 101 吨 = 103
- 100 吨 = 103
- 99 吨 = 103
- 98 吨 = 98
- 97 吨 = 97
这里的问题是“tp”在 103 级“冻结”了太长时间。
对于这么大的问题,我真的很抱歉。但可能有人正在解决密切的问题并可以分享经验。我的主要问题是我确实需要同时解决两个相反的问题:
- “真实价格”必须只是一般条件下的“最后”值
- “真实价格”不应该经常改变(所以我需要以一种或另一种方式使用以前的值)
- 也很难说我们什么时候有“一般”条件,什么时候有“测量问题”
所以我的问题真的很模糊,我只是希望有人试图解决这样的问题。一如既往,应该使用“常识”来解决这个问题。
c# - 我应该尽量避免在超低延迟软件中使用“new”关键字吗?
我正在编写高频交易软件。我确实关心每一微秒。现在它是用 C# 编写的,但我很快就会迁移到 C++。
让我们考虑这样的代码
我想超低延迟的软件不应该过多地使用“new”关键字,所以我搬到actions
了一个领域:
也许我应该尽量避免使用“new”关键字?我可以使用一些预分配对象的“池”:
- 我应该走多远?
- 避免有多重要
new
? - 使用我只需要配置的预分配对象时,我会赢得什么吗?(在上面的示例中设置类型和价格)
请注意,这是超低延迟,所以让我们假设性能优于可读性、可维护性等。