You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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();

代码说明

  1. 直接对整个DataFrame调用ResampleEquivalence,以行索引(row.Key)除以2000作为分组键,实现每2000个Tick分为一组。
  2. 聚合时通过group.GetColumn<string>("time")获取分组内的时间列,调用Max()得到区间最大时间值(示例中的时间字符串格式可直接按字典序比较,与时间顺序一致)。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:55:35