财务申请中的小数点位置不正确
Incorrect decimal placement in financial application
我是编程新手,刚开始学习 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)将为您过滤或标记不良报价。
- 如果您一直看到这个问题,那是因为刻度尺寸等问题
或规模。有些交易所的做法不同,但实际上你
需要将某些价格字段乘以一定比例。咨询
有关详细信息,请参阅数据提供程序文档。
如果这种情况很少见,您可能只是得到了一个糟糕的价格。是的,这绝对 会 偶尔发生,你需要为此做好准备,除非你想成为下一个 Knight Capital.
在我编写(或贡献)的所有处理程序中,都有一个 "sanity check" 来查看数据是否正确。根据您要完成的目标,只需删除错误的勾号即可。
我常用的另一种解决方案是备用数据流(通常称为 "A" 和 "B" 流或类似的流)。如果您在一个流中遇到错误,请使用另一个。
也就是说这与编程语言没有直接关系,但其核心是处理 API/data 的怪癖。
编辑
还要注意此处的线程问题。确保 CurrentPrice
不会同时被多个线程更新。 decimal
是以 10 为基数的 128 位浮点数,大于当前字长(32 或 64 位)。
您可能需要同步读取和写入它,您可以通过多种方式做到这一点。不过,上述信息仍然适用。
我是编程新手,刚开始学习 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)将为您过滤或标记不良报价。
- 如果您一直看到这个问题,那是因为刻度尺寸等问题 或规模。有些交易所的做法不同,但实际上你 需要将某些价格字段乘以一定比例。咨询 有关详细信息,请参阅数据提供程序文档。
如果这种情况很少见,您可能只是得到了一个糟糕的价格。是的,这绝对 会 偶尔发生,你需要为此做好准备,除非你想成为下一个 Knight Capital.
在我编写(或贡献)的所有处理程序中,都有一个 "sanity check" 来查看数据是否正确。根据您要完成的目标,只需删除错误的勾号即可。
我常用的另一种解决方案是备用数据流(通常称为 "A" 和 "B" 流或类似的流)。如果您在一个流中遇到错误,请使用另一个。
也就是说这与编程语言没有直接关系,但其核心是处理 API/data 的怪癖。
编辑
还要注意此处的线程问题。确保 CurrentPrice
不会同时被多个线程更新。 decimal
是以 10 为基数的 128 位浮点数,大于当前字长(32 或 64 位)。
您可能需要同步读取和写入它,您可以通过多种方式做到这一点。不过,上述信息仍然适用。