当股票市场波动比较大,趋势性机会比较少的时候,做中长线的人往往被市场所累,遭受比较大的回撤;相反,如果能在掌握一些股票波动规律的基础上,做一些短线,反而会有不错的收益。而做短线,尤其是量化交易的话,日K线的数据周期太长,遗漏了太多的日内波动信息;而实时数据周期虽然段,但是噪音过多。5分钟线是比较理想的短周期数据。
之前的文章里面(https://zhuanlan.zhihu.com/p/37157872),写了如何利用BaoStock的历史日K线数据和实时行情,实现对盘中突破10日高点,且在20日均线上股票的提示买入信号。但是这样的信号有时间会频繁出现,,而且买入的时候,趋势可能已经走完了,如果股票不是基于基本面做长线的话,经常会遇到回撤,不适合进行短线交易。
所以,本人准备再接再厉,在之前的基础上,将实时行情转为短周期的K线,建立基于5分钟,15分钟,或者30分钟的短线交易策略。并且在盘中给出交易信号。以下是生成5分钟K线的程序。大家可以在此基础上,实现日内基于5分钟K线数据的短期策略。
首先默认已经安装python,且版本是3.5或者以上。
安装pandas: pip insall pandas
安装numpy: pip install numpy
安装baostock数据接口包:pip installbaostock。
baostock提供免费历史k线的下载,包括前后复权的数据,而且还提供股票实时数据
如果有问题,请去官网下载再安装:http://www.baostock.com,不需要注册。
import baostock as bs
import pandas as pd
import numpy as np
import datetime
#订阅实时行情,制定回调函数split_real_time_to_mins_k.
def test_real_time_stock_price(stockcode):
login_result = bs.login_real_time(user_id=’anonymous’, password=’123456′)
# 订阅
rs = bs.subscribe_by_code(stockcode, 0, split_real_time_to_mins_k, “”, “user_params”)
# rs = bs.subscribe_by_code(stockcode, 0, callbackFunc, “”, “user_params”)
if rs.error_code != ‘0’:
print(“request real time error”, rs.error_msg)
else:
# 使主程序不再向下执行。使用time.sleep()等方法也可以
text = input(“press any key to cancel real time \r\n”)
# 取消订阅
cancel_rs = bs.cancel_subscribe(rs.serial_id)
# 登出
login_result = bs.logout_real_time(“anonymous”)
# 每次收到实时行情后,回调此方法
def split_real_time_to_mins_k(ResultData):
#当盘中价格高于警示价格,输出提示信息。
#日期、时间、证券代码、股票名字、今日开盘价、昨日收盘价、当前价格、今日最高价、今日最低价、成交量、成交金额
for key in ResultData.data:
# print(ResultData.data[key])
# print(key,his_k_close_dict[key],ResultData.data[key])
#是否是新的行情
update_signal = False
new_update_timestr = ‘%s %s’%(ResultData.data[key][0],ResultData.data[key][1])
curr_time = datetime.datetime.strptime(new_update_timestr,’%Y-%m-%d %H:%M:%S’)
now_time = datetime.datetime.now()
# if now_time.hour > 15 or now_time.hour < 9:
# continue
# print(curr_time.year,curr_time.month,curr_time.day,curr_time.hour,curr_time.minute,curr_time.second)
if key in min_info_dict and ‘last_time’ in min_info_dict[key] :
if curr_time > min_info_dict[key][‘last_time’] and (curr_time.hour in (10,13,14) or (curr_time.hour == 9 and curr_time.minute >=30 )
or (curr_time.hour == 11 and curr_time.minute <= 30) or (curr_time.hour == 15 and curr_time.minute == 0)):
update_signal = True
else:
continue
else:
#初始化
min_info_dict[key] = {}
min_info_dict[key][‘last_time’] = curr_time
min_info_dict[key][‘5min’] = {}
min_info_dict[key][‘5min’][‘last_5min_k_time’] = curr_time
min_info_dict[key][‘5min’][‘openlist’] = []
min_info_dict[key][‘5min’][‘closelist’] = []
min_info_dict[key][‘5min’][‘highlist’] = []
min_info_dict[key][‘5min’][‘lowlist’] = []
min_info_dict[key][‘5min’][‘volumnlist’] = []
min_info_dict[key][‘5min’][‘amountlist’] = []
min_info_dict[key][‘5min’][‘timelist’] = []
update_signal = True
if update_signal:
#如果是新的行情,则获取新的价格,成交量等信息
newprice = float(ResultData.data[key][6])
newvolumn = float(ResultData.data[key][9])
newamount = float(ResultData.data[key][10])
# print(“%s at time %s the price is %f,volum :%f,amount: %f”%(key,new_update_timestr,newprice,newvolumn,newamount))
timeminus = curr_time – min_info_dict[key][‘5min’][‘last_5min_k_time’]
last_piece_time = min_info_dict[key][‘5min’][‘last_5min_k_time’]
# print(type(timeminus))
# print(timeminus.seconds)
#先判断K线是不是走完5分钟,如果走完5分钟,就计算该K线的全部数值,并且讲缓存的之前5分钟的数据清空
min_info_dict[key][‘last_time’] = curr_time
#mins 为5时是5分钟K线,为15时时15分钟K线,为30是30分钟k线
mins = 5
if (curr_time.minute != last_piece_time.minute and (curr_time.minute – 1) % mins == 0 and timeminus.seconds > 120) \
or (curr_time.hour == 13 and curr_time.minute == 0 and timeminus.seconds > 60) or timeminus.seconds == 0:
#5分钟k线走完
min_info_dict[key][‘5min’][‘last_5min_k_time’] = curr_time
min_info_dict[key][‘5min’][‘5min_bar_start_open’] = newprice
min_info_dict[key][‘5min’][‘5min_this_bar_high’] = newprice
min_info_dict[key][‘5min’][‘5min_this_bar_low’] = newprice
min_info_dict[key][‘5min’][‘5min_bar_start_volumn’] = newvolumn
min_info_dict[key][‘5min’][‘5min_bar_start_amount’] = newamount
if len(min_info_dict[key][‘5min’][‘volumnlist’]):
min_info_dict[key][‘5min’][‘volumnlist’].append(newvolumn – min_info_dict[key][‘5min’][‘5min_bar_start_volumn’])
min_info_dict[key][‘5min’][‘amountlist’].append(newamount – min_info_dict[key][‘5min’][‘5min_bar_start_amount’])
else:
min_info_dict[key][‘5min’][‘volumnlist’].append(0)
min_info_dict[key][‘5min’][‘amountlist’].append(0)
min_info_dict[key][‘5min’][‘openlist’].append(min_info_dict[key][‘5min’][‘5min_bar_start_open’])
min_info_dict[key][‘5min’][‘closelist’].append(newprice)
min_info_dict[key][‘5min’][‘highlist’].append(min_info_dict[key][‘5min’][‘5min_this_bar_high’])
min_info_dict[key][‘5min’][‘lowlist’].append(min_info_dict[key][‘5min’][‘5min_this_bar_low’])
min_info_dict[key][‘5min’][‘timelist’].append(‘%s’%(ResultData.data[key][1]))
print(min_info_dict[key][‘5min’][‘closelist’])
elif timeminus.seconds > 0:
#更新当前K线的数据
min_info_dict[key][‘5min’][‘5min_this_bar_high’] = max(newprice,min_info_dict[key][‘5min’][‘5min_this_bar_high’])
min_info_dict[key][‘5min’][‘5min_this_bar_low’] = min(newprice,min_info_dict[key][‘5min’][‘5min_this_bar_low’])
volumn = newvolumn – min_info_dict[key][‘5min’][‘5min_bar_start_volumn’]
amount = newamount – min_info_dict[key][‘5min’][‘5min_bar_start_amount’]
min_info_dict[key][‘5min’][‘volumnlist’][-1] = volumn
min_info_dict[key][‘5min’][‘amountlist’][-1] = amount
min_info_dict[key][‘5min’][‘openlist’][-1]= min_info_dict[key][‘5min’][‘5min_bar_start_open’]
min_info_dict[key][‘5min’][‘closelist’][-1] = newprice
min_info_dict[key][‘5min’][‘highlist’][-1] = min_info_dict[key][‘5min’][‘5min_this_bar_high’]
min_info_dict[key][‘5min’][‘lowlist’][-1] = min_info_dict[key][‘5min’][‘5min_this_bar_low’]
min_info_dict[key][‘5min’][‘timelist’][-1] = ‘%s’%(ResultData.data[key][1])
else:
print(“error “)
#输出5分钟K线的时间点,开盘价,最高价,最低价,收盘价,成交量数据
print(key,min_info_dict[key][‘5min’][‘last_5min_k_time’])
print(min_info_dict[key][‘5min’][‘timelist’])
print(min_info_dict[key][‘5min’][‘openlist’])
print(min_info_dict[key][‘5min’][‘highlist’])
print(min_info_dict[key][‘5min’][‘lowlist’])
print(min_info_dict[key][‘5min’][‘closelist’])
print(min_info_dict[key][‘5min’][‘volumnlist’])
if __name__ == ‘__main__’:
his_k_close_dict = {}
min_info_dict = {}
#默认股票池
stockcodelist = [‘sh.600000′,’sz.300009′,’sz.300182′,’sh.603568′,’sz.000049′,’sh.600518′,’sz.300532′,’sz.300423′,’sh.603816′,’sz.002262′,’sz.300010’, ‘sz.000049′,’sz.000413′,’sz.000869′,’sz.000848′,’sh.600495’]
# stockcodelist = [‘sh.600495’]
stockcodes = “”
for stockcode in stockcodelist:
stockcodes = “%s%s,”%(stockcodes,stockcode)
stockcodes = stockcodes[:-1]
print(stockcodes)
#获取实时行情数据,转化为5min数据,然后进行分析
test_real_time_stock_price(stockcodes)
这样就可以获取当日开盘以来的所有5分钟K线的数据了。