金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 752|回复: 15

关于Python程序history_bars_date的获取昨日收盘价问题-1

[复制链接]

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
发表于 2025-6-10 22:09 | 显示全部楼层 |阅读模式
老师好!我用如下程序获取获某期货的昨日收盘价,目前报如下错误,请帮忙指正可能的错误,非常感谢!
21:11:00 > 合约 M00 的 bars 数据格式不正确
21:11:00 > 合约 RB00 的 bars 数据格式不正确
21:11:00 > 合约 FG00 的 bars 数据格式不正确
21:11:00 > 合约 C00 的 bars 数据格式不正确
21:11:00 > 合约 HC00 的 bars 数据格式不正确
21:11:00 > 合约 SA00 的 bars 数据格式不正确
21:11:00 > 合约 TA00 的 bars 数据格式不正确
21:11:01 > 合约 V00 的 bars 数据格式不正确
21:11:01 > 合约 MA00 的 bars 数据格式不正确
21:11:01 > 合约 I00 的 bars 数据格式不正确
21:11:01 > 合约 RM00 的 bars 数据格式不正确
21:11:01 > 合约 Y00 的 bars 数据格式不正确


源程序如下:
def get_previous_day_close(context, contract, current_time):
    """获取前一交易日下午15:00的收盘价"""
    try:
        previous_day = current_time.date() - datetime.timedelta(days=1)
        current_day = current_time.date()
        previous_str = previous_day.strftime('%Y-%m-%d') + '00:00:00'
        current_str = current_day.strftime('%Y-%m-%d') + '00:00:00'
        bars = history_bars_date(contract, previous_str, current_str, '1d', ['close'],skip_suspended=True,include_now=False)
        if bars is None or len(bars) < 1:
            print(f"无法获取 {contract} 的前一日收盘价,可能是数据缺失")
            return None
        if not all(isinstance(bar, dict) and 'close' in bar for bar in bars):
            print(f"合约 {contract} 的 bars 数据格式不正确")
            return None
        previous_close = bars[-1]['close']
        return previous_close
    except Exception as e:
        print(f"获取 {contract} 的前一日收盘价失败: {str(e)}")
        return None

回复

使用道具 举报

37

主题

9998

帖子

6万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
wenarm
发表于 2025-6-11 09:04 | 显示全部楼层
不是所有的ai都能写出标准代码。history_bars_date返回的数据类型&#8203;numpy.ndarray 对象。并非字典类型。
if not all(isinstance(bar, dict) and 'close' in bar for bar in bars):
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 09:38 | 显示全部楼层
多谢老师回复,我把代码改为如下内容,但是报如下错误,请老师帮忙多指点!
09:37:41 > 合约 BR00 的 numpy.ndarray 长度不足
09:37:41 > 合约 CY00 的 numpy.ndarray 长度不足

修订后代码如下:
def get_previous_day_close(context, contract, current_time):
    """获取前一交易日下午15:00的收盘价,兼容 numpy.ndarray 和 list[dict]"""
    try:
        # 计算起止字符串
        previous_day = current_time.date() - datetime.timedelta(days=1)
        current_day = current_time.date()
        start_str = previous_day.strftime('%Y-%m-%d') + '00:00:00'
        end_str = current_day.strftime('%Y-%m-%d') + '00:00:00'
               
#        previous_day = current_time.date() - datetime.timedelta(days=1)
#        start_str = previous_day.strftime('%Y-%m-%d') + ' 00:00:00'
#        end_str   = previous_day.strftime('%Y-%m-%d') + ' 23:59:59'
        bars = history_bars_date(contract, start_str, end_str, '1d', ['close'],
                                    skip_suspended=True, include_now=False)

        # 返回值为空或 None
        if bars is None:
            print(f"无法获取 {contract} 的前一日收盘价,返回 None")
            return None

        # numpy.ndarray 情况
        if isinstance(bars, np.ndarray):
            if bars.size < 1:
                print(f"合约 {contract} 的 numpy.ndarray 长度不足")
                return None
            # 如果是二维数组,第一列为 close
            if bars.ndim == 2:
                prev_close = float(bars[-1, 0])
            else:
                prev_close = float(bars[-1])
            return prev_close

        # list[dict] 情况
        if isinstance(bars, list):
            if len(bars) < 1:
                print(f"合约 {contract} 的 list 长度不足")
                return None
            last = bars[-1]
            if isinstance(last, dict) and 'close' in last:
                return float(last['close'])
            else:
                print(f"合约 {contract} 的 list 最后项格式不符: {last}")
                return None

        # 其他未知格式
        print(f"合约 {contract} 的 bars 返回类型未知: {type(bars)}")
        return None
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 10:15 | 显示全部楼层
老师好!针对以上报错,我已经修订如下代码,目前跑的是实盘交易,目前测出history_bars_date函数无法取回昨日的收盘价,而history_bars可以取回昨日收盘价,但是收盘价与实际实盘不一致,请帮忙告知如何精准取回昨日收盘价。非常感谢!



def get_previous_day_close(context, contract, current_time):
    """获取前一交易日下午收盘价;主方案 + fallback"""
    try:
        prev_day = current_time.date() - datetime.timedelta(days=1)
        start_str = prev_day.strftime('%Y-%m-%d') + ' 00:00:00'
        end_str   = prev_day.strftime('%Y-%m-%d') + ' 23:59:59'

        # 主方案:history_bars_date
        bars = history_bars_date(contract, start_str, end_str, '1d', ['close'],skip_suspended=True, include_now=False)

        # 判断并提取
        if isinstance(bars, np.ndarray):
            if bars.shape[0] >= 1:
                # 2D 数组时首列为 close
                return float(bars[-1,0] if bars.ndim==2 else bars[-1])
        elif isinstance(bars, list) and len(bars) >= 1 and isinstance(bars[-1], dict):
            return float(bars[-1]['close'])

        # 主方案失败,fallback:history_bars 最近2日日线
        fb = history_bars(contract, 2, '1d', ['close'],skip_suspended=True, include_now=False)
        if isinstance(fb, np.ndarray) and fb.shape[0] >= 2:
            return float(fb[-2,0] if fb.ndim==2 else fb[-2])
        if isinstance(fb, list) and len(fb) >= 2 and isinstance(fb[-2], dict):
            return float(fb[-2]['close'])

        # 若仍失败
        print(f"[跳过] {contract} 前一日收盘价不可用")
        return None

    except Exception as e:
        print(f"[异常] 获取 {contract} 前一日收盘价失败:{e}")
        return None
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 10:51 | 显示全部楼层
目前取history_bars函数返回的昨日收盘价,对应的期货涨跌幅为如下样例,
始终是当前涨幅第一: AG00, 对应涨幅=7.23%, 跌幅第一: JM00, 对应跌幅=-27.40%。始终是AG00和JM00的涨跌幅最大,这与实际盘面不符。
10:50:30 > 当前时间2025-06-11 10:50:30.242149,期货IDSC0000,当前价477.8999938964844,收盘价539.7000122070312,价差-11.450809137065598
10:50:30 > 当前时间2025-06-11 10:50:30.244337,期货IDBC00,当前价70410.0,收盘价69302.1015625,价差1.5986505640104485
10:50:30 > 当前时间2025-06-11 10:50:30.246550,期货IDRS00,当前价5138.0,收盘价5862.0,价差-12.350733538041624
10:50:30 > 合约 ZC00 最新价格数据长度不足
10:50:30 > 当前涨幅第一: AG00, 对应涨幅=7.23%, 跌幅第一: JM00, 对应跌幅=-27.40%
10:50:30 > 当前持仓: {'AG00': {'direction': 'long', 'open_price': 8908.0}, 'JM00': {'direction': 'short', 'open_price': 783.5}}
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 11:02 | 显示全部楼层
目前反映一个问题棘手的问题,就是history_bars返回值不准和history_bar_date无数据。希望得到老师的指点,多谢!
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 11:07 | 显示全部楼层
附件为实际的涨跌幅,与我们取值计算的涨跌幅差很远,一个是2%以内,另一个大于7%。请老师多指正!
截图202506111106535530.png
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 11:17 | 显示全部楼层
这是最新的证据以及验证结果。
以下是程序取值,请帮忙留意!history_bars函数返回的昨日收盘价,对应当前涨幅第一: AG00, 对应涨幅=7.23%, 跌幅第一: JM00, 对应跌幅=-27.40%。这与实际盘面不符,请帮忙给出可能的原因,这个严重影响我的程序效果!
回复

使用道具 举报

37

主题

9998

帖子

6万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
wenarm
发表于 2025-6-11 13:06 | 显示全部楼层
本帖最后由 技术006 于 2025-6-11 13:21 编辑
刘通 发表于 2025-6-11 11:17
这是最新的证据以及验证结果。
以下是程序取值,请帮忙留意!history_bars函数返回的昨日收盘价,对应当前 ...

1.涨幅有两种算法,一种是当前最新价和昨收比较。另一种是当前最新价与昨结算比较。
上图中显示牌中使用算法是第二种。

2.在你本地数据完整的情况下,history_bars和history_bar_date都应该能取值指定日期的数据。
你在取收盘价时,顺带把k线时间一并获取,并输出k线的日期。就能判断自己现在取的数据是哪一天。(5楼中的昨收的价格一定不是最近几天的范围内。你大概率缺失数据)


金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

12

主题

49

帖子

49

积分

Rank: 1

等级: 新手上路

注册:
2025-4-8
曾用名:
 楼主| 发表于 2025-6-11 14:31 | 显示全部楼层
老师,您好!多谢您的回复。我是用如下程序取昨日收盘价:
def get_previous_day_close(context, contract, current_time):
    """获取前一交易日的收盘价"""
    try:
        bars = history_bars(contract, 1, '1d', ['close'], skip_suspended=True, include_now=False)
        if bars is None or len(bars) < 1:
            print(f"无法获取 {contract} 的前一日收盘价")
            return None
        
        if isinstance(bars, np.ndarray):
            previous_close = bars[-1, 0] if bars.ndim == 2 else bars[-1]
        elif isinstance(bars, list) and all(isinstance(bar, dict) for bar in bars):
            previous_close = bars[-1]['close']
        else:
            print(f"无法识别 {contract} 的 bars 类型: {type(bars)}")
            return None
        
        return previous_close
    except Exception as e:
        print(f"获取 {contract} 的前一日收盘价失败: {str(e)}")
        return None
我用如下程序算涨跌幅的:
def calculate_price_change(context, contract):
    """计算给定合约的涨跌幅,使用文华交易软件逻辑"""
    current_time = datetime.datetime.now()
    try:
        current_price = get_current_price(contract)
        if current_price is None:
            return None

        if is_night_session(current_time):
            reference_price = get_today_afternoon_close(context, contract, current_time)
        else:
            reference_price = get_previous_day_close(context, contract, current_time)

        if reference_price is None:
            return None

        price_change = (current_price - reference_price) / reference_price * 100
        #print(f"当前时间{current_time},期货ID{contract},当前价{current_price},收盘价{reference_price},百分比{price_change}%")
        return price_change
    except Exception as e:
        print(f"计算 {contract} 的涨跌幅时出错: {str(e)}")
        return None
目前算出来的涨跌幅如下:
14:24:09 > 当前涨幅第一: AG00, 对应涨幅=6.98%, 跌幅第一: JM00, 对应跌幅=-27.03%
14:24:09 > 开多期货ID是 AG00: 涨幅=6.98%, 收盘价8312.0,交易价格=8892.0, 时间: 2025-06-11 14:24:09.292278,百分比6.977863330125119%
14:24:09 > 开空期货ID是 JM00: 跌幅=-27.03%, 收盘价1078.5,交易价格=787.0, 时间: 2025-06-11 14:24:09.309176,百分比-27.028280018544276%
14:24:09 > 当前持仓: {'AG00': {'direction': 'long', 'open_price': 8892.0}, 'JM00': {'direction': 'short', 'open_price': 787.0}}
这个收盘价就是get_previous_day_close函数获取的,非常不准。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 微信登录

本版积分规则

手机版|小黑屋|上海金之塔信息技术有限公司 ( 沪ICP备13035422号 )

GMT+8, 2025-6-30 11:46 , Processed in 0.106159 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表