Пример #1
0
 public static void Publish(string exchange, Orderbook message, string routingKey = null)
 => Channel(TheRandom.Pair(Dimension))
 .BasicPublish(
     exchange,
     body: Serialize(message),
     routingKey: routingKey ?? string.Empty,
     mandatory: false,
     basicProperties: new BasicProperties
 {
     Persistent   = false,
     DeliveryMode = 1
 });
Пример #2
0
        public Orderbook(string assetPairId, decimal bid, decimal ask, int depth)
        {
            AssetPairId = assetPairId;

            var jitter = TheRandom.Range(1, Program.Settings.books.bestPriceDeviation);

            bid *= jitter;
            ask *= jitter;

            for (var(i, offset) = (0, 0.001m * (ask - bid)); i < depth; offset = Max(0.001m, Min((ask - bid) * i / depth, offset * i++)))
            {
                // volume = 10 * (i * i + 1)
                Bids.Add(Level(bid - i * offset, Vol(i)));
                Asks.Add(Level(ask + i * offset, Vol(i)));
            }
        }
Пример #3
0
 private static decimal Vol(int i)
 => TheRandom.In(10 * ((i - 1) * (i - 1) + 1), 10 * (i * i + 1));
Пример #4
0
        public static void Main(string[] args)
        {
            Settings = JsonConvert.DeserializeObject <Settings>(File.ReadAllText(@"./input.json"));
            RabbitMqPublisher.ConnectionString = new Uri(Settings.rabbitMq.connString.AppendPathSegment("%2f"));

            var headers = new
            {
                api_key      = "margintrading",
                Content_Type = "application/json"
            };

            if (!string.IsNullOrEmpty(Settings.rabbitMq.fxRatesExchange))
            {
                Log("Pre-populating FxRates");

                var pairs = Settings.mtSettingsService
                            .AppendPathSegment("api/assetPairs")
                            .WithHeaders(headers)
                            .GetJsonListAsync().Result
                            .Select(x => (string)x.Id).OrderBy(x => x).ToArray();

                var oldFx = Settings.mtTradingCore
                            .AppendPathSegment("api/prices/bestFx")
                            .WithHeaders(headers)
                            .PostJsonAsync(new { pairs }).ReceiveJson <Dictionary <string, dynamic> >().Result;

                var fxRates = pairs.Select(i => (id: i,
                                                 mid: oldFx.ContainsKey(i)
                        ? (decimal)oldFx[i].Bid
                        : TheRandom.In(Settings.defaults.bid, Settings.defaults.ask))).ToList();

                fxRates.ForEach(p => RabbitMqPublisher.Publish(
                                    exchange: Settings.rabbitMq.fxRatesExchange,
                                    message: new Orderbook(
                                        assetPairId: p.id,
                                        bid: p.mid,
                                        ask: p.mid,
                                        depth: 1)));

                Log("FxRates have been pre-populated");
                Log("Waiting 5 seconds after burst");
                Thread.Sleep(5000);
            }

            var instruments = Settings.mtSettingsService
                              .AppendPathSegment("api/tradingInstruments")
                              .WithHeaders(headers)
                              .GetJsonListAsync().Result
                              .Select(x => (string)x.Instrument).OrderBy(x => x).ToArray();

            Log($"Trading instruments discovered: {instruments.Length}");

            if (!string.IsNullOrEmpty(Settings.instrumentRegex))
            {
                instruments = instruments.Where(x => new Regex(Settings.instrumentRegex).IsMatch(x)).ToArray();
            }

            var oldQuotes = Settings.mtTradingCore
                            .AppendPathSegment("api/prices/best")
                            .WithHeaders(headers)
                            .PostJsonAsync(new { instruments }).ReceiveJson <Dictionary <string, dynamic> >().Result;

            Log($"Trading quote history exists for {oldQuotes.Count} pairs");

            var quotes = instruments.Select(i =>
                                            oldQuotes.ContainsKey(i)
                    ? (id: i, bid: (decimal)oldQuotes[i].Bid, ask: (decimal)oldQuotes[i].Ask)
                    : (id: i, Settings.defaults.bid, Settings.defaults.ask)).ToList();

            Log($"Operational instruments: {quotes.Count}");

            if (quotes.Count.Equals(0))
            {
                return;
            }

            var cycleCount = 0;
            var ramp       = Settings.publishingRate.initial;

            while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Enter))
            {
                var sw     = Stopwatch.StartNew();
                var target = Stopwatch.Frequency / (ramp
                                                        += Settings.publishingRate.increment *
                                                           (Min(Settings.publishingRate.target, ++cycleCount) <= Floor(ramp)
                                        ? 0 : cycleCount = 1));

                Log($"Current publishing rate: {ramp}");
                for (var i = 0; i < quotes.Count; sw.Blink(target * i++ / quotes.Count))
                {
                    RabbitMqPublisher.Publish(
                        exchange: Settings.rabbitMq.orderBooksExchange,
                        message: new Orderbook(
                            quotes[i].id,
                            quotes[i].bid,
                            quotes[i].ask,
                            depth: Settings.books.depth
                            ));
                }

                sw.Blink(target);
            }
            Console.ReadKey();
        }