我有一个内存映射文件,其中保存着股市数据。我正在存储如下数据:
Symbol, Date, Open, High, Close, Low, Volume
AAPL,25/01/2019 03:00:00,153.55,153.9,153.9,153.55,821
AAPL,25/01/2019 03:02:00,154.2,154.21,154.21,154.2,966
现在,我们要获取每行的收盘价清单。确实我们需要这样,如果当前时间戳是25/01/2019 11:35:00 AM并且条件是15滴答,那么我需要从25/01/2019 11:19:00 AM到11:34的收盘价清单:凌晨00点。
我正在尝试使用子字符串和拆分来收盘价,但是我有超过10,000条记录,所以这会很奇怪。
string name = "AAPL,25/01/2019 03:00:00,153.55,153.9,153.9,153.55,821";
//name = name.Substring(name.IndexOf(',') + 1);
//name = name.Split(',').Last();
答案 0 :(得分:1)
您必须将任务分为两部分。首先读取文件并将其转换为适当的结构。为此,您必须创建一个代表一个股票数据记录的类:
public class StockData
{
public string Symbol { get; set; }
public DateTime Date { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Close { get; set; }
public decimal Low { get; set; }
public int Volume { get; set; }
}
然后创建一个读取数据的方法
private static IEnumerable<StockData> ReadStockData(string path)
{
const int ExpectedSize = 15000;
var stockData = new List<StockData>(ExpectedSize); // For efficiency. Defines starting size
// of internal buffer and avoids
// resizing operations.
foreach (string line in File.ReadLines(path)) {
string[] parts = line.Split(',');
if (parts.Length == 7) { // Exclude empty lines etc.
var data = new StockData {
Symbol = parts[0],
Date = DateTime.Parse(parts[1]),
Open = Decimal.Parse(parts[2]),
High = Decimal.Parse(parts[3]),
Close = Decimal.Parse(parts[4]),
Low = Decimal.Parse(parts[5]),
Volume = Int32.Parse(parts[6])
};
stockData.Add(data);
}
}
return stockData;
}
为简单起见,我未包含任何错误处理。您可能要使用TryParse
而不是Parse
等。但这取决于数据的质量。
然后您可以选择和分析数据
var data = ReadStockData(path);
var start = new DateTime(2019, 1, 25, 3, 0, 0);
var end = start.AddMinutes(15);
var result = data
.SkipWhile(d => d.Date < start)
.TakeWhile(d => d.Date <= end);
foreach (StockData sd in result) {
// ...
}
您还可以完全避免将库存数据缓存在列表中,而使用Iterator。
private static IEnumerable<StockData> ReadStockData(string path)
{
foreach (string line in File.ReadLines(path)) {
string[] parts = line.Split(',');
if (parts.Length == 7) { // Exclude empty lines etc.
var data = new StockData {
Symbol = parts[0],
Date = DateTime.Parse(parts[1]),
Open = Decimal.Parse(parts[2]),
High = Decimal.Parse(parts[3]),
Close = Decimal.Parse(parts[4]),
Low = Decimal.Parse(parts[5]),
Volume = Int32.Parse(parts[6])
};
yield return data;
}
}
}
优点是在消耗文件的同时读取文件。一旦TakeWhile
返回最后一个所需的记录,它也会停止读取和转换文件。但是,如果您打算对同一数据运行多个查询,则将其存储在列表中仍然有意义。使用迭代器方法,您仍然可以使用
var result = data
.SkipWhile(d => d.Date < start)
.TakeWhile(d => d.Date <= end)
.ToList();