金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 973|回复: 19

为何实盘行情我用history_bars_date函数无法获取到5分钟级别和30分钟级别的K线

[复制链接]

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
发表于 2025-6-23 23:11 | 显示全部楼层 |阅读模式
为何实盘行情我在开盘前几分钟用history_bars_date函数无法获取到5分钟级别和30分钟级别的K线?虽然20:55:00没有K线,但是SQHC00在2025-06-18 00:00:00到 2025-06-20 00:00:00期间其实本地是有K线的
以下是日志打印,日志内容是简化的

截图202506232305015582.png 截图202506232307216598.png 截图202506232310269465.png


回复

使用道具 举报

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
 楼主| 发表于 2025-7-3 11:38 | 显示全部楼层
我的测试代码根据时间节点传递给 history_bars_date函数的start_date, end_date参数.
我的时间节点信息获取在自有jzt_fuLegalStamp包中,另外交易日历类TradeCalendar是在自有包jzt_trade_calendar中.
由于这些包的代码较长, 如果你们有自己的时间节点信息获取函数,你们可自行替代. 如需要我提供,也可.
如下是我的测试代码:
##############################################################################
#                      test_history_bars_date
##############################################################################
import time
import datetime as DateTime
from jzt_trade_calendar import *   
from jzt_fuLegalStamp import *  
from PythonApi import *
   
class GlobalCls:
    def _init_(self):
        self.name = 'global var'
g = GlobalCls()
  
def IsPaperTrading(context):
    return context.run_info.run_type == 'paper_trading'   
#----------------------------------------
def init(context):
    g.context = context
    Print(f"context.run_info.frequency:{context.run_info.frequency}")
    Print(f"context.run_info.base_book_id:{context.run_info.base_book_id}")
    #-------------------------------------------------------------
    #                交易日历相关
    #-------------------------------------------------------------  
    earlyest_market_date = DateTime.datetime.strptime('19930915','%Y%m%d')
    if context.run_info.run_type == 'backtest':  
        start_date = context.run_info.start_date
    else:
        start_date = GetBasebookCurstamp()
    tmp_beg_dt = start_date - DateTime.timedelta(days=365*1) #PS:向前推1年
   
    if tmp_beg_dt.year < earlyest_market_date.year:
        tmp_beg_dt = earlyest_market_date
        
    tmp_end_dt = context.run_info.end_date + DateTime.timedelta(days=365*5) #PS:向后推x年
    #PS:仅返回回测或实盘时对应合约的历史交易日list,交易日类型是datetime.datetime
    context.tradedate_lst = get_trading_dates(tmp_beg_dt,tmp_end_dt) #获取交易日历
    #Print(f"get_trading_dates({tmp_beg_dt},{tmp_end_dt}) ret list. list[0]:{context.tradedate_lst[0]} list[-1]:{context.tradedate_lst[-1]}")
    #assert( context.tradedate_lst[0]-tmp_beg_dt < DateTime.timedelta(days=20) ) #获得的最早日期不能比要查询的起始日期过大
   
    g.trade_calendar = TradeCalendar(context.tradedate_lst)
      
    #-------------------------------------------------------------
    g.fu_1mtp_man = FuXmTimepointMan(1) #1分钟K时间节点管理对象
    g.fu_5mtp_man = FuXmTimepointMan(5) #5分钟K时间节点管理对象
    g.fu_30mtp_man = FuXmTimepointMan(30) #30分钟K时间节点管理对象
    #-------------------------------------------------------------
    if 0:
        context.universe = ['INSC0000',  
                    'SQHC00',   
                    'SQRU00',   
                    'SQSP00',   
                    'SQAU00',   
                    'INNR00',   
                    'DQV00',     
                    'ZQTA00',   
                    'ZQFG00',   
                    'DQM00',     
                    'DQJ00',     
                    'SQSN00',   
                    'ZQRM00',   
                    'ZQCF00',   
                    'DQEB00',   
                    'SQRB00',   
                    'SQPB00',   
                    'SQAG00',   
                    'DQPG00',   
                    'DQB00',     
                    'SQCU00',   
                    'DQJD00',   
                    'DQY00',     
                    'DQI00',     
                    'SQNI00',   
                    'DQP00',     
                    'ZQUR00',   
                    'ZQSA00',   
                    'ZQSF00',   
                    'SRX00', #'ZQSRX00',   
                    'AX00',  #'DQAX00',   
                    'ZQAP00',   
                    'ZQMA00',
                    'DQJM00'
                    ]
    else:
        context.universe = ['ZQSM00']
        
    Print("init finish")
    pass

# before_trading此函数会在每天基准合约的策略交易开始前被调用,当天只会被调用一次。--(选择实现)
def before_trading(context):
    pass


# 你选择的品种的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新。--(必须实现)
def handle_bar(context):
    #symbol = 'DQPG00'
    HISTORY_ITEMS_LIST = ['datetime', 'close']  
    STAMP_INDEX = 0
   
    target_dt = GetBasebookCurstamp()
    if target_dt != GetFuTimepoint('5m', target_dt):
        return
        
    is_all_symbols_bars_ok = True
    for symbol in context.universe:
        base_bars = history_bars(symbol, 1, context.run_info.frequency, HISTORY_ITEMS_LIST, include_now=True)
        #若该品种未休盘
        if len(base_bars) and PyramidBarStampToDatetime(base_bars[-1,STAMP_INDEX]) == target_dt:
            #获取所处30m级别K线--
            freq = '30m'  
            end_dt = GetFuTimepoint(freq, target_dt)
            pre_tp = GetFuPrexTimepoint(freq, target_dt)  
            bars_help = history_bars_date(symbol, pre_tp, end_dt, freq, HISTORY_ITEMS_LIST, include_now=True)
            
            if len(bars_help):
                fu_xmtp_man = GetFuXmtpMan(freq)  
                assert(fu_xmtp_man is not None)
                latest_bar_stamp = PyramidBarStampToDatetime(bars_help[-1,STAMP_INDEX])
                cur_timepoint = fu_xmtp_man.GetDateTimepoint_bydt(target_dt)
                if latest_bar_stamp == cur_timepoint:
                    #Print(f"{symbol} {freq} latest_bar_stamp:{latest_bar_stamp} == cur_timepoint:{cur_timepoint} ")
                    pass
                else:
                    is_all_symbols_bars_ok = False
                    Print(f"history_bars_date({symbol}, {pre_tp}, {end_dt}, {freq}, {HISTORY_ITEMS_LIST}, include_now=True) ret bars len:{len(bars_help)}")
                    info_comp = '>' if latest_bar_stamp > cur_timepoint else '<'
                    Print(f"Warning: {symbol} {freq} latest_bar_stamp:{latest_bar_stamp} {info_comp} cur_timepoint:{cur_timepoint} !")
                    assert(False)
            else:
                Print(f"Warning: history_bars_date({symbol}, {pre_tp}, {end_dt}, {freq}, {HISTORY_ITEMS_LIST}, include_now=True) ret bars len:{len(bars_help)}")
                is_all_symbols_bars_ok = False
    if is_all_symbols_bars_ok:
        #Print(f"is_all_symbols_bars_ok:{is_all_symbols_bars_ok}")
        pass
    pass
     
# after_trading函数会在每天交易结束后被调用,当天只会被调用一次。 --(选择实现)
def after_trading(context):
    pass
   
def exit(context):
    print(f"on exit")
   
def Print(content):
    dt_str = GetDatetimeForLogTag().strftime('%Y%m%d %H:%M:%S')
    print("[{}] {}".format(dt_str, content)) #PS:打印也是耗时操作   
###########################################################   
#                      时间节点相关 250620
###########################################################
def GetFuXmtpMan(freq):
    if freq == FREQ_1M: return g.fu_1mtp_man
    elif freq == FREQ_5M: return g.fu_5mtp_man
    elif freq == FREQ_30M: return g.fu_30mtp_man
    else: return None
   
def GetFuPrexTimepoint(freq:str, target_dt:DateTime.datetime):
    fu_xmtp_man = GetFuXmtpMan(freq)
    assert(fu_xmtp_man is not None)
    #if fu_xmtp_man is not None:
    return fu_xmtp_man.GetPreDateTimepoint_bydt(target_dt, g.trade_calendar)
     
def GetFuTimepoint(freq:str, target_dt:DateTime.datetime):
    fu_xmtp_man = GetFuXmtpMan(freq)
    assert(fu_xmtp_man is not None)
    #if fu_xmtp_man is not None:
    return fu_xmtp_man.GetDateTimepoint_bydt(target_dt)
   
#####################################################
#                  时间相关
#####################################################
def PyramidBarStampToDatetime(val):
    val = int(val)
    #print("PyramidBarStampToDatetime val:{}".format(val))
    return DateTime.datetime(year=int(val//10000000000),
        month= val%10000000000//100000000,
        day=   val%100000000//1000000,
        hour=  val%1000000//10000,
        minute=val%10000//100,
        second=val%100,
        microsecond=0)   
#现实时间
def GetActualDateTime():
    return DateTime.datetime.now()
     
def GetBasebookCurstamp():
    return g.context.now
   
def GetDatetimeForLogTag():
    if IsPaperTrading(g.context): return GetActualDateTime()
    else: return GetBasebookCurstamp()      

#根据程序运行模式获取当前时间(可以是模拟时间) PS:包含秒   
def GetCurrentDateTime():   
    if IsPaperTrading(g.context): return DateTime.datetime.now().replace(microsecond=0)
    else: return g.context.now.replace(microsecond=0)     
回复

使用道具 举报

21

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2025-6-24 08:45 | 显示全部楼层
你是不是打开过了K线图了。打开K线图会自动补充的。这会导致你检查数据时候是有的,实际前面调用时候未必有数据的。
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
 楼主| 发表于 2025-6-24 11:37 | 显示全部楼层
技术009 发表于 2025-6-24 08:45
你是不是打开过了K线图了。打开K线图会自动补充的。这会导致你检查数据时候是有的,实际前面调用时候未必有 ...

我是打开了HC00. 问题是,不打开检查的话,如何知道是不是本地数据缺失呢?
回复

使用道具 举报

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
 楼主| 发表于 2025-6-24 14:55 | 显示全部楼层
我刚刚补过数据,运行时也出现也是同样的问题
截图202506241453397938.png
截图202506241455245954.png
回复

使用道具 举报

21

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2025-6-24 15:54 | 显示全部楼层
历史的数据,先补充一批足量的。然后每天设置下收盘。

只要收盘不出问题,基本数据不会缺失的。
还有你调用5分钟,你补1分钟,当然不行了。他们是2个独立的基础周期。
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
 楼主| 发表于 2025-6-25 10:49 | 显示全部楼层
hello,
1.软件的收盘设置上次已经设置过了.
2. 2.1.有不少策略都是结合不同周期的,所谓看大做小. 所以客观上,单个策略有需要不同级别(x分钟,x小时,乃至日月级)数据的需求
   2.2 你是说本地5分钟级别K线数据不可以由1分钟级别K线生成?  那么3分钟级别K线数据是由1分钟级别K线数据生成吗?
3. 关于history_bars_date函数
   3.1 是否只要start_date, end_date之间存在完整的frequency级别的K线, 就应该可以查询到?
   3.2 include_now参数是跟end_date配合还是跟当前时间配合?
   3.3  此函数的start_date, end_date,哪个优先级更高? 因为我不知道:数据是从组装好的本地K线数据文件读取后选start_date/end_date所落脚的K进行截取?还是说根据start_date或end_date来进行组装?
   
回复

使用道具 举报

21

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2025-6-25 10:51 | 显示全部楼层
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
 楼主| 发表于 2025-6-25 11:18 | 显示全部楼层
技术009 发表于 2025-6-25 10:51
数据下载相关:https://www.weistock.com/docs/HELP/notes/%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86/%E6%95%B ...

根据这个说明书上说明: "历史任意周期数据只会由一种基础周期数据构成,若该周期历史数据不足,只需补充相应的基础周期数据。
若使用非5秒倍数的秒周期数据,需补充历史分笔数据。"
5分钟K线数据是由1分钟线吧?
*) 其实我更关心我的第3点的问题
回复

使用道具 举报

45

主题

259

帖子

259

积分

等级: 免费版

注册:
2023-9-29
曾用名:
 楼主| 发表于 2025-6-27 14:00 | 显示全部楼层
仿真盘,我调用history_bars_date,include_now=True,返回的结果不对,断言识别. 请问是什么原因?

补充内容 (2025-6-27 14:02):
断言失败了
今天13:40是 history_bars_date获取30m级别的K线,include_now=True
截图202506271353597404.png
回复

使用道具 举报

21

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2025-6-27 14:38 | 显示全部楼层
你这个报错信息不完整呀。 你下面traceback后面的报错是什么
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-5 21:28 , Processed in 0.105547 second(s), 26 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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