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

Python处理日度金融数据生成月度OHLC数据遇问题求助

问题分析与代码修正:日度金融数据转月度数据

嘿,我看了你这段处理日度转月度金融数据的代码,确实在高低价计算这部分踩了好几个坑,咱们一一拆解并修正:

首先先明确你的需求:把日度数据转换成月度数据,每个月需要获取首个交易日的open、最后交易日的close、当月最高high、当月最低low。

先看你的原始数据:

price_data = [
    ['2018-05-05', '2.75', '2.05', '2.67', '2.92'],
    ['2018-05-08', '2.93', '2.97', '2.79', '2.84'],
    ['2018-05-09', '2.46', '2.74', '2.45', '2.69'],
    ['2018-05-10', '2.69', '2.69', '2.21', '2.33']
]

原代码的核心错误点

  • 循环起始索引错误:你从range(2, len(price_data))开始循环,直接跳过了前两个交易日,导致第一个月的初始数据完全丢失,逻辑从根上就错了。
  • 字符串直接比较价格:所有价格都是字符串类型(比如'2.97'),用>或<比较的是字符串字典序而非数值大小——比如'10.0'会被认为小于'2.0',这会导致高低价判断完全失真。
  • 高低价更新逻辑混乱:
    1. 你只在月份切换时初始化month_high和month_low,但当月后续交易日的更新逻辑位置错误,且仅和前一天价格对比,没有和当月已记录的高低价对比,会漏掉更高/更低的价格。
    2. 没有处理当月最后一个交易日的收盘价,也没有在月份切换时把上一个月的完整数据存入列表。
  • 月份切换判断不完整:跨年的月份切换逻辑(1月和12月)处理粗糙,且完全没覆盖同月份的持续更新场景。

修正后的代码实现

我换了更清晰的思路:先按年月分组存储数据,再对每组数据计算所需的月度指标,逻辑更直观,也避免了复杂的循环判断:

price_data = [
    ['2018-05-05', '2.75', '2.05', '2.67', '2.92'],
    ['2018-05-08', '2.93', '2.97', '2.79', '2.84'],
    ['2018-05-09', '2.46', '2.74', '2.45', '2.69'],
    ['2018-05-10', '2.69', '2.69', '2.21', '2.33'],
    ['2018-06-01', '2.35', '2.50', '2.20', '2.40']  # 新增跨月测试数据
]

# 第一步:统一转换数据类型,提取年月作为分组键
processed_data = []
for row in price_data:
    date_str = row[0]
    # 字符串价格转float,确保数值比较正确
    open_p = float(row[1])
    high_p = float(row[2])
    low_p = float(row[3])
    close_p = float(row[4])
    # 生成年月键(如'2018-05')用于分组
    year_month = '-'.join(date_str.split('-')[:2])
    processed_data.append((year_month, date_str, open_p, high_p, low_p, close_p))

# 第二步:按年月分组存储数据,自动计算月度指标
monthly_data = {}
for item in processed_data:
    ym, date, op, hp, lp, cp = item
    if ym not in monthly_data:
        # 首次遇到该月份,初始化:首个开盘价、初始高低价、初始收盘价
        monthly_data[ym] = {
            'first_date': date,
            'open': op,
            'high': hp,
            'low': lp,
            'close': cp
        }
    else:
        # 持续更新当月的高低价和最后收盘价
        monthly_data[ym]['high'] = max(monthly_data[ym]['high'], hp)
        monthly_data[ym]['low'] = min(monthly_data[ym]['low'], lp)
        monthly_data[ym]['close'] = cp  # 每次覆盖,最后就是当月最后交易日的收盘价

# 第三步:整理成你需要的列表格式
trading_day_l = []
month_open_l = []
month_high_l = []
month_low_l = []
month_close_l = []

# 按年月排序,保证时间顺序正确
for ym in sorted(monthly_data.keys()):
    trading_day_l.append(monthly_data[ym]['first_date'])
    month_open_l.append(monthly_data[ym]['open'])
    month_high_l.append(monthly_data[ym]['high'])
    month_low_l.append(monthly_data[ym]['low'])
    month_close_l.append(monthly_data[ym]['close'])

# 输出验证结果
print("月度首个交易日日期:", trading_day_l)
print("月度开盘价:", month_open_l)
print("月度最高价:", month_high_l)
print("月度最低价:", month_low_l)
print("月度收盘价:", month_close_l)

修正思路的优势

  1. 类型转换先行:彻底解决字符串价格比较的错误问题。
  2. 字典分组更直观:用年月作为键,每个月的数据独立存储,不需要手动判断月份切换,逻辑清晰易懂。
  3. 高低价更新简单可靠:用max()和min()直接对比更新,不会漏掉任何极值。
  4. 自动处理最后收盘价:每次覆盖当月收盘价,最后自然得到最后交易日的数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:14:42