tick数据合成k线的完整过程(含源代码)

写在前面

码上君量化互助社群已建立,所有源码免费对社群成员开放,如有需要请查看社群介绍文章,里面有加入社群的方式。

社群介绍:码上君量化互助社群介绍

公众号-码上助君(可跳转)
感兴趣的关注下公众号,优先发布,接收后续的更新内容会更及时奥


本文主要分享 tick 数据合成 k线 的完整过程,这样我们的策略就可以在此 k 线的基础上,计算各种技术指标(如ema、atr、kdj、macd等等)。

tick 数据的选择

国内股票行情是3秒一个切片,期货是1秒推送两个切片,由于期货行情是免费且无需登录验证,方便获取,所以选择期货行情数据进行k线合成。

在前面的文章中分享过期货行情订阅的代码,主要是以下回调函数:
在这里插入图片描述

相关链接:CTP-API开发系列之九:行情登录及订阅代码

行情结构体字段

在这里插入图片描述

行情结构体里面的字段比较多,大部分是没有用的,在行情回调函数中我们仅保存部分需要用到的字段,最主要的就是合约代码InstrumentID、更新时间UpdateTime、最新价LastPrice、累计成交量Volume、累计成交额Turnover

def OnRtnDepthMarketData(self, pDepthMarketData: 'CThostFtdcDepthMarketDataField') -> "void":
	# Volume 成交量
	if pDepthMarketData.Volume == 0:
		return
	md = f"{pDepthMarketData.TradingDay},{pDepthMarketData.UpdateTime},{pDepthMarketData.UpdateMillisec},{pDepthMarketData.InstrumentID}," \
         f"{pDepthMarketData.LastPrice},{pDepthMarketData.BidPrice1},{pDepthMarketData.BidVolume1},{pDepthMarketData.AskPrice1}," \
         f"{pDepthMarketData.AskVolume1},{pDepthMarketData.Volume},{pDepthMarketData.Turnover}"
	log_md.info(md)
tick 行情示例

先以读取文件的方式,将所有的tick数据保存到 DataFrame 中

f = open('./logs/md_20240925085557.csv')

titles = ['date', 'time', 'mill', 'id', 'last_price', 'bid_price1', 'bid_volume1', 'ask_price1', 'ask_volume1', 'volume', 'turnover']
datas = []

for one in f.readlines():
    d = one.replace(' ', '').split('INFO:')[1].split('[')[0].split(',')
    datas.append(d)
    result = dict(zip(titles, d))

df = pd.DataFrame(datas, columns=titles)
print(df)

这里面有部分数据是非交易时间的,期货的交易日是从夜盘开始的,所以也会看到部分夜盘的最后一笔行情,需要在合成的时候进行特殊处理。

这里订阅的期货全是市场的主力合约,为了展示方便,后面仅以螺纹钢rb2501合约为例进行合成:

data = df.loc[df['id'] == 'rb2501']
print(data)

在这里插入图片描述

批量合成1分钟k线方式

time的格式 HH:MM:SS,合成1分钟k线,我们先按照time字段取 HH:MM,将相同时分内的数据,第一条记录的last_price记为open,最后一条记录的last_price记为close,最大一条记录的last_price记为high,最小一条记录的last_price记为low

每一条记录的成交量增量、成交额增量都是减去上一条记录对应的数值,相同时分内的增量进行累加记为volume、turnover

data['last_price'] = data['last_price'].astype(float)
data['volume'] = data['volume'].astype(float)
data['turnover'] = data['turnover'].astype(float)

data['volume_change'] = data['volume'] - data['volume'].shift(1)
data['turnover_change'] = data['turnover'] - data['turnover'].shift(1)
data['minute'] = data['time'].str[0:5]

minute_grouped = data.groupby('minute')

df = pd.DataFrame()
df['open'] = minute_grouped.first()['last_price']
df['high'] = minute_grouped.max()['last_price']
df['low'] = minute_grouped.min()['last_price']
df['close'] = minute_grouped.last()['last_price']
df['volume'] = minute_grouped.agg({'volume_change': 'sum'})
df['turnover'] = minute_grouped.agg({'turnover_change': 'sum'})
print(df)

在这里插入图片描述

下图是某商业软件的截图,我们取09:02的k线进行对比,可以发现与我们合成的数据09:01这条数据是一致的,也就是说09:01这一分钟内的数据,最终形成的k线时间是下一分钟的时间
在这里插入图片描述

df['tmp_minute'] = df.index.tolist()
df['new_minute'] = df['tmp_minute'].shift(-1)
df = df.drop('tmp_minute', axis=1)
df.dropna(inplace=True)
df.rename(columns={'new_minute': 'minute'}, inplace=True)
df.set_index('minute', inplace=True)

df = df[1:-1]
print(df)

我们继续优化后,可以发现跟上图是一致的
在这里插入图片描述

在这里插入图片描述

增量合成1分钟k线方式

上面的合成k线的方式,是批量处理的,在实际的策略中,我们更需要的是一种增量合成的方式

来一条tick数据,进行一次合成,当1根k线完全合成后(HH:MM发生改变),再将合成的k线推送给相应的策略使用。

我们用一个函数实现该功能:
在这里插入图片描述

同时,我们还可以非常方便的进行各类指标的计算
在这里插入图片描述

添加到1min线队列的末尾 的位置的时候,就代表一根新的k线已经合成,此时可以推送需要的策略模块。

k线分钟级别扩展

以 rb2501 数据为例,我们从 27002 条tick数据,最终合成了 227 条1分钟级别的数据。

1分钟级别的数据对于绝大多数策略已经足够使用了,有了1分钟数据作为基础,在进行5分钟、10分钟、30分钟、1小时等级别的数据就更简单了,大家可以自行扩展。

源码获取方式

码上君量化互助社群已建立,所有源码免费对社群成员开放,包括文章的示例tick数据文件,如有需要请查看社群介绍文章,里面有加入社群的方式。

社群介绍:码上君量化互助社群介绍

公众号-码上助君(可跳转)
感兴趣的关注下公众号,优先发布,接收后续的更新内容会更及时奥

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值