c# - 财务应用程序中的小数位不正确
问题描述
我对编程很陌生,开始学习 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 时才会发生问题。
我不知道为什么会发生这种情况,而且似乎完全是随机的。
任何人都知道为什么会发生这种情况或如何发生?
感谢您的帮助!
解决方案
有两个常见的原因:
- 市场数据由于更新速度快,有时会根据供应商的不同给您直接提供不良数据。如果您直接从交易所消费,则需要为此编写代码。一些提供商(如OPRA)会为您过滤或标记错误的报价。
- 如果您一直看到此问题,那是由于刻度大小或比例等因素造成的。一些交易所这样做的方式不同,但实际上你需要将某些价格字段乘以一定的比例。有关详细信息,请参阅数据提供者文档。
如果这种情况很少见,您可能只是得到了一个糟糕的价格。是的,这绝对会偶尔发生,你需要为此做好准备,除非你想成为下一个骑士资本。
在我编写(或贡献)的所有处理程序中,都有一个“健全性检查”来查看数据是否良好。根据您要完成的工作,只需删除坏的刻度就可以了。
我常用的另一种解决方案是备用数据流(通常称为“A”和“B”流或类似的)。如果您在一个流上打勾,请使用另一个。
也就是说,这与编程语言没有直接关系,但其核心是处理 API/数据的怪癖。
编辑
还要注意这里的线程问题。确保CurrentPrice
不会同时被多个线程更新。 decimal
是 128 位基数 10 浮点数,并且大于当前的字长(32 位或 64 位)。
您可能需要同步对它的读取和写入,您可以通过多种方式执行此操作。不过,上述信息仍然适用。
推荐阅读
- python-3.x - Postgres SQLalchemy 自动映射无法识别关系
- d3.js - d3 重新居中 SVG 中的元素组
- e-commerce - 从 Hybris 5.2 到 6.7 导入产品图像数据
- javascript - 有没有办法在 javascript 中创建类似 python 的生成器?
- python - Python3和Python2在同一台机器上
- excel - 在 Excel 查询编辑器中合并具有不同列数的 CSV 文件文件夹
- c# - WPF 组合框阻止选择更新
- magento - 为什么第二个产品动态添加到购物车中会丢失 Magento2 中的选项
- jenkins - 强制多分支管道构建互斥
- python - 删除 x 轴上的所有其他刻度