【问题标题】:C# Algorithmic Stock TradingC# 算法股票交易
【发布时间】:2016-11-04 05:33:39
【问题描述】:

我们正在开发 C# 算法交易软件。我们监控市场价格,然后根据特定条件购买股票。

可以从 GUI (WPF) 获取用户输入并发送到后端进行监控。

后端连续接收来自证券交易所的数据并检查用户输入的价格是否满足某些限制和条件。如果一切都满意,那么我们将买入/卖出股票(在期货 FUT 中)。

现在,我想设计我的后端服务。

  1. 我需要任务并行库或自定义线程池,以便在应用程序启动时创建我的任务/线程/池(可能是增量的或固定的,例如 5000)。
  2. 所有将处于等待状态。
  3. 一旦用户创建算法,我们将从池中激活一个线程并监控每个传入字符串的价格。如果匹配,则买入/卖出,然后再次进入等待状态。 (我不想创建和销毁线程/任务,因为它很耗时)。

那么请你们在这方面帮助我吗?如果上面的方法好还是我们有其他方法?

我对这个想法感到震惊,无法跳出框框思考这个问题。

【问题讨论】:

  • 你能用C# 5.0 async-await吗?
  • 是的。我对此没有限制。但是我需要创建一个任务池对吗?

标签: multithreading c#-4.0 task-parallel-library tpl-dataflow algorithmic-trading


【解决方案1】:

上面的做法绝对不是“好”

鉴于上述想法,该架构在许多主要方面都是错误的。如果您的项目渴望在 2017 年以上的市场中生存,请尝试从 2007-2016 年已经犯过的错误中吸取教训。


百分比显示了 2007 年 1 月至 2012 年 1 月所有美国股票的 NBBO 波动。 (较低的值意味着更好的 NBBO 稳定性。较高的值:不稳定)(由 NANEX 提供)

金融市场以纳秒级运行

是的,几英寸的玻璃纤维信号传播传输延迟决定了盈亏。

如果计划在股票市场进行交易,您的系统将观察到 HFT 人群,在您的眼前以如此大规模的方式进行报价填充和真空清洁的肮脏练习,以至于您的单机多线程执行在你的决定发生在你的本地 CPU 上之前,它会在你的决定发生之前的许多微秒内穿过空虚的落差。


2007-01 ~ 2012-01 期间高频交易的兴起(由 NANEX 提供)。

五月read more about an illusion of liquidity here.

查看报价相对于交易级别的扩展: (由 NANEX 提供)

即使一个人决定在外汇上交易单一工具,时间也非常短(超过 20% 的 ToB 出价在不到 2 毫秒的时间内更改,并且不会在您的交易算法之前到达您的本地主机可能会做出相应的反应)。

如果您的 TAMARA 测量值与此类似,在您的本地主机上,只需忘记交易任何 HF/MF/LF-HFT 工具 -- 您根本看不到真实的市场(冰山一角)——因为 +20% 的价格事件发生在第一列 (1 .. 2 ms),您在该列中看不到任何单一事件全部!

【讨论】:

  • 知识渊博,我们的目标当然是在 2017 年以上市场达到纳秒级。非常感谢您的 cmets 和回答。这向我展示了我在哪里以及 mu 学习曲线有多陡峭。老实说,我必须学习很多才能理解这一点。
  • 如果您的计划确实有资金参加 1ns 比赛,请务必给我一个加入的邀请。 很酷的旅程!
  • @SNR,如果谈到 nanoseconds-driven 设计实践,您可能还会喜欢 CPU / GPU 代码 + 缓存 + RAM 延迟的概述,请记住,一次将设计硬实时系统>>> stackoverflow.com/a/33065382/3666197
  • 非常感谢您提供的信息。正如我所说,我无法立即理解它。 :-)。我很乐意为您提供,但我现在不在一个阶段。但肯定会吸引你。
【解决方案2】:

5000 线程很糟糕,永远不要这样做,与并行执行时间改进相比,上下文切换损失会降低性能。传统上,默认情况下,应用程序的线程数应等于系统中的内核数。还有其他可能的变体,但它们可能不是您的最佳选择。

所以你可以使用ThreadPool 和一些working item method 无限循环,这是非常低的级别,但你可以控制系统中发生的事情。回调函数可以更新用户界面,以便通知用户交易结果。

但是,如果您说可以使用TPL,我建议您考虑以下两个选项:

  1. 使用tasks running forever 的集合来检查新的交易请求。您仍然应该调整同时运行的任务的数量,因为您可能不希望它们相互争夺 CPU 时间。由于LongRunning 任务是使用专用后台线程创建的,因此其中许多也会降低您的应用程序性能。也许在这种方法中,您应该为在任务中运行的算法引入策略模式实现。

  2. 在您的应用程序中设置TPL Dataflow 进程。对于这种方法,您应该将有关算法的信息封装在 DTO 对象中,并引入管道:

    • BufferBlock 用于存储所有传入的请求。如果您想并行检查sellbuy 选项,也许您可​​以在这里使用BroadcastBlock。您可以在此处将块与布尔谓词链接,以便不同的块将处理不同类型的请求。
    • ActionBlock(可能来自用户的每个算法一个块)用于处理算法检查以查找您提供决策所依据的模式。
    • ActionBlock 用于存储所有 buy / sell 对算法成功传递的数据的请求。
    • BufferBlockReactive Extensions 的 UI 反应(Introductory book for Rx,如果您不熟悉它)

    此解决方案仍需使用block creation options 进行调整,并为您提供更多信息,让您了解交易算法中的数据流向、决策速度和整体性能。您应该正确检查 TPL 数据流块的默认值,您可以在 the official documentation 中找到它们。其他不错的起点是 Stephen Cleary 的介绍性博文(Part 1Part 2Part 3)和his book 中关于这个库的第 4 章。

【讨论】:

  • 恕我直言,请原谅我的系统设计术语纯粹。基于线程的执行只是一种 [concurrent]-type 系统调度,主要不是 [parallel]-type 系统行为。 InMOS Transputer 硬件提供基于硬件的[parallel] 类型系统行为,因此occam 语言可以提供PAR 代码段,确实保证在真正的并行调度在保证完全相同的时间产生结果。当前的 XEON 硬件可能允许最多 2HT*nCpuCOREs 并发 INSTR 执行。
  • 由于TPL 代表Task Parallel Library,我使用了parallel 这个词来表示将在parallel 中运行的任务,即TPL
  • 当然,NP :o) 它最近“如此普遍”,受到技术营销的感染,以至于技术纯度几乎丢失了。真丢脸,如果我们忘记了我们的工艺(并且似乎也只是为了改写营销谣言;o)享受这一天,VMAtm。
  • @VMAtm:我现在最关心 CPU 周期的使用,因为我们需要运行这么多并行任务来处理连接,同时将数据存储在数据库和内存字典中。今天有很多东西要消化。我知道 TPL 的基础知识,但这些链接肯定会以正确的方向指向我。
  • @VMAtm,我将此标记为答案。从这个方向开始,并希望最好。谢谢。
【解决方案3】:

对于 C# 5.0,自然的方法是使用在默认线程池之上运行的 async 方法。

这样,您会经常创建Tasks,但最突出的成本是 GC。除非您有非常高的性能要求,否则该成本应该是可以接受的。

【讨论】:

  • 非常感谢。我们的应用程序应该是低延迟和高性能的应用程序。这是原因之一,我想创建自定义池。
  • 我认为你应该先做最简单的方法,只有当它证明是不够的,然后看看如何改进它。特别是因为现有池可能会比您的自定义池更优化。
  • 再次感谢。我会试试看。我会看看是否有人对自定义池有任何想法。不过谢谢你的建议。
【解决方案4】:

我认为使用事件循环会更好,如果需要扩展,您可以随时按库存分片。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-04-07
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多