首页 > 解决方案 > 财务应用程序中的小数位不正确

问题描述

我对编程很陌生,开始学习 C#,这是我的第一个项目。我正在努力弄清楚为什么会出现奇怪且看似随机的问题。这是一个相当简单的交易应用程序。基本上,它连接到 websocket 流并从交易所接收实时价格数据,然后实时评估价格并执行一些操作。价格每秒更新数百次,运行没有问题,然后突然之间,我会得到一个比交易所发送的实际价格低数千美元的价格值。我终于实时捕捉到了这种情况。该应用程序已经运行了 11 个小时左右没有问题,然后出现了错误的值。

这是有问题的代码:

public static decimal CurrentPrice;
// ...
if (BitmexTickerStreamIsConnected)
{
    bitmexApiSocketService.Subscribe(BitmetSocketSubscriptions.CreateInstrumentSubsription(
        message =>
        {
            foreach (var instrumentDto in message.Data)
            {
                if (instrumentDto.Symbol == "XBTUSD")
                {
                    BitmexTickerStreamLastMessageReceived = DateTime.Now;
                    decimal LastPrice = instrumentDto.LastPrice.HasValue ? Convert.ToDecimal(instrumentDto.LastPrice) : CurrentPrice;
                    CurrentPrice = LastPrice;
                }
            }
        }));
}

这些是断点被进一步击中后调试中的值:

instrumentDto.LastPrice = 7769.5
LastPrice = 7769.5
CurrentPrice = 776.9

问题是 CurrentPrice 似乎出于某种原因将小数点向左移动了一位。从 websocket 传入的值很好,只是当 CurrentPrice 设置为 LastPrice 时才会发生问题。

我不知道为什么会发生这种情况,而且似乎完全是随机的。

任何人都知道为什么会发生这种情况或如何发生?

感谢您的帮助!

标签: c#.netdecimalfinancetrading

解决方案


有两个常见的原因:

  • 市场数据由于更新速度快,有时会根据供应商的不同给您直接提供不良数据。如果您直接从交易所消费,则需要为此编写代码。一些提供商(如OPRA)会为您过滤或标记错误的报价。
  • 如果您一直看到此问题,那是由于刻度大小或比例等因素造成的。一些交易所这样做的方式不同,但实际上你需要将某些价格字段乘以一定的比例。有关详细信息,请参阅数据提供者文档。

如果这种情况很少见,您可能只是得到了一个糟糕的价格。是的,这绝对偶尔发生,你需要为此做好准备,除非你想成为下一个骑士资本

在我编写(或贡献)的所有处理程序中,都有一个“健全性检查”来查看数据是否良好。根据您要完成的工作,只需删除坏的刻度就可以了。

我常用的另一种解决方案是备用数据流(通常称为“A”和“B”流或类似的)。如果您在一个流上打勾,请使用另一个。

也就是说,这与编程语言没有直接关系,但其核心是处理 API/数据的怪癖。

编辑

还要注意这里的线程问题。确保CurrentPrice不会同时被多个线程更新。 decimal是 128 位基数 10 浮点数,并且大于当前的字长(32 位或 64 位)。

您可能需要同步对它的读取和写入,您可以通过多种方式执行此操作。不过,上述信息仍然适用。


推荐阅读