如果一个股票的k线是一条水平线,没法赚钱。
有波动,才有赚钱机会。
股票A,最近30天,每天的平均波动是5%,股票B,最近30天,每天的平均波动是1%,那么,A比B的赚钱机会要多。
如果一个股票的波动率,从日均1%上升到日均5%,表明交易开始活跃,有一波行情。
因此需要计算股票的波动率,根据波动率选择标的。
一个比较稳妥的方案,是计算上证50或者沪深300的股票,在1、3、7、21、28天的日k平均波动,以及最大波动。
日K波动:今天最高价15块,最低价10块,那么今天日K的最大波动是50%。
日K平均波动:若干天内的“日K波动”的平均值。
日K最大波动:若干天内的最高价除以这些天内的最低价。
代码如下:
import tushare as ts
import numpy as np
import pandas as pd
def test2():
"""
获取上证50名单,返回值形如:
date code name
0 2019-12-20 600000 浦发银行
1 2019-12-20 600009 上海机场
2 2019-12-20 600016 民生银行
"""
sz50 = ts.get_sz50s()
"""
获取沪深300名单,返回值形如:
date code name weight
0 2019-11-29 600000 浦发银行 1.12
1 2019-11-29 600004 白云机场 0.14
2 2019-11-29 600009 上海机场 0.58
"""
hs300 = ts.get_hs300s()
# #一些测试
# print(hs300)
# #输出前5个记录
# print('head:\n', sz50.head(), '\n\n')
# #输出后3个记录
# print('tail:\n', sz50.tail(3), '\n\n')
# #index,每条记录的序号
# print('index:\n', [i for i in sz50.index], '\n\n')
# #columns
# print('columns:\n', [i for i in sz50.columns], '\n\n')
# #打印一列
# print(sz50[sz50.columns[0]])
# #打印一行
# print(sz50[0:1])
# #打印特定位置
# print(sz50.loc[0:3, ['date', 'name']])
# #打印特定位置,注意,要清楚知道坐标,index必须是整数
# print(sz50.iloc[0, 1])
# 获取一只股票最近两年的日K线价格
"""
获取浦发银行最近2年的日k各指标,形如:
open high close ... v_ma5 v_ma10 v_ma20
date ...
2019-12-23 12.46 12.46 12.20 ... 385949.64 366221.89 313179.32
2019-12-20 12.41 12.55 12.42 ... 387825.12 346537.26 307239.01
2019-12-19 12.40 12.50 12.41 ... 426565.94 327041.55 301929.48
"""
prices = ts.get_hist_data(sz50.iloc[0, 1])
"""
print(prices.loc[prices.index[0],:])
输出日k的各指标,形如:
open 12.460
high 12.460
close 12.200
low 12.170
volume 370338.910
price_change -0.220
p_change -1.770
ma5 12.364
ma10 12.181
ma20 12.046
v_ma5 385949.640
v_ma10 366221.890
v_ma20 313179.320
"""
"""
# 计算价格最大值和最小值
# print(prices.max().loc['high'])
# print(prices.min().loc['low'])
"""
# 取最近30个交易日的开盘,收盘,最大,最小,价格
prices = prices.iloc[:30, 0:4]
# 计算每一天的波动率,也就是(最大值/最小值-1)x100%
for idx in prices.index:
ff = 100.0 * (prices.loc[idx, 'high'] / prices.loc[idx, 'low'] - 1)
print('%.2f%%' % ff)
"""
计算一只股票在最近若干天内的最大波动率。
最近1天、3天、7天、14天、21天、28天的波动率。
计算方式:1天、3天、7天、14天、21天、28天内的(最大值/最小值-1)x100%
"""
def get_fluctuation_rate_max(prices, cycles=[1, 3, 7, 14, 21, 28]):
ret = pd.DataFrame(index=[0])
#处理多个周期
for cc in cycles:
prices_tmp = prices.loc[prices.index[:cc], ['high', 'low']]
ret['max_rate_cycle_%d_day'%cc] = prices_tmp.max().loc['high']/prices_tmp.min().loc['low']-1
return ret
"""
计算一只股票在最近若干天内的每日波动率的平均值。
最近1天、3天、7天、14天、21天、28天的波动率。
计算方式:1天、3天、7天、14天、21天、28天内的(最大值/最小值-1)x100%
"""
def get_fluctuation_rate_mean(prices, cycles=[1, 3, 7, 14, 21, 28]):
ret = pd.DataFrame(index=[0])
#最近若干天,比如30天,每天的波动(最大值/最小值-1)
fluctuation_rate_day = [(prices.loc[idx, 'high'] / prices.loc[idx, 'low'] - 1) for idx in prices.index]
#处理多个周期
for cc in cycles:
ret['mean_rate_cycle_%d_day'%cc]=np.mean(fluctuation_rate_day[:cc])
return ret
"""
波动极值密度
一段时间内,价格在最大最小之间来回波动的密度。如果价格走势是单向的,最大最小也有,但不利于波动赚钱。
方法:
"""
def get_fluctuation_rate_density(prices, cycles=[1, 3, 7, 14, 21, 28]):
pass
def get_variable_fluctuation_rate_of_one_stock(code, cycles, num):
prices = ts.get_hist_data(code)
prices = prices.iloc[:num, :]
res1 = get_fluctuation_rate_max(prices, cycles)
# print('res1 = ', res1.iloc[0,:])
res2 = get_fluctuation_rate_mean(prices, cycles)
# print('res2 = ', res2.iloc[0,:])
#把结果拼接起来
ret = pd.concat([res1,res2], axis=1)
# print('res = ', res.iloc[0, :])
#更换idex
ret.index = pd.Series([code])
# print('res = \n', res.loc[res.index[0],:])
# print(res.index)
return ret
def get_variable_fluctuaion_rate_of_stocks(stock_list, cycles, num):
"""
输出字段,1~28天波动的最大值,1~28天的每天波动均值
max_rate_cycle_1_day,
max_rate_cycle_3_day,
max_rate_cycle_7_day,
max_rate_cycle_14_day,
max_rate_cycle_21_day,
max_rate_cycle_28_day,
mean_rate_cycle_1_day,
mean_rate_cycle_3_day,
mean_rate_cycle_7_day,
mean_rate_cycle_14_day,
mean_rate_cycle_21_day,
mean_rate_cycle_28_day
"""
n = 0
ret = get_variable_fluctuation_rate_of_one_stock(stock_list.loc[stock_list.index[0],'code'],
cycles, num)
for code in stock_list.loc[stock_list.index[1:], 'code']:
res = get_variable_fluctuation_rate_of_one_stock(code, cycles, num)
ret = pd.concat([ret, res], sort=False)
n+=1
# if n >= 2:
# break
return ret
if __name__ == '__main__':
# 时间阶段
cycles = [1, 3, 7, 14, 21, 28]
# 前num个交易记录,如果是日K,就是前num天
num = 30
# 注意,一定要有 num > cycles[-1]
sz50 = ts.get_sz50s()
hs300 = ts.get_hs300s()
stocks = sz50
stocks = hs300
res = get_variable_fluctuaion_rate_of_stocks(stocks, cycles, num)
res['code'] = res.index
res = pd.merge(res, stocks)
#输出全部记录,不省略
pd.set_option('display.max_rows', None)
for i in res.columns:
if i in ['code', 'name', 'date', 'weight',]:
continue
print('\n\n')
print(i)
res = res.sort_values(by=i, ascending=False)
print(res.loc[:, ['code', 'name', i]])
# break
计算结果示例:
max_rate_cycle_1_day
code name max_rate_cycle_1_day
108 601066 中信建投 0.125447
163 601901 方正证券 0.120261
20 600061 国投资本 0.119609
285 300033 同花顺 0.110267
119 601198 东兴证券 0.108020
202 000596 古井贡酒 0.106462
14 600030 中信证券 0.103656
195 000413 东旭光电 0.094637
147 601688 华泰证券 0.086484
91 600837 海通证券 0.085383
102 600999 招商证券 0.085057
40 600233 圆通速递 0.082927
159 601881 中国银河 0.082484
...
mean_rate_cycle_28_day
code name mean_rate_cycle_28_day
182 603986 兆易创新 0.058799
265 002555 三七互娱 0.054141
270 002624 完美世界 0.052897
179 603799 华友钴业 0.052539
82 600703 三安光电 0.052010
115 601162 天风证券 0.050139
236 002065 东华软件 0.050134
258 002456 欧菲光 0.049248
259 002460 赣锋锂业 0.048495
108 601066 中信建投 0.047841
246 002241 歌尔股份 0.047783
278 002938 鹏鼎控股 0.046844
158 601878 浙商证券 0.045959
285 300033 同花顺 0.044652
269 002602 世纪华通 0.043885
210 000671 阳光城 0.043126
291 300136 信维通信 0.043070
175 603160 汇顶科技 0.042619
260 002466 天齐锂业 0.042314
297 300413 芒果超媒 0.042066
85 600733 北汽蓝谷 0.041399
195 000413 东旭光电 0.041143
298 300433 蓝思科技 0.040816
294 300251 光线传媒 0.040216
280 002945 华林证券 0.040192
在有价值的标的里,寻找波动率高的标的,进行后续操作。