public static DynamicVolume GetVolume(List <DynamicDisk> disks, VolumeManagerDatabase database, VolumeRecord volumeRecord) { List <ComponentRecord> componentRecords = database.FindComponentsByVolumeID(volumeRecord.VolumeId); if (volumeRecord.NumberOfComponents != (ulong)componentRecords.Count || componentRecords.Count == 0) { // database record is invalid throw new InvalidDataException("Number of components in volume record does not match actual number of component records"); } if (componentRecords.Count == 1) { ComponentRecord componentRecord = componentRecords[0]; return(GetVolume(disks, database, volumeRecord, componentRecord)); } else // Mirrored volume { // Mirrored Simple Volume is the only kind of mirror suppored by Windows (only 2-way mirror is supported) // Veritas also supports Mirrored Stripe / Mirrored RAID-5 / Mirrored Spanned Volume (up to 32-way mirror is supported) List <DynamicVolume> volumes = new List <DynamicVolume>(); foreach (ComponentRecord componentRecord in componentRecords) { DynamicVolume volume = GetVolume(disks, database, volumeRecord, componentRecord); volumes.Add(volume); } MirroredVolume mirroredVolume = new MirroredVolume(volumes, volumeRecord.VolumeGuid, database.DiskGroupGuid); mirroredVolume.VolumeID = volumeRecord.VolumeId; mirroredVolume.Name = volumeRecord.Name; return(mirroredVolume); } }
private static Raid5Volume GetRAID5Volume(List <DynamicDisk> disks, VolumeManagerDatabase database, ComponentRecord componentRecord, VolumeRecord volumeRecord) { List <DynamicColumn> columns = GetDynamicVolumeColumns(disks, database, componentRecord, volumeRecord); Raid5Volume volume = new Raid5Volume(columns, (int)componentRecord.StripeSizeLBA, volumeRecord.VolumeGuid, database.DiskGroupGuid); volume.VolumeID = volumeRecord.VolumeId; volume.Name = volumeRecord.Name; volume.DiskGroupName = database.DiskGroupName; return(volume); }
private static SpannedVolume GetSpannedVolume(List <DynamicDisk> disks, VolumeManagerDatabase database, ComponentRecord componentRecord, VolumeRecord volumeRecord) { List <DynamicColumn> columns = GetDynamicVolumeColumns(disks, database, componentRecord, volumeRecord); SpannedVolume volume = new SpannedVolume(columns[0], volumeRecord.VolumeGuid, database.DiskGroupGuid); volume.VolumeID = volumeRecord.VolumeId; volume.Name = volumeRecord.Name; volume.DiskGroupName = database.DiskGroupName; return(volume); }
private static SimpleVolume GetSimpleVolume(List <DynamicDisk> disks, VolumeManagerDatabase database, ComponentRecord componentRecord, VolumeRecord volumeRecord) { List <ExtentRecord> extentRecords = database.FindExtentsByComponentID(componentRecord.ComponentId); if (extentRecords.Count == 1) { ExtentRecord extentRecord = extentRecords[0]; DiskRecord diskRecord = database.FindDiskByDiskID(extentRecord.DiskId); DynamicDisk disk = DynamicDiskHelper.FindDisk(disks, diskRecord.DiskGuid); // we add nulls as well DynamicDiskExtent extent = DynamicDiskExtentHelper.GetDiskExtent(disk, extentRecord); SimpleVolume volume = new SimpleVolume(extent, volumeRecord.VolumeGuid, database.DiskGroupGuid); volume.VolumeID = volumeRecord.VolumeId; volume.Name = volumeRecord.Name; volume.DiskGroupName = database.DiskGroupName; return(volume); } else { // component / extent records are invalid throw new InvalidDataException("Number of extents in component record does not match actual number of extent records"); } }
private static List <DynamicColumn> GetDynamicVolumeColumns(List <DynamicDisk> disks, VolumeManagerDatabase database, ComponentRecord componentRecord, VolumeRecord volumeRecord) { // extentRecords are sorted by offset in column List <ExtentRecord> extentRecords = database.FindExtentsByComponentID(componentRecord.ComponentId); if (componentRecord.NumberOfExtents != extentRecords.Count || extentRecords.Count == 0) { // database record is invalid throw new InvalidDataException("Number of extents in component record does not match actual number of extent records"); } SortedList <uint, List <DynamicDiskExtent> > columns = new SortedList <uint, List <DynamicDiskExtent> >(); foreach (ExtentRecord extentRecord in extentRecords) { DiskRecord diskRecord = database.FindDiskByDiskID(extentRecord.DiskId); DynamicDisk disk = DynamicDiskHelper.FindDisk(disks, diskRecord.DiskGuid); // we add nulls as well DynamicDiskExtent extent = DynamicDiskExtentHelper.GetDiskExtent(disk, extentRecord); if (columns.ContainsKey(extentRecord.ColumnIndex)) { columns[extentRecord.ColumnIndex].Add(extent); } else { List <DynamicDiskExtent> list = new List <DynamicDiskExtent>(); list.Add(extent); columns.Add(extentRecord.ColumnIndex, list); } } List <DynamicColumn> result = new List <DynamicColumn>(); foreach (List <DynamicDiskExtent> extents in columns.Values) { result.Add(new DynamicColumn(extents)); } return(result); }
private static DynamicVolume GetVolume(List <DynamicDisk> disks, VolumeManagerDatabase database, VolumeRecord volumeRecord, ComponentRecord componentRecord) { if (componentRecord.ExtentLayout == ExtentLayoutName.Concatenated) { if (componentRecord.NumberOfExtents == 1) { // Simple volume return(GetSimpleVolume(disks, database, componentRecord, volumeRecord));; } else { // spanned volume SpannedVolume volume = GetSpannedVolume(disks, database, componentRecord, volumeRecord); return(volume); } } else if (componentRecord.ExtentLayout == ExtentLayoutName.Stripe) { // striped volume StripedVolume volume = GetStripedVolume(disks, database, componentRecord, volumeRecord); return(volume); } else if (componentRecord.ExtentLayout == ExtentLayoutName.RAID5) { Raid5Volume volume = GetRAID5Volume(disks, database, componentRecord, volumeRecord); return(volume); } else { return(null); } }
private void Detect(StockLastTradeMessage lastTrade) { if (string.IsNullOrWhiteSpace(lastTrade?.Ticker) || lastTrade.Price == 0 || lastTrade.Size == 0) { return; } if (lastTrade.Price < _appSettings.Value.DataProcessing.MinimumPrice && lastTrade.Price > _appSettings.Value.DataProcessing.MaximumPrice) { return; } if (ValidSymbols.All(x => x.Symbol != lastTrade.Ticker)) { return; } var toDate = DateTime.Now; var fromDate = toDate.ResolveFromDate(_appSettings.Value.DataProcessing.TimeFrame); var openMarketStartTime = new DateTime(toDate.Year, toDate.Month, toDate.Day, 9, 30, 0); List <StockLastTrade> lastTrades = _lastTradesService.GetLastTrades(lastTrade.Ticker, fromDate, toDate, _appSettings.Value.DataProcessing.RecordLength, _appSettings.Value.DataProcessing.TimeFrame).GetAwaiter().GetResult(); if (!lastTrades.Any()) { return; } var groups = lastTrades.GroupBy(x => { var stamp = x.DateTime; stamp = stamp.AddMinutes(-(stamp.Minute % _appSettings.Value.DataProcessing.TimeFrame)); stamp = stamp.AddMilliseconds(-stamp.Millisecond - 1000 * stamp.Second); return(stamp); }) .Select(g => new OneMinuteDataGroup { TimeStamp = g.Key, LastTrades = g }) .Take(_appSettings.Value.DataProcessing.RecordLength).ToList(); var groupedRecords = groups.Select(x => new VolumeRecord { Date = x.TimeStamp, Price = (double)x.LastTrades.First().Price, Volume = x.LastTrades.Sum(r => r.Size), VolumeFriendly = x.LastTrades.Sum(r => (double)r.Size).HumanReadable(4), TimeFrame = _appSettings.Value.DataProcessing.TimeFrame.ToString(), TrendType = TrendType.Neutral, }).ToList(); if (!groupedRecords.Any()) { return; } var records = new List <VolumeRecord>(); foreach (var x in groupedRecords.Where(x => x.Date != openMarketStartTime).ToList()) { var r = new VolumeRecord(); r.Date = x.Date; r.Price = x.Price; r.Volume = x.Volume; r.Ticker = lastTrade.Ticker; r.VolumeFriendly = x.VolumeFriendly; r.TrendType = x.ResolveTrendType(groupedRecords); r.Ratio = x.CalculateRatio(groupedRecords); r.TimeFrame = _appSettings.Value.DataProcessing.TimeFrame.ToString(); r.AverageVolume = groupedRecords.Any(t => t.Date != x.Date) ? groupedRecords.Where(t => t.Date != x.Date).Average(a => a.Volume).HumanReadable(4) : "N/A"; records.Add(r); } if (!records.Any()) { return; } var avgRatio = records.Average(x => x.Ratio); var spikeRatio = avgRatio + (avgRatio * _appSettings.Value.DataProcessing.RatioPercentage / 100); if (records[0].Ratio >= spikeRatio) { var volumeSpike = new Trader.Domain.VolumeSpike { Ticker = lastTrade.Ticker, Date = toDate, MinuteTimeFrame = _appSettings.Value.DataProcessing.TimeFrame, VolumeRecords = records }; if (volumeSpike.VolumeRecords.Any()) { VolumeRecord volumeRecord = volumeSpike.VolumeRecords[0]; volumeRecord.Date = DateTime.Now; volumeRecord.ApiType = ApiType.Polygon; var symbol = ValidSymbols.FirstOrDefault(x => x.Symbol == volumeRecord.Ticker); if (symbol != null) { volumeRecord.Industry = symbol.Industry; volumeRecord.Sector = symbol.Sector; } switch (volumeRecord.TrendType) { case TrendType.Bullish: _logger.LogInformation("---------MADE IT 1-------------r"); _volumeRecordService.SaveVolumeRecord(volumeRecord); break; case TrendType.Bearish: _logger.LogInformation("---------MADE IT 2-------------r"); _volumeRecordService.SaveVolumeRecord(volumeRecord); break; case TrendType.None: break; case TrendType.Neutral: break; default: throw new ArgumentOutOfRangeException(); } } } }
public void SaveVolumeRecord(VolumeRecord r) { _collection.InsertOne(r); }