Exemple #1
0
        public async void StoreInstrumentCandles_WithExistingData()
        {
            // Arrange
            var instrument  = InstrumentName.EUR_USD;
            var granularity = Granularity.H1;
            var candles     = new List <Candle>()
            {
                new Candle()
                {
                    Time   = DateTime.UtcNow.AddDays(-3).AddHours(1),
                    Volume = 1234,
                    Bid    = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                    Mid = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                    Ask = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                }
            };
            var instrumentWithCandles = new InstrumentWithCandles()
            {
                InstrumentName = instrument,
                Granularity    = granularity,
                Candles        = candles
            };
            var blobClientMock = new Mock <BlobClient>();

            blobClientMock.Setup(bc => bc.UploadAsync(It.IsAny <Stream>(), true, It.IsAny <CancellationToken>()));
            blobClientMock.Setup(bc => bc.DownloadToAsync(It.IsAny <Stream>())).Callback <Stream>(candleStream => WriteSerializedCandlesToStream(candleStream)); // There is already existing data for the month
            var blobContainerClientMock = new Mock <BlobContainerClient>();

            blobContainerClientMock.Setup(bcc => bcc.CreateIfNotExistsAsync(It.IsAny <PublicAccessType>(), null, null, It.IsAny <CancellationToken>()));
            blobContainerClientMock.Setup(bcc => bcc.GetBlobClient(It.IsAny <string>())).Returns(blobClientMock.Object);
            _storageClientMock.Setup(sc => sc.GetBlobContainerClient(It.IsAny <string>())).Returns(blobContainerClientMock.Object);

            // Act
            await _instrumentStorageService.StoreInstrumentCandles(instrumentWithCandles);

            // Assert
            blobClientMock.Verify(bc => bc.UploadAsync(It.IsAny <Stream>(), true, It.IsAny <CancellationToken>()), Times.Exactly(1));
        }
        /// <summary>
        /// Get instrument with it's candles for a specific timerange
        /// with a specific granularity
        /// </summary>
        /// <param name="instrument">Name of the instrument</param>
        /// <param name="granularity">Granularity of the instrument</param>
        /// <param name="utcFrom">Time to get the candles from (taken as an UTC time)</param>
        /// <param name="utcTo">Time to get the candles to (taken as an UTC time)</param>
        /// <returns>The instrument object with it's candles</returns>
        public async Task <InstrumentWithCandles> GetInstrumentCandles(InstrumentName instrument, Granularity granularity, DateTime utcFrom, DateTime utcTo)
        {
            // Collect all blob names needed
            var blobNames = GetBlobPaths(instrument, granularity, utcFrom, utcTo);

            // Get the container client
            var containerClient = _storageService.GetBlobContainerClient(INSTRUMENT_CONTAINER);

            // Create returning instrument object
            var instrumentWithCandles = new InstrumentWithCandles()
            {
                InstrumentName = instrument,
                Granularity    = granularity,
                Candles        = new List <Candle>()
            };

            // Loop through the required blob files to get all candles data
            foreach (string blob in blobNames)
            {
                // Get the blob client
                var blobClient = containerClient.GetBlobClient(blob);

                // Download blob to stream
                using var stream = new MemoryStream();
                await blobClient.DownloadToAsync(stream);

                // Deserialize stream to object
                stream.Position = 0;
                var serializer = new JsonSerializer();
                using var streamReader   = new StreamReader(stream);
                using var jsonTextReader = new JsonTextReader(streamReader);
                var candles = serializer.Deserialize <IEnumerable <Candle> >(jsonTextReader);

                // Add it to the instrument
                // Since it is abstract ICollection
                // Do a loop
                foreach (var candle in candles)
                {
                    instrumentWithCandles.Candles.Add(candle);
                }
            }

            // Order candles by time (better safe then sorry)
            instrumentWithCandles.Candles.OrderBy(candle => candle.Time);

            // Return instrument with it's candles
            return(instrumentWithCandles);
        }
        /// <summary>
        /// Store candles
        /// </summary>
        /// <param name="instrument">The instrument object to store candles for</param>
        /// <returns></returns>
        public async Task StoreInstrumentCandles(InstrumentWithCandles instrument)
        {
            // Get or create container
            var containerClient = _storageService.GetBlobContainerClient(INSTRUMENT_CONTAINER);
            await containerClient.CreateIfNotExistsAsync();

            // Explode instrument to monthly candles list
            var candlesMonthly = instrument.Candles.ToLookup(c => new { c.Time.ToUniversalTime().Year, c.Time.ToUniversalTime().Month });

            // Base folder name
            var instrumentGranularityFolder = GetInstrumentFolder(instrument.InstrumentName, instrument.Granularity);

            // Upload that monthly data
            foreach (var yearAndMonth in candlesMonthly)
            {
                // Candles to upload
                var candlesToUpload = candlesMonthly[yearAndMonth.Key].ToList();

                // Download monthly data if exists
                try
                {
                    var startTime = new DateTime(yearAndMonth.Key.Year, yearAndMonth.Key.Month, 1, 0, 0, 0, DateTimeKind.Utc);
                    var endTime   = new DateTime(yearAndMonth.Key.Year, yearAndMonth.Key.Month, DateTime.DaysInMonth(yearAndMonth.Key.Year, yearAndMonth.Key.Month), 0, 0, 0, DateTimeKind.Utc);
                    var monthlyCandlesAlreadyThere = await GetInstrumentCandles(instrument.InstrumentName, instrument.Granularity, startTime, endTime);

                    candlesToUpload.AddRange(monthlyCandlesAlreadyThere.Candles);
                }
                catch
                {
                    // Swallow blob not found exception
                }

                // Serialize object to memory stream
                var serializedCandles = JsonConvert.SerializeObject(candlesToUpload);
                using var stream = new MemoryStream(Encoding.UTF8.GetBytes(serializedCandles));

                // Upload to blob
                await containerClient.GetBlobClient($"{instrumentGranularityFolder}/{GetMonthlyFile(yearAndMonth.Key.Year, yearAndMonth.Key.Month)}").UploadAsync(stream, true);
            }
        }
Exemple #4
0
        public async void StoreInstrumentCandles_WithoutExistingData()
        {
            // Arrange
            var instrument  = InstrumentName.EUR_USD;
            var granularity = Granularity.H1;
            var candles     = new List <Candle>()
            {
                new Candle()
                {
                    Time   = new DateTime(2015, 5, 12, 10, 00, 00, DateTimeKind.Utc),
                    Volume = 1234,
                    Bid    = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                    Mid = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                    Ask = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                },
                new Candle()
                {
                    Time   = new DateTime(2015, 6, 12, 10, 00, 00, DateTimeKind.Utc),
                    Volume = 1234,
                    Bid    = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                    Mid = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                    Ask = new Candlestick()
                    {
                        Open  = 1.1234,
                        High  = 1.1234,
                        Low   = 1.1234,
                        Close = 1.1234
                    },
                }
            };
            var instrumentWithCandles = new InstrumentWithCandles()
            {
                InstrumentName = instrument,
                Granularity    = granularity,
                Candles        = candles
            };
            var blobClientMock = new Mock <BlobClient>();

            blobClientMock.Setup(bc => bc.UploadAsync(It.IsAny <Stream>(), true, It.IsAny <CancellationToken>()));
            blobClientMock.Setup(bc => bc.DownloadToAsync(It.IsAny <Stream>())).Throws(new Exception()); // No already existing data found for the given months
            var blobContainerClientMock = new Mock <BlobContainerClient>();

            blobContainerClientMock.Setup(bcc => bcc.CreateIfNotExistsAsync(It.IsAny <PublicAccessType>(), null, null, It.IsAny <CancellationToken>()));
            blobContainerClientMock.Setup(bcc => bcc.GetBlobClient(It.IsAny <string>())).Returns(blobClientMock.Object);
            _storageClientMock.Setup(sc => sc.GetBlobContainerClient(It.IsAny <string>())).Returns(blobContainerClientMock.Object);

            // Act
            await _instrumentStorageService.StoreInstrumentCandles(instrumentWithCandles);

            // Assert
            blobClientMock.Verify(bc => bc.DownloadToAsync(It.IsAny <Stream>()), Times.Exactly(2));
            blobClientMock.Verify(bc => bc.UploadAsync(It.IsAny <Stream>(), true, It.IsAny <CancellationToken>()), Times.Exactly(2));
        }
Exemple #5
0
        public async void GetInstrumentCandles()
        {
            // Arrange
            var instrument  = InstrumentName.EUR_USD;
            var granularity = Granularity.H1;
            var from        = DateTime.UtcNow.AddDays(-5);
            var to          = DateTime.UtcNow.AddDays(-5).AddHours(1);
            var mockCandles = new InstrumentWithCandles()
            {
                InstrumentName = instrument,
                Granularity    = granularity,
                Candles        = new List <Candle>()
                {
                    new Candle()
                    {
                        Time   = DateTime.UtcNow.AddDays(-5),
                        Volume = 1234,
                        Bid    = new Candlestick()
                        {
                            Open  = 1.1234,
                            High  = 1.1234,
                            Low   = 1.1234,
                            Close = 1.1234
                        },
                        Mid = new Candlestick()
                        {
                            Open  = 1.1234,
                            High  = 1.1234,
                            Low   = 1.1234,
                            Close = 1.1234
                        },
                        Ask = new Candlestick()
                        {
                            Open  = 1.1234,
                            High  = 1.1234,
                            Low   = 1.1234,
                            Close = 1.1234
                        },
                    },
                    new Candle()
                    {
                        Time   = DateTime.UtcNow.AddDays(1),
                        Volume = 1234,
                        Bid    = new Candlestick()
                        {
                            Open  = 1.1234,
                            High  = 1.1234,
                            Low   = 1.1234,
                            Close = 1.1234
                        },
                        Mid = new Candlestick()
                        {
                            Open  = 1.1234,
                            High  = 1.1234,
                            Low   = 1.1234,
                            Close = 1.1234
                        },
                        Ask = new Candlestick()
                        {
                            Open  = 1.1234,
                            High  = 1.1234,
                            Low   = 1.1234,
                            Close = 1.1234
                        },
                    }
                }
            };

            _instrumentStorageServiceMock.Setup(iss => iss.GetInstrumentCandles(instrument, granularity, from, to)).Returns(Task.FromResult(mockCandles));

            // Act
            var instrumentWithCandles = await _instrumentCandlesController.GetInstrumentCandles(instrument, granularity, from, to);

            // Assert
            _instrumentStorageServiceMock.Verify(iss => iss.GetInstrumentCandles(instrument, granularity, from, to), Times.Once());
            Assert.Equal(mockCandles, instrumentWithCandles);
        }