本文原创,如果转载请注明来源
该问题最终分成三篇文章予以最终解决,相关文章链接如下:
从tick数据中提取周期K线数据 —- 1)尝试与问题
从tick数据中提取周期k线数据 — 2)继续改进
从tick数据中提取周期k线数据 — 3)终极解决
def generate_kline_data(stockDF, zhouqi, output_file):
# print(stockDF)
#sys.exit(0)
stockDF.set_index('time',inplace=True)
# stockDF.index = pd.to_datetime(stockDF.index)
stockDF['amount'] = stockDF['price'] * stockDF['volume']
stockDF['amount'] = stockDF['amount'].apply(lambda x: round(x, 3))
df = stockDF.resample(zhouqi).last()
# print(df)
# period_stock_data['change'] = stockData['change'].resample(zhouqi).sum()
# period_stock_data['pct_chg'] = stockData['pct_chg'].resample(zhouqi).apply(lambda x: (x / 100 + 1.0).prod() - 1.0) * 100
df['open'] = stockDF['price'].resample(zhouqi).first()
df['close'] = stockDF['price'].resample(zhouqi).last()
df['high'] = stockDF['price'].resample(zhouqi).max()
df['low'] = stockDF['price'].resample(zhouqi).min()
df['vol'] = stockDF['volume'].resample(zhouqi).sum()
df['amount'] = stockDF['amount'].resample(zhouqi).sum()
# 去掉空值行
df = df[df['high'].notnull()]
df.reset_index(inplace=True)
df['time'] = df['time']+ pd.Timedelta(minutes=1)
# 去掉 volume, price, type 列
df.drop(columns=['volume', 'price', 'type'], inplace=True)
# print(df)
print(df.iloc[0])
print(str(df.iloc[0]['time']))
if str(df.iloc[0]['time']).find("09:3")<0:
df.loc[1,'open'] = df.iloc[0]['open']
df.loc[1,'high'] = max(df.iloc[0]['high'],df.iloc[1]['high'])
df.loc[1,'low'] = min(df.iloc[0]['low'],df.iloc[1]['low'])
df.loc[1,'vol'] = df.iloc[0]['vol']+df.iloc[1]['vol']
df.loc[1,'amount'] = df.iloc[0]['amount']+df.iloc[1]['amount']
#删除第一行
df = df.iloc[1:]
#修改最后一行
df.iloc[-1, df.columns.get_loc('time')] = df.iloc[-1]['time'] - pd.Timedelta(minutes=1)
print("----------------- end -----------------")
# 保存结果到CSV文件
df.to_csv(output_file, index=False)
上述代码中,解决了每日tick数据中的前两行,以及最后一行数据的日期问题。得到的计算结果与通达信显示结果基本上一致。
之所以说基本上,是因为通达信软件中的第一条数据中的成交额是直接 收盘价×成交量得到的。而本函数中该条数据中的成交额是9:25这一条数据单独算的成交额以及9:30单独算的成交额,两者之和算是修正后的第一条数据中的成交额,因而更加精确。
至此,算是彻底完成了从tick到k线数据的转换。