Неверное десятичное размещение в финансовой заявке - PullRequest
3 голосов
/ 11 марта 2020

Я довольно новичок в программировании и начал изучать C#, и это мой первый проект. Я изо всех сил пытаюсь выяснить, почему происходит странная и, казалось бы, случайная проблема. Это довольно простое торговое приложение. По сути, он подключается к потоку веб-сокетов и получает данные о ценах в реальном времени от биржи, а затем оценивает цену в режиме реального времени и выполняет некоторые действия. Цена обновляется сотни раз в секунду и работает без проблем, и вдруг я получу цену, равную тысячам долларов от реальной цены, которая была отправлена ​​с биржи. Я наконец поймал это происходящее в реальном времени. Приложение работало в течение 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 по какой-то причине сдвигает десятичную влево на одно место. Значения, поступающие из веб-сокета, хороши, только когда CurrentPrice установлен на LastPrice, проблема возникает.

Я понятия не имею, почему это происходит и кажется совершенно случайным.

Кто-нибудь знает, почему это может происходить или как?

Спасибо за помощь!

1 Ответ

2 голосов
/ 11 марта 2020

Существует две распространенные причины:

  • Рыночные данные, из-за того, как быстро они обновляются, иногда выдают неверные данные в зависимости от поставщика. Если вы потребляете напрямую с биржи, вам нужно написать код для этого. Некоторые провайдеры (например, OPRA ) будут фильтровать или помечать плохие тики для вас.
  • Если вы постоянно сталкиваетесь с этой проблемой, это связано с такими вещами, как размер или масштаб тика. Некоторые биржи делают это по-разному, но эффективно вам нужно умножить определенные ценовые поля на определенный масштаб. За подробностями обращайтесь к документации поставщика данных.

Если это наблюдается очень редко, вы, вероятно, просто получили плохую цену. Да, это абсолютно будет случаться время от времени, и вы должны быть готовы к этому, если только вы не хотите стать следующим Рыцарь Капитал .

Во всех обработчиках I ' Мы написали (или внесли свой вклад), что есть «проверка работоспособности», чтобы проверить, хороши ли данные. В зависимости от того, что вы пытаетесь выполнить sh, достаточно просто сбросить плохой тик.

Другое решение, которое я обычно использовал, - это альтернативные потоки данных (обычно называемые «A» и «B»). потоки или аналогичные). Если вы получаете плохую галочку в одном потоке, используйте другой.

Тем не менее, это не имеет прямого отношения к языку программирования, но в основном он обрабатывает причуды с API / данными.

Редактировать

Также остерегайтесь проблем с потоками здесь. Убедитесь, что CurrentPrice не обновляется несколькими потоками одновременно. decimal - это 128-битная базовая 10 с плавающей запятой, и это больше, чем размер слова в настоящее время (32 или 64 бита).

Вам может потребоваться синхронизировать чтение и запись в него, что вы можете делать различными способами. способов. Приведенная выше информация по-прежнему применима, однако.

...