我用的米框获取行情数据,我的逻辑需要找两个大阳线,需要获取日开盘价和日收盘价,日最高价,日最低价。而实盘中行情推送过来的bar是分钟数据,怎么才能获取开盘价和日收盘价,日最高价,日最低价?
我用的米框获取行情数据,我的逻辑需要找两个大阳线,需要获取日开盘价和日收盘价,日最高价,日最低价。而实盘中行情推送过来的bar是分钟数据,怎么才能获取开盘价和日收盘价,日最高价,日最低价?
自行使用分钟线合成,无非缓存下当日最高最低价、然后时间戳隔日时重置刷新就好
在论坛里面看到不少关于分钟合成日线的讨论,也试着实现了
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)
效果如下
,按照初始化使用天数,就会有多少条,
多谢张老师。。
你这是按照期货早上是开盘时间还是晚上是开盘时间,期货螺纹钢晚上是开盘时间。
是的,默认就是自然日。如果想按照国内期货期货时间,就是晚上九点开盘时间就是第二天的话。有个取巧的方法,就是把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)
请问一下这个代码只能盘中的时候用吧,
回测的时候无法使用,对吧?
常山之蛇 wrote:
请问一下这个代码只能盘中的时候用吧,
回测的时候无法使用,对吧?
回测也可以用,注释trading == False就可以;为了效率,建议放到一个专门方法做日线逻辑触发,改为一旦dataframe增多一条,出发日线逻辑
我写了一个:
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
找了好久 日线合成 感谢大神
杨永福 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线数据回测的时候
出现这个。能帮我看下哪里用的不对?