使用Deedle重采样Tick数据生成OHLC并输出区间最大Time
问题:使用Deedle按Tick区间生成OHLC时获取区间最大时间值
我尝试用Deedle解析包含Tick数据的CSV文件,基于lastPrice列通过ResampleEquivalence按2000 Tick区间生成Open、High、Low、Close(OHLC)值,但无法输出对应区间的最大Time值,求解决方法。
CSV数据示例
"time", "lastPrice", "bidPrice", "askPrice", "volume" 20230208 050001 0040000;4175.25;4175;4175.25;3 20230208 050001 1040000;4175.25;4175.25;4175.5;1 20230208 050001 1040000;4175.25;4175.25;4175.5;2 20230208 050001 3520000;4175.25;4175;4175.25;1 20230208 050007 1880000;4175.25;4175;4175.25;1 20230208 050007 8520000;4175.25;4175;4175.25;1 20230208 050008 8280000;4175.25;4175;4175.25;1 20230208 050010 2920000;4175;4175;4175.25;1 20230208 050010 2920000;4175;4175;4175.25;1 20230208 050010 2920000;4175;4175;4175.25;1 20230208 050010 2920000;4175;4175;4175.25;1 20230208 050010 2920000;4175;4175;4175.25;1 20230208 050010 3520000;4175;4175;4175.25;1
我编写的代码
var df = Frame.ReadCsv("./Data/ES 03-23.Last.txt", hasHeaders: false, separators: ";").IndexColumnsWith(new[] { "time", "lastPrice", "bidPrice", "askPrice", "volume" }); var prices = df["lastPrice"]; var agg = prices.ResampleEquivalence(kv => { return kv / 2000; } ).Select(data => new { Timestamp = data.ToString(), Open = data.Value.FirstValue(), High = data.Value.Max(), Close = data.Value.LastValue(), Low = data.Value.Min() }); Frame.FromRecords(agg).Print();
解决方法
问题根源在于你仅对lastPrice单列做重采样,无法访问到time列的分组数据。需要对整个DataFrame按Tick行索引分组,才能同时聚合时间和价格数据。
修改后的代码
var df = Frame.ReadCsv("./Data/ES 03-23.Last.txt", hasHeaders: false, separators: ";") .IndexColumnsWith(new[] { "time", "lastPrice", "bidPrice", "askPrice", "volume" }); // 按每2000个Tick分组,行索引从0开始,用索引除以2000作为分组键 var agg = df.ResampleEquivalence(row => row.Key / 2000) .Select(group => new { MaxTimestamp = group.GetColumn<string>("time").Max(), Open = group.GetColumn<double>("lastPrice").FirstValue(), High = group.GetColumn<double>("lastPrice").Max(), Low = group.GetColumn<double>("lastPrice").Min(), Close = group.GetColumn<double>("lastPrice").LastValue() }); Frame.FromRecords(agg).Print();
代码说明
- 直接对整个DataFrame调用
ResampleEquivalence,以行索引(row.Key)除以2000作为分组键,实现每2000个Tick分为一组。 - 聚合时通过
group.GetColumn<string>("time")获取分组内的时间列,调用Max()得到区间最大时间值(示例中的时间字符串格式可直接按字典序比较,与时间顺序一致)。 - OHLC值的计算逻辑保持不变,从分组的DataFrame中提取
lastPrice列完成计算。
进阶优化(确保时间比较准确性)
如果后续时间格式变化,字符串字典序可能无法正确反映时间顺序,可先将time列转换为DateTime类型再取最大值:
using System.Globalization; var df = Frame.ReadCsv("./Data/ES 03-23.Last.txt", hasHeaders: false, separators: ";") .IndexColumnsWith(new[] { "time", "lastPrice", "bidPrice", "askPrice", "volume" }); // 将time列转换为DateTime类型 df = df.AddColumn("datetime", df["time"].Select(t => DateTime.ParseExact(t.ToString(), "yyyyMMdd HHmmssffffff", CultureInfo.InvariantCulture))); var agg = df.ResampleEquivalence(row => row.Key / 2000) .Select(group => new { MaxTimestamp = group.GetColumn<DateTime>("datetime").Max().ToString("yyyyMMdd HHmmssffffff"), Open = group.GetColumn<double>("lastPrice").FirstValue(), High = group.GetColumn<double>("lastPrice").Max(), Low = group.GetColumn<double>("lastPrice").Min(), Close = group.GetColumn<double>("lastPrice").LastValue() }); Frame.FromRecords(agg).Print();
内容的提问来源于stack exchange,提问作者mike123
相关产品推荐
相关产品推荐

