vn.py量化社区
By Traders, For Traders.
Member
加入于:
帖子: 77
声望: 0

我用的米框获取行情数据,我的逻辑需要找两个大阳线,需要获取日开盘价和日收盘价,日最高价,日最低价。而实盘中行情推送过来的bar是分钟数据,怎么才能获取开盘价和日收盘价,日最高价,日最低价?

Administrator
avatar
加入于:
帖子: 4607
声望: 264

自行使用分钟线合成,无非缓存下当日最高最低价、然后时间戳隔日时重置刷新就好

Member
加入于:
帖子: 131
声望: 37

在论坛里面看到不少关于分钟合成日线的讨论,也试着实现了

  1. 这里把合成的日线HLOC信息放在pandas.DataFrame里面,因为日线分析的话,对运算时间要求不是特别高,DataFrame足矣
  2. 合成过程放在on_bar方法里面,对每个传入的分钟进行日线合并处理;
  3. 这里用了trading == False进行判断,就是只在策略初始化过程对于历史数据进行日线合并。在交易过程中,不对当天传入分钟数据进行处理。因为日线是长周期数据,放在程序启动时候调用使用就可以,不必要盘中分析,如果打算真要,注释掉这个就可以。
  4. 这里只是提供了这个DataFrame 放置日线数据和合并,具体如何分析还是要看使用者了
    加入全局变量, dayFrame存储日线
     import pandas as pd
     dayFrame = pd.DataFrame(columns=['datetime', 'high', 'low', 'open', 'close'])
    合并过程,在on_bar 方法中插入下面代码
     def on_bar(self, bar: BarData):
          if self.trading == False:
             # adjustedBarTime = bar.datetime + timedelta(hours = 5)
             if self.dayFrame.empty:
                 # 如果dayFrame 为空,先加入一条
                 self.dayFrame = self.dayFrame.append({'datetime': bar.datetime.date(), 'high':bar.high_price, 'low': bar.low_price, 'open': bar.open_price, 'close': bar.close_price},
                                            ignore_index=True)
             else:
                 self.dayFrame = self.dayFrame.sort_values(['datetime']).reset_index(drop=True)
                 # 如果dayFrame 不为空,先按照日期排序,
                 if bar.datetime.date() in self.dayFrame['datetime'].values:
                     # 如果是已有日期,对比high,low更新,并使用新close
                     self.dayFrame.loc[self.dayFrame['datetime'] == bar.datetime.date(), 'high'] = \
                         max(max(self.dayFrame.loc[self.dayFrame['datetime'] == bar.datetime.date(), 'high'].values),bar.high_price)
                     self.dayFrame.loc[self.dayFrame['datetime'] == bar.datetime.date(), 'low'] = \
                         min(min(self.dayFrame.loc[self.dayFrame['datetime'] == bar.datetime.date(), 'low'].values),bar.low_price)
                     self.dayFrame.loc[self.dayFrame['datetime'] == bar.datetime.date(), 'close'] = bar.close_price
                 else:
                     # 如果是新的日期,新建一条
                     self.dayFrame = self.dayFrame.append(
                         {'datetime': bar.datetime.date(), 'high': bar.high_price, 'low': bar.low_price,
                          'open': bar.open_price, 'close': bar.close_price},
                         ignore_index=True)

效果如下
,按照初始化使用天数,就会有多少条,
description

Member
avatar
加入于:
帖子: 144
声望: 3

多谢张老师。。

Member
加入于:
帖子: 77
声望: 0

你这是按照期货早上是开盘时间还是晚上是开盘时间,期货螺纹钢晚上是开盘时间。

Member
加入于:
帖子: 131
声望: 37

是的,默认就是自然日。如果想按照国内期货期货时间,就是晚上九点开盘时间就是第二天的话。有个取巧的方法,就是把bar时间加上5个小时,那么下午9点就变成明天1点,这样dataframe就会合并为下一天数据。而当天15点加上5点20点还是当天数据。
不过这样改很粗糙,只能支持国内时间和国内期货,如果服务器再其他时区,或者其他产品就另外分析。

另外周五晚上还有加2天,手机编辑,可以看看我的blog,就不修改

修改方法,定义局部变量adjustedBarTime,是传入bar.datetime 时间加5;代替后面新增代码中所有用到bar.datetime地方。

from datetime import datetime, timedelta
if self.trading == False:
    adjustedBarTime = bar.datetime + timedelta(hours = 5)
Member
avatar
加入于:
帖子: 144
声望: 3

请问一下这个代码只能盘中的时候用吧,
回测的时候无法使用,对吧?

Member
加入于:
帖子: 131
声望: 37

常山之蛇 wrote:

请问一下这个代码只能盘中的时候用吧,
回测的时候无法使用,对吧?

回测也可以用,注释trading == False就可以;为了效率,建议放到一个专门方法做日线逻辑触发,改为一旦dataframe增多一条,出发日线逻辑

Member
avatar
加入于:
帖子: 4
声望: 1

我写了一个:

class ComBarGenerator(BarGenerator):
    """
    For:
    1. generating 1 minute bar data from tick data
    2. generateing x minute bar/x hour bar data from 1 minute data

    Notice:
    1. for x minute bar, x must be able to divide 60: 2, 3, 5, 6, 10, 15, 20, 30
    2. for x hour bar, x can be any number
    """

    def __init__(
        self,
        on_bar: Callable,
        window: int = 0,
        on_window_bar: Callable = None,
        interval: Interval = Interval.MINUTE,
        on_day_bar: Callable = None
    ):
        """Constructor"""
        super(ComBarGenerator, self).__init__(on_bar, window, on_window_bar, interval)
        self.on_day_bar = on_day_bar
        self.day_bar = None
        self.today_open = None

    # ----------------------------------------------------------------------
    def update_day_bar(self, bar):
        """1分钟K线更新"""

        # If not inited, creaate window bar object
        if not self.day_bar:
            # Generate timestamp for bar data
            dt = bar.datetime.replace(hour=0, minute=0, second=0, microsecond=0)

            self.day_bar = BarData(
                symbol=bar.symbol,
                exchange=bar.exchange,
                datetime=dt,
                gateway_name=bar.gateway_name,
                open_price=bar.open_price,
                high_price=bar.high_price,
                low_price=bar.low_price
            )
        # Otherwise, update high/low price into window bar
        else:
            self.day_bar.high_price = max(
                self.day_bar.high_price, bar.high_price)
            self.day_bar.low_price = min(
                self.day_bar.low_price, bar.low_price)

        # Update close price/volume into window bar
        self.day_bar.close_price = bar.close_price
        self.day_bar.volume += int(bar.volume)
        self.day_bar.open_interest = bar.open_interest

        # Check if window bar completed
        finished = False
        if not self.last_bar:
            finished = False
            self.today_open = bar.open_price
        elif (self.last_bar.datetime.date() == bar.datetime.date()
                and bar.datetime.hour > 18 > self.last_bar.datetime.hour):
            finished = True
        elif (self.last_bar.datetime.date() != bar.datetime.date()
              and self.last_bar.datetime.hour < 18):
            finished = True

        if finished:
            self.on_day_bar(self.day_bar)
            self.day_bar = None
            self.today_open = bar.open_price

        # Cache last bar object
        self.last_bar = bar

    def get_today_open(self):
        return self.today_open
Member
加入于:
帖子: 51
声望: 2

找了好久 日线合成 感谢大神

Member
加入于:
帖子: 51
声望: 2

杨永福 wrote:

想问一下 怎么用呢 大神

from vnpy.app.cta_strategy import (
    CtaTemplate,
    StopOrder,
    TickData,
    BarData,
    TradeData,
    OrderData,
    BarGenerator,
    ArrayManager,
)
from vnpy.trader.constant import Interval,Direction
from strategies.my_strategy_tool import ComBarGenerator


class demo(CtaTemplate):
    author = "用Python的交易员"

    fast_window = 10
    slow_window = 20

    fast_ma0 = 0.0
    fast_ma1 = 0.0

    slow_ma0 = 0.0
    slow_ma1 = 0.0

    parameters = ["fast_window", "slow_window"]
    variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = ComBarGenerator(self.on_bar,1,self.on_day_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("策略初始化")
        self.load_bar(10)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("策略启动")
        self.put_event()

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("策略停止")

        self.put_event()

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.bg.update_day_bar(bar)

    def on_day_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return


        print("周期时间:{name}".format(name = bar.datetime))

        print("周期开盘价:{url}".format(url= bar.open_price))
        print("周期最高价价:{url}".format(url= bar.high_price))

        print("周期收盘价:{url}".format(url = bar.close_price))

这是复制你的那个 ComBarGenerator 写的 但是 我用1分钟K线数据回测的时候
description
出现这个。能帮我看下哪里用的不对?

© 2015-2019 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3

沪公网安备 31011502017034号