CTP tick数据合成K线的代码
Tick转K线的代码
tick已经存到本地csv,代码如下
import csv,random
from datetime import datetime,timedelta
import pandas as pd
with open('./data/rb2310_tick.csv',newline='') as f:
reader = csv.reader(f)
next(reader)#跳过首行
a=list(reader)
class Tick(object):
pass
class BarData(object):
def __init__(self):
self.symbol: str
self.exchange: str
self.date: time
self.open: float = 0
self.high: float = 0
self.low: float = 0
self.close: float = 0
self.volume: int = 0
self.openInterest: int = 0
def onBar(bar):
kline_list.append([bar.symbol,bar.exchange,bar.date,bar.open,bar.high,bar.low,bar.close,bar.volume,bar.openInterest])
return pd.DataFrame(kline_list,columns=['symbol','exchange','date','open','high','low','close','volume','open_interest'])
bar=None
lastVolume=0
kline_list=[]
for m in a:
tick=Tick()
tick.symbol=m[1]
tick.exchange=0 #未读取
tick.updateTime= datetime.strptime(m[25]+m[18], '%Y%m%d%H:%M:%S')
tick.lastPrice=round(float(m[2]),2)
tick.volume=int(m[9])#后面要与整型计算 字符串会报错
tick.openInterest=m[11]
if not bar:
newMinitue = True
elif tick.updateTime.minute != bar.date.minute:
sf=tick.updateTime.strftime('%H%M')
if sf=='1500':#最后1笔数据是有效数据 持仓量在变 收盘也可能不同
bar.close = tick.lastPrice
bar.openInterest = tick.openInterest
bar.volume += max(tick.volume-lastVolume,0)
bar.high = max(bar.high, tick.lastPrice)
bar.low = min(bar.low, tick.lastPrice)
#数据清理后 推送K线
if sf<='1500':
# 推送已经结束的上一分钟K线
bar.date+=timedelta(minutes=1)#以结束时间为K线结束
df=onBar(bar)
newMinitue = True
else:
newMinitue = False
if newMinitue :
bar= BarData()
bar.date =tick.updateTime.replace(second=0, microsecond=0)
bar.symbol = tick.symbol
bar.exchange = tick.exchange
bar.open = tick.lastPrice
bar.high = tick.lastPrice
bar.low = tick.lastPrice
else :
bar.high = max(bar.high, tick.lastPrice)
bar.low = min(bar.low, tick.lastPrice)
# 通用更新部分
bar.close = tick.lastPrice
bar.openInterest = tick.openInterest
#注意Volume字段是累计成交量,所以这个时间段内成交量为该值与上一时间段末成交量的差值
bar.volume += max(tick.volume-lastVolume,0)
lastVolume = tick.volume
df.set_index('date',inplace=True)
print(df)
Tick和K线都在内存中,就需要用字典根据不同合约各自保存
import random,csv
import pandas as pd
from datetime import datetime,timedelta
with open('./data/rb2310_tick.csv',newline='') as f:
reader = csv.reader(f)
next(reader)
a=list(reader)
with open('./data/au2310_tick.csv',newline='') as f:
reader = csv.reader(f)
next(reader)
b=list(reader)
with open('./data/sc2309_tick.csv',newline='') as f:
reader = csv.reader(f)
next(reader)
c=list(reader)
res=a+b+c
res.sort(key=lambda x: x[18])#根据tick时间排序
# [row[1]+' '+row[18] for row in res]#现在可以看到 从CTP获取数据一样的顺序了
class BarData(object):
def __init__(self):
self.symbol: str
self.exchange: str
self.date: time
self.open: float = 0
self.high: float = 0
self.low: float = 0
self.close: float = 0
self.volume: int = 0
self.openInterest: int = 0
self.lastVolume: int = 0
subID=('rb2310','au2310','sc2309')
gtick_map={}
gbar_map={}
bar={}
temp_d={}
for key in subID:
gtick_map[key]=[]
gbar_map[key]=[]
bar[key]=None
temp_d[key]={}
temp_d[key]['lastVolume']=0
def onBar(bar):
gbar_map[bar.symbol].append([bar.date,bar.symbol,bar.open,bar.high,bar.low,bar.close,bar.volume,bar.openInterest])
def tick2bar(tick):
symbol=tick['symbol']
if not bar[symbol]:
newMinitue = True
elif tick['updateTime'].minute != bar[symbol].date.minute:
sf=tick['updateTime'].strftime('%H%M')
#数据清理
if sf>'1500':
return
if sf=='1500':#最后1笔数据是有效数据 持仓量在变 收盘也可能不同
bar[symbol].close =tick['lastPrice']
bar[symbol].openInterest =tick['openInterest']
bar[symbol].high = max(bar[symbol].high, tick['lastPrice'])
bar[symbol].low = min(bar[symbol].low, tick['lastPrice'])
bar[symbol].volume += max(tick['volume']-temp_d[symbol]['lastVolume'],0)
bar[symbol].date+=timedelta(minutes=1)#以结束时间为K线结束
onBar(bar[symbol])
newMinitue = True
else:
newMinitue = False
if newMinitue :
bar[symbol]= BarData()
bar[symbol].date =tick['updateTime'].replace(second=0, microsecond=0)
bar[symbol].symbol = tick['symbol']
bar[symbol].exchange = tick['exchange']
bar[symbol].open =tick['lastPrice']
bar[symbol].high =tick['lastPrice']
bar[symbol].low = tick['lastPrice']
else :
bar[symbol].high = max(bar[symbol].high, tick['lastPrice'])
bar[symbol].low = min(bar[symbol].low, tick['lastPrice'])
#通用更新部分
bar[symbol].close =tick['lastPrice']
bar[symbol].openInterest =tick['openInterest']
bar[symbol].volume += max(tick['volume']-temp_d[symbol]['lastVolume'],0)
temp_d[symbol]['lastVolume']=tick['volume']
for i in res:
d={}
d['symbol']=i[1]
d['exchange']=0 #未读取
d['updateTime']=datetime.strptime(i[25]+i[18], '%Y%m%d%H:%M:%S')
d['lastPrice']=round(float(i[2]),2)
d['volume']=int(i[9])
d['openInterest']=i[11]
gtick_map[d['symbol']].append(d)
tick2bar(d)
df_bar=pd.DataFrame(gbar_map['au2310'],columns=['date','symbol','open','high','low','close','volume','open_interest'])
df_tick=pd.DataFrame(gtick_map['au2310'])
df_bar
相关资料:
https://zhuanlan.zhihu.com/p/80713696
https://zhuanlan.zhihu.com/p/40229144
存储和取出的问题
1、实时写入文件,实时读取文件;
2、Tick和K线放到内存,当天收盘后,把当天的数据追加到文件里,但Tick量很大,尤其订阅多个合约,对内存是一个考验。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具