股票k线统计,统计内容为:
a.以日线分析,出现连续红、连续绿、绿转红、红转绿的概率 b.出现连续红、连续绿时,连续几天的概率最高 c.结合成交量分析,缩量上涨、下跌,下一天出现红、绿的概率,扩量上涨、下跌,下一天出现红、绿的概率 d.统计所有日期,上涨、下跌多少幅度的概率最高 不考虑:高开低走但是收盘高于昨天的情况(表现为当天是绿的,但价格比昨天上涨),低开高走同理
将字典转换成格式化的JSON串
class Convert:
#将字典转换成json格式化输出
def convert_dict_to_format_json(self,mydict):
return json.dumps(mydict,sort_keys=True,indent=2,ensure_ascii=False)
统计列表中的值,出现的概率
#统计列表中的值,出现的概率,注意,tg_list是整数列表
def find_out_appear_rate(tg_list):
#将值作为键,统计其出现概率,放入字典
tg_dict={}
key_name_set=set(tg_list)
for i in key_name_set:
tg_dict[str(i)]=round(tg_list.count(i)/len(tg_list),2)
return tg_dict
获取股票数据
import tushare as ts
import pandas as pd
# 加了这一行那表格的一行就不会分段出现了
pd.set_option('display.width', 1000)
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
ts.set_token('这里替换自己的token')#从https://tushare.pro/获取
pro=ts.pro_api()
#获取股票数据
def get_stock_data(data_type,ts_code):
'''
:param data_type:
ths_daily(同花顺板块指数行情)
cb_daily(可转债行情)
:param ts_code:
:return:
'''
if data_type=='cb_daily':
df = pro.cb_daily(ts_code=ts_code,start_date='20240101',end_date='20240428')
elif data_type=='ths_daily':
df=pro.ths_daily(ts_code='883980.TI', start_date='20190701', end_date=myTime().mydate(), fields='ts_code,trade_date,open,close,high,low,pct_change')
else:
df=''
return df
对获取到的股票数据进行统计
#出现连续红、连续绿、绿转红、红转绿的概率
def find_out_red_green_change_rate(tg_list):
#使用双指针法
pre=-1
cur=0
lianxu_hong_list=[]
lianxu_lv_list=[]
lianxu_hong_count=0
lianxu_lv_count=0
hong_to_lv_count=0
lv_to_hong_count=0
#初始标记为None
pre_mark=None
while cur<len(tg_list):
#当前值
cur_value=tg_list[cur]
#如果当前值为正,标记为红,为0标记为前值,为负标记为绿
if cur_value>0:
mark='hong'
#当为红色,判断前值是否也是红色,如果是红色,代表颜色连续,连续值+=1,如果前值为绿色,代表绿转红,绿转红+=1
if pre_mark=='hong':
lianxu_hong_count+=1
else:
lv_to_hong_count+=1
#此时发生了颜色变更,将连续绿的计数值重置为0
if lianxu_lv_count>0:
lianxu_lv_list.append(lianxu_lv_count)
lianxu_lv_count=0
elif cur_value<0:
mark='lv'
if pre_mark=='lv':
lianxu_lv_count+=1
else:
hong_to_lv_count+=1
if lianxu_hong_count>0:
lianxu_hong_list.append(lianxu_hong_count)
lianxu_hong_count=0
else:
mark=pre_mark
#如果前值为红,则红连续+=1,如果是绿,则绿连续+=1
if pre_mark=='hong':
lianxu_hong_count+=1
else:
lianxu_lv_count+=1
#将本轮的mark值赋值给pre_mark,方便指针往下移
pre_mark=mark
pre+=1
cur+=1
#列表总个数
total_count=len(tg_list)
#连续红的个数
total_hong=sum(lianxu_hong_list)
#连续绿的个数
total_lv=sum(lianxu_lv_list)
result='''连续红的个数%d
连续绿的个数%d
绿转红的个数%d
红转绿的个数%d''' % (total_hong,total_lv,lv_to_hong_count,hong_to_lv_count)
print(result)
print('连续红的个数分布:',end='')
# print(lianxu_hong_list)
print(Convert().convert_dict_to_format_json(find_out_appear_rate(lianxu_hong_list)))
print('连续绿的个数分布:',end='')
# print(lianxu_lv_list)
print(Convert().convert_dict_to_format_json(find_out_appear_rate(lianxu_lv_list)))
1、含可转债(指数代码:883980.TI,区间:20190701-20240426)
result=get_stock_data('ths_daily','')
tg_list=list(result["pct_change"])
find_out_red_green_change_rate(tg_list)
执行结果:
连续红的个数339
连续绿的个数260
绿转红的个数281
红转绿的个数280
连续红的个数分布:{
"1": 0.41,
"2": 0.27,
"3": 0.14,
"4": 0.08,
"5": 0.07,
"6": 0.01,
"7": 0.02,
"9": 0.01
}
连续绿的个数分布:{
"1": 0.49,
"2": 0.26,
"3": 0.15,
"4": 0.05,
"5": 0.02,
"6": 0.02
}
由于该指数从成立以来,整体是上涨的,所以红的个数较多。但是发现,连续红、连续绿、绿转红、红转绿的概率其实基本大体一致。连续收红、连续收绿中,出现一次的概率最大,基本占了一半。能够连涨三天、连跌三天的概率是1/4左右。所以连涨三天或连跌三天后,下一天变盘的概率很大。
通过肉眼观察,连跌7天后涨了三天,然后继续连跌六天。接着就大幅反弹,基本回到起跌点。
2、上证指数(指数代码:000001.SH,区间:20180605-20240426)
之所以取20180605是因为当天开盘点位3088等于20240426收盘点位
result=get_stock_data('index_daily','000001.SH')
# print(list(result["pct_change"]))
tg_list=list(result["pct_chg"])
find_out_red_green_change_rate(tg_list)
执行结果:
连续红的个数345
连续绿的个数337
绿转红的个数375
红转绿的个数374
连续红的个数分布:{
"1": 0.47,
"2": 0.29,
"3": 0.13,
"4": 0.07,
"5": 0.03,
"6": 0.01,
"7": 0.01
}
连续绿的个数分布:{
"1": 0.51,
"2": 0.28,
"3": 0.14,
"4": 0.04,
"5": 0.03,
"6": 0.01
}
依旧符合之前的观察,连续相同颜色的概率略小于改变颜色的概率。但是相差不大。而连续两天相同颜色的概率是所有连续中可能性最大的。(变颜色的概率占了一半,而连续两天后继续保持的概率是0.5*0.5=0.25)。假设当前已经红了两天,那么第三天还是红的概率是:0.5*0.25=0.125
根据成交量分析下一天的走势
#根据成交量变化,预测下一天涨跌
def find_out_next_day_according_to_vol(pct_chg_list,vol_list):
pre,cur=-1,0
pre_vol=0
suo_hong_count=0
suo_lv_count=0
kuo_hong_count=0
kuo_lv_count=0
while cur<len(pct_chg_list):
cur_value=pct_chg_list[cur]
cur_vol=vol_list[cur]
#缩量
if cur_vol<=pre_vol:
#为红
if cur_value>=0:
suo_hong_count+=1
else:
suo_lv_count+=1
else:
if cur_value>=0:
kuo_hong_count+=1
else:
kuo_lv_count+=1
pre_vol=cur_vol
pre+=1
cur+=1
result='''缩量上涨个数%d
缩量下跌个数%d
扩量上涨个数%d
扩量下跌个数%d''' % (suo_hong_count,suo_lv_count,kuo_hong_count,kuo_lv_count)
print(result)
result=get_stock_data('index_daily','000001.SH')
# print(list(result["pct_change"]))
tg_list=list(result["pct_chg"])
# find_out_red_green_change_rate(tg_list)
vol_list=list(result["vol"])
find_out_next_day_according_to_vol(tg_list,vol_list)
执行结果:
缩量上涨个数385
缩量下跌个数318
扩量上涨个数336
扩量下跌个数393
依旧是大体上一致。不管是成交量扩大还是缩小,下一天的走势大体上是无序的。但是:缩量时上涨的概率大,扩量时下跌的概率大。
继续细分,考虑前一天的上涨和下跌,改造函数如下
#根据成交量变化,预测下一天涨跌
def find_out_next_day_according_to_vol(pct_chg_list,vol_list):
pre,cur=-1,0
pre_pct_chg=0
pre_vol=0
hong_suo_hong_count=0
hong_suo_lv_count=0
hong_kuo_hong_count=0
hong_kuo_lv_count=0
lv_suo_hong_count=0
lv_suo_lv_count=0
lv_kuo_hong_count=0
lv_kuo_lv_count=0
while cur<len(pct_chg_list):
cur_value=pct_chg_list[cur]
cur_vol=vol_list[cur]
#前一天是红的
if pre_pct_chg>=0:
#缩量
if cur_vol<=pre_vol:
#为红
if cur_value>=0:
hong_suo_hong_count+=1
else:
hong_suo_lv_count+=1
else:
if cur_value>=0:
hong_kuo_hong_count+=1
else:
hong_kuo_lv_count+=1
else:
#缩量
if cur_vol<=pre_vol:
#为红
if cur_value>=0:
lv_suo_hong_count+=1
else:
lv_suo_lv_count+=1
else:
if cur_value>=0:
lv_kuo_hong_count+=1
else:
lv_kuo_lv_count+=1
pre_pct_chg=cur_value
pre_vol=cur_vol
pre+=1
cur+=1
result1='''前一天上涨时:
缩量上涨个数%d
缩量下跌个数%d
扩量上涨个数%d
扩量下跌个数%d''' % (hong_suo_hong_count,hong_suo_lv_count,hong_kuo_hong_count,hong_kuo_lv_count)
result2='''前一天下跌时:
缩量上涨个数%d
缩量下跌个数%d
扩量上涨个数%d
扩量下跌个数%d''' % (lv_suo_hong_count,lv_suo_lv_count,lv_kuo_hong_count,lv_kuo_lv_count)
print(result1)
print(result2)
执行结果:
前一天上涨时:
缩量上涨个数206
缩量下跌个数169
扩量上涨个数141
扩量下跌个数205
前一天下跌时:
缩量上涨个数179
缩量下跌个数149
扩量上涨个数195
扩量下跌个数188
当天上涨,如果缩量,则上涨概率大,如果扩量,则下跌概率大。
当天下跌,如果缩量,则上涨概率大,如果扩量,则上涨和下跌的概率对半(尽量观望不操作)。
统计增长率的分布
#统计上涨和下跌最大的概率位于哪个区间
def find_out_rate_in_which_zone(tg_list):
data_map=[[] for i in range(11)]
for i in tg_list:
abs_i=abs(i)
if 0<=abs_i<0.5:
data_map[0].append(i)
elif 0.5<=abs_i<1:
data_map[1].append(i)
elif 1<=abs_i<1.5:
data_map[2].append(i)
elif 1.5<=abs_i<2:
data_map[3].append(i)
else:
for j in range(2,10):
if j<=abs_i<j+1:
data_map[j+1].append(i)
if abs_i==10:
data_map[10].append(i)
d1,d2=[],[]
for i in range(11):
zone=data_map[i]
zone_d1=[]
zone_d2=[]
for j in zone:
if j>=0:
zone_d1.append(j)
else:
zone_d2.append(j)
d1.append(zone_d1)
d2.append(zone_d2)
# print(d1)
# print(d2)
print('正数:位于0-0.5,05-1,1-1.5,1.5-2,2-3,3-4,4-5,5-6,6-7,7-8,8-9,9-10的个数分别是')
[print(len(i),end=',') for i in d1]
print('负数:位于0-0.5,05-1,1-1.5,1.5-2,2-3,3-4,4-5,5-6,6-7,7-8,8-9,9-10的个数分别是')
[print(len(i),end=',') for i in d2]
result=get_stock_data('index_daily','000001.SH')
# print(list(result["pct_change"]))
tg_list=list(result["pct_chg"])
# find_out_red_green_change_rate(tg_list)
vol_list=list(result["vol"])
# find_out_next_day_according_to_vol(tg_list,vol_list)
find_out_rate_in_which_zone(tg_list)
正数:位于0-0.5,05-1,1-1.5,1.5-2,2-3,3-4,4-5,5-6,6-7,7-8,8-9,9-10的个数分别是
316,204,102,89,7,1,2,0,0,0,0,
负数:位于0-0.5,05-1,1-1.5,1.5-2,2-3,3-4,4-5,5-6,6-7,7-8,8-9,9-10的个数分别是
323,196,102,76,7,3,3,0,1,0,0,
可知,上证指数每天波动最大的区间是【-0.5-0.5】,超过2的时候极少。
上涨0-0.5:520个,下跌0.5-0:519个。合计,占1431个总数的72.6%