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

C# 如何过滤股票数据中Extended Trading Hours时段的盘后交易数据

美股常规交易时段数据高效筛选方案

实现思路

不需要遍历每条Aggregate做时区转换,仅需提前生成目标日期范围内所有常规交易日的交易时段Unix时间戳区间,后续筛选仅做数值比较,性能相比单条转换提升2个数量级以上。

具体实现

1. 前置处理:生成交易时段区间

// 定义PST时区,Windows环境用"Pacific Standard Time",Linux/macOS环境用"America/Los_Angeles"
TimeZoneInfo pstZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

// 生成所有交易日的常规时段Unix时间戳区间(仅需执行一次,次数等于交易日总数)
List<(long StartMsec, long EndMsec)> tradingSessionRanges = new();
for (DateTime date = aggrParams.FromDate.Date; date <= aggrParams.ToDate.Date; date = date.AddDays(1))
{
    // 跳过周末(美股周六周日休市)
    if (date.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday)
        continue;

    // 构造当日PST时区交易起止时间
    DateTime pstStart = new DateTime(date.Year, date.Month, date.Day, 9, 30, 0);
    DateTime pstEnd = new DateTime(date.Year, date.Month, date.Day, 16, 0, 0);

    // 转UTC后生成Unix毫秒时间戳,自动处理PST/PDT夏令时切换
    long startMsec = new DateTimeOffset(TimeZoneInfo.ConvertTimeToUtc(pstStart, pstZone)).ToUnixTimeMilliseconds();
    long endMsec = new DateTimeOffset(TimeZoneInfo.ConvertTimeToUtc(pstEnd, pstZone)).ToUnixTimeMilliseconds();

    tradingSessionRanges.Add((startMsec, endMsec));
}

注意:如果你的FromDate/ToDate是PST时区的日期,需要将你已有的时间戳转换代码修改为以下写法,保证时间基准一致:

long unixTimeMsecFromDate = new DateTimeOffset(TimeZoneInfo.ConvertTimeToUtc(aggrParams.FromDate, pstZone)).ToUnixTimeMilliseconds();
long unixTimeMsecToDate = new DateTimeOffset(TimeZoneInfo.ConvertTimeToUtc(aggrParams.ToDate, pstZone)).ToUnixTimeMilliseconds();

2. LINQ筛选常规交易时段数据

普通版本(适配任意顺序的Aggregate列表)

List<Aggregate> regularTradingData = allAggregates
    .Where(aggr => 
    {
        long ts = (long)aggr.UnixTimestamp;
        // 先过滤整体时间范围,快速排除无效数据
        if (ts < unixTimeMsecFromDate || ts > unixTimeMsecToDate)
            return false;
        // 判断是否落在任意常规交易时段内
        return tradingSessionRanges.Any(r => ts >= r.StartMsec && ts < r.EndMsec);
    }).ToList();

优化版本(适配已按时间戳升序排序的Aggregate列表)

如果你的原始数据已经按时间戳升序排列,可通过二分查找进一步降低判断开销:

long[] sessionStartTimes = tradingSessionRanges.Select(r => r.StartMsec).ToArray();
List<Aggregate> regularTradingData = new();
foreach (var aggr in allAggregates)
{
    long ts = (long)aggr.UnixTimestamp;
    if (ts < unixTimeMsecFromDate || ts > unixTimeMsecToDate)
        continue;
    
    // 二分查找匹配最近的交易时段
    int index = Array.BinarySearch(sessionStartTimes, ts);
    index = index < 0 ? ~index - 1 : index;
    
    if (index >= 0 && ts < tradingSessionRanges[index].EndMsec)
        regularTradingData.Add(aggr);
}

补充说明

  • Aggregate中定义的UnixTimestamp为decimal类型,由于Unix毫秒时间戳为整数,转换为long不会出现精度损失
  • 若需要排除美股法定节假日,可在生成交易时段区间的逻辑中增加节假日判断,跳过休市日期即可
  • 整个方案仅在生成区间时做时区转换,转换次数等于查询范围内的交易日数量,远低于逐行转换的次数,适合大数据量场景

内容的提问来源于stack exchange,提问作者Leon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:36:08