public static void MergeCandle(this CandleTableEntity entity, IFeedCandle candle, TimeInterval interval) { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } // 1. Check if candle with specified time already exist // 2. If found - merge, else - add to list // var cell = candle.DateTime.GetIntervalCell(interval); var tick = candle.DateTime.GetIntervalTick(interval); var existingCandle = entity.Candles.FirstOrDefault(ci => ci.Tick == tick && ci.Cell == cell); if (existingCandle != null) { // Merge in list var mergedCandle = existingCandle .ToCandle(entity.IsBuy, entity.DateTime, interval) .MergeWith(candle); entity.Candles.Remove(existingCandle); entity.Candles.Add(mergedCandle.ToItem(interval)); } else { // Add to list entity.Candles.Add(candle.ToItem(interval)); } }
public void MergeCandle(IFeedCandle candle, TimeInterval interval) { // 1. Check if candle with specified time already exist // 2. If found - merge, else - add to list // //var cell = candle.DateTime.GetIntervalCell(interval); var tick = candle.DateTime.GetIntervalTick(interval); var existingCandle = Candles.FirstOrDefault(ci => ci.Tick == tick); if (existingCandle != null) { // Merge in list var mergedCandle = existingCandle .ToCandle(PriceType == PriceType.Bid, DateTime, interval) .MergeWith(candle); Candles.Remove(existingCandle); Candles.Add(mergedCandle.ToItem(interval)); } else { // Add to list Candles.Add(candle.ToItem(interval)); } }
public static IFeedCandle MergeWith(this IFeedCandle target, IFeedCandle update) { if (target == null || update == null) { return(target ?? update); } if (target.IsBuy != update.IsBuy) { throw new InvalidOperationException(string.Format("Can't merge buy and sell candles. Source={0} Update={1}", target.ToJson(), update.ToJson())); } if (target.DateTime != update.DateTime) { throw new InvalidOperationException(string.Format("Can't merge candles with different DateTime property. Source={0} Update={1}", target.ToJson(), update.ToJson())); } return(new FeedCandle() { Open = update.Open, Close = update.Close, High = Math.Max(target.High, update.High), Low = Math.Min(target.Low, update.Low), IsBuy = target.IsBuy, DateTime = target.DateTime }); }
public void PriceValuesAreMerged() { DateTime dt = new DateTime(2017, 1, 1); // Case 1: Update values are taken // var target = new FeedCandle() { Open = 2, Close = 3, High = 4, Low = 1, IsBuy = true, DateTime = dt }; var update = new FeedCandle() { Open = 3, Close = 2, High = 5, Low = 0.1, IsBuy = true, DateTime = dt }; IFeedCandle merged = target.MergeWith(update); Assert.Equal(update.Open, merged.Open); Assert.Equal(update.Close, merged.Close); Assert.Equal(update.High, merged.High); Assert.Equal(update.Low, merged.Low); Assert.True(merged.IsBuy); Assert.Equal(merged.DateTime, dt); // Case 2: Target values are preserved // update = new FeedCandle() { Open = 3, Close = 2, High = 3, Low = 2, IsBuy = true, DateTime = dt }; merged = target.MergeWith(update); Assert.Equal(target.High, merged.High); Assert.Equal(target.Low, merged.Low); }
public static string PartitionKey(this IFeedCandle candle, PriceType priceType) { if (candle == null) { throw new ArgumentNullException(nameof(candle)); } return(CandleTableEntity.GeneratePartitionKey(priceType)); }
public static string RowKey(this IFeedCandle candle, TimeInterval interval) { if (candle == null) { throw new ArgumentNullException(nameof(candle)); } return(CandleTableEntity.GenerateRowKey(candle.DateTime, interval)); }
public static ApiAssetPairHistoryRateModel ToApiModel(string assetPairId, IFeedCandle buyCandle, IFeedCandle sellCandle) { return(new ApiAssetPairHistoryRateModel { Id = assetPairId, Ask = sellCandle.Close, Bid = buyCandle.Close }); }
public static void MergeCandle(this CandleTableEntity entity, CandleItem candle, TimeInterval interval) { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } IFeedCandle fc = candle.ToCandle(entity.IsBuy, entity.DateTime, interval); entity.MergeCandle(fc, interval); }
public Task InsertOrMergeAsync(IFeedCandle candle, string asset, TimeInterval interval, PriceType priceType) { this.storage.Add(new StoreItem() { candle = candle, asset = asset, interval = interval, priceType = priceType }); return(Task.Delay(200)); }
public static CandleItem ToItem(this IFeedCandle candle, TimeInterval interval) { return(new CandleItem() { Open = candle.Open, Close = candle.Close, High = candle.High, Low = candle.Low, Tick = candle.DateTime.GetIntervalTick(interval) }); }
public static ApiCandle ToApiCandle(this IFeedCandle candle) { return((candle != null) ? new ApiCandle { T = candle.DateTime, O = candle.Open, C = candle.Close, H = candle.High, L = candle.Low } : null); }
public static bool IsEqual(this IFeedCandle candle, IFeedCandle other) { if (other != null && candle != null) { return(candle.DateTime == other.DateTime && candle.Open == other.Open && candle.Close == other.Close && candle.High == other.High && candle.Low == other.Low && candle.IsBuy == other.IsBuy); } return(false); }
public async Task InsertOrMergeAsync(IFeedCandle candle, PriceType priceType, TimeInterval interval) { // Get candle table entity var partitionKey = CandleTableEntity.GeneratePartitionKey(priceType); var rowKey = CandleTableEntity.GenerateRowKey(candle.DateTime, interval); var entity = await _tableStorage.GetDataAsync(partitionKey, rowKey) ?? new CandleTableEntity(partitionKey, rowKey); // Merge candle entity.MergeCandle(candle, interval); // Update await _tableStorage.InsertOrMergeAsync(entity); }
/// <summary> /// Insert or merge candle value. /// </summary> public async Task InsertOrMergeAsync(IFeedCandle feedCandle, string asset, TimeInterval interval, PriceType priceType) { ValidateAndThrow(asset, interval, priceType); var repo = GetRepo(asset, interval); try { await repo.InsertOrMergeAsync(feedCandle, priceType, interval); } catch { ResetRepo(asset, interval); throw; } }
public async Task InsertOrMergeAsync(IFeedCandle candle, string asset, TimeInterval interval) { if (candle == null) { throw new ArgumentNullException(nameof(candle)); } if (string.IsNullOrEmpty(asset)) { throw new ArgumentNullException(nameof(asset)); } await InsertOrMergeAsync(new Dictionary <TimeInterval, IEnumerable <IFeedCandle> >() { { interval, new IFeedCandle[] { candle } } }, asset); }
public void SingleQuoteIsHandled() { DateTime dt = new DateTime(2017, 1, 1); IReadOnlyCollection <Quote> quotes = new Quote[] { new Quote() { AssetPair = "btcusd", IsBuy = true, Price = 100, Timestamp = dt }, }; IFeedCandle result = quotes.ToCandle(dt); Assert.NotNull(result); Assert.True(result.IsEqual(new FeedCandle() { Open = 100, Close = 100, High = 100, Low = 100, IsBuy = true, DateTime = dt })); }
public void QuotesToCandle_NormalScenario2() { DateTime dt = new DateTime(2017, 1, 1); IReadOnlyCollection <Quote> quotes = new Quote[] { new Quote() { AssetPair = "btcusd", IsBuy = false, Price = 100, Timestamp = dt.AddMinutes(1) }, new Quote() { AssetPair = "btcusd", IsBuy = false, Price = 101, Timestamp = dt } }; IFeedCandle result = quotes.ToCandle(dt); Assert.NotNull(result); Assert.True(result.IsEqual(new FeedCandle() { Open = 101, Close = 100, High = 101, Low = 100, IsBuy = false, DateTime = dt })); }
public static string ToJson(this IFeedCandle candle) { return((candle != null) ? $"{{ open:{candle.Open} close:{candle.Close} high:{candle.High} low:{candle.Low} isBuy:{candle.IsBuy} dateTime:{candle.DateTime.ToString("o")} }}" : string.Empty); }